css:flexbox 基本属性详解

现在大部分浏览器都支持flexbox布局方法。react和react-native中几乎全部采用flex来布局。简单总结下常用属性供参考。

1. flex-direction 属性

先以一个简单的nav为例:

HTML

<nav class="main-nav">
        <ul>
          <li><a href="#">Work</a></li>
          <li><a href="#">About</a></li>
          <li><a href="#">Contact</a></li>
        </ul>
      </nav>

CSS

body {
    background: white;
    font-family: 'Open Sans', sans-serif;
}

.main-nav li {
    width: 100px;
}

.main-nav a {
    text-decoration: none;
    color: black;
    font-size: 21px;
    font-weight: 600;
    color: #00a9d9;
}

.main-nav a: hover {
    text-decoration: underline;
}

效果

Screen Shot 2017-04-02 at 10.34.53 PM.png

现在加上以下属性

.main-nav ul {
    list-style: none;
    display: flex;
}

变为

Screen Shot 2017-04-02 at 10.35.43 PM.png

flex会让<ul>这个容器成为一个具有flex功能的block-level容器,并且会影响到它的子元素的布局表现。

如果想让<ul>成为一个inline元素,可以写成display: inline-flex,这样它仍然具有flex container的效果,同时也表现为一个inline元素,就像<img>一样。

当加上display: flex;后,<li>元素由垂直排列变成了水平排列。这是因为flexflex-direction属性的默认值为row,如果我们添加上

.main-nav ul {
    list-style: none;
    display: flex;
        flex-direction: column
}

能看到<li>元素又变为了垂直排列。

flex-direction的值除了row,column还可以是row-reversecolumn-reverse

flex-direction这个属性在用在响应式web design上非常便利,配合media-query可以根据屏幕大小,将元素从水平排列变成垂直排列。

需要注意的是flexbox属性, 包括 flex-direction, 在有些浏览器上需要加prefixes,所以用之前一定要查查浏览器支持情况, can I use 这个网站就可以。还有个很方便的方法是用auto prefixer post CSS工具可以自动添加前缀,省去很多麻烦。

2. order属性

先添加加上header,main和footer,为了明显用背景色块来区分。
HTML

<body>
  <header class="main-header">Header</header>
  <nav class="main-nav">
    <ul>
      <li><a href="#">Work</a></li>
      <li><a href="#">About</a></li>
      <li><a href="#">Contact</a></li>
    </ul>
  </nav>
  <main class="main-content">Content</main>
  <footer class="main-footer">Footer</footer>
</body>

CSS

.main-header {
    background: #B61E32;
    padding: 10px;
}

.main-content {
    background: #F7CE2B;
    min-height: 40vh;
    padding: 10px;
}

.main-footer {
    background: #ABC999;
    padding: 10px;
}

效果


Screen Shot 2017-04-02 at 10.37.14 PM.png

然后将整个body都设为flex容器

body {
    display: flex;
    flex-direction: column;
}

此时,所有的flex元素默认order都是0,所以会按照元素的顺序来渲染,如果将某元素的order改成1:

.main-nav {
    order: 1;
}

可以看到main-nav元素跑到了最下面。

Screen Shot 2017-04-02 at 10.58.15 PM.png

当然,还能设为负数,试试改为-1。

3. justify-content属性

html

<body>
  <article class="fake-article">
    <header>
      <h1>Fake Article</h1>
    </header>
    <p>Vestibulum id ligula porta felis euismod semper. Curabitur blandit tempus porttitor. Nullam quis risus eget urna mollis ornare vel eu leo. Donec ullamcorper nulla non metus auctor fringilla.</p>
  </article>
  <article class="not-real">
    <header>
      <h1>Not Real</h1>
    </header>
    <p>Nullam quis risus eget urna mollis ornare vel eu leo. Etiam porta sem malesuada magna mollis euismod.</p>
  </article>
  <article class="phoney">
    <header>
      <h1>Phoney</h1>
    </header>
    <p>Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Donec id elit non mi porta gravida at eget metus. Praesent commodo cursus magna, vel scelerisque nisl consectetur et.</p>
  </article>
</body>

css

:root {
  height: 100%;
}
body {
  font-family: 'Open Sans', sans-serif;
  margin: 0;
  min-height: 100%;
  background: #333;
}
h1 {
  font-weight: 600;
  margin: 0 0 5px 0;
}
p {
  margin: 5px 0;
}
article {
  box-sizing: border-box;
  background: #FFF;
  margin: 5px;
}
body {
  display: flex;
  flex-direction: column;
}

效果:


Screen Shot 2017-04-02 at 10.39.06 PM.png

justify-content这个属性会影响children沿着flex-direction方向的排列和空间分配。当前的flex-directioncolumn。所以这个属性会影响子元素在从上到下的竖直方向上,如何分配多余空间,但是并不会改变元素本身的实际大小。

  • flex-start: justify-content默认值是flex-start,意思是所有元素都是从起始点开始向下排列。
  • flex-end: 设成flex-end,可以看到子元素们会一起从结束点开始排列。
body {
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
}

效果:


Screen Shot 2017-04-02 at 10.42.57 PM.png
  • center: 设成center,他们就会一起挤在中间的位置,还记得刚开始学css的时候总是为如何才能实现真正的vertical-align苦恼,有了flexbox终于能非常简单的实现了。
Screen Shot 2017-04-02 at 10.44.11 PM.png
  • space-between: 第一个元素在start位置,最后一个元素在end位置,中间元素均等间隙排列。
Screen Shot 2017-04-02 at 10.44.58 PM.png
  • space-around: 会平均分配剩余空间给所有元素间隙,但第一个元素的前面和最后一个元素的后面则是中间的间隙距离一半。
Screen Shot 2017-04-02 at 10.45.26 PM.png

4. align-items 和 align-self

justify-content是会影响子元素沿着flex-direction方向的排列,而align-item则会影响子元素与flex-direction方向垂直的方向上的排列情况。

为了更直观的说明,将flex-direction改为row,并将articleflex设为1,意思是所有article所占宽度总相等。

body {
  display: flex;
  flex-direction: row;
}
article {
  box-sizing: border-box;
  background: #FFF;
  margin: 5px;
  flex: 1;
}
  • 这样改之后会发现,三个ariticle元素虽然内容高度不同,但box都变成了100% height,这是因为align-items的默认值是stretch,就是会用掉所有的垂直方向上的多余空间。
Screen Shot 2017-04-02 at 10.46.36 PM.png
  • 若将align-items的值设为”flex-start“,如图,就会变成不同高度。
body {
  display: flex;
  flex-direction: row;
  align-items: flex-start;
}
Screen Shot 2017-04-02 at 10.47.26 PM.png
  • 相似的还有 flex-end, center。
  • 还有一个值是 baseline。就是根据首个元素的baseline来进行对齐。

align-items是用于container的属性,统一设置子元素的排列规则。如果想单独设置某一个子元素的布局规则,可以使用”align-self“。

比如给第二个article元素加上class.not-real

.not-real  {
    align-self: flex-end ;
}

效果如图,在不影响其他元素的情况下,改变了.not-real。

Screen Shot 2017-04-02 at 10.48.39 PM.png

5. flex-basis,flex-shrink,flex-grow

HTML

<body>
  <h1 class="title-1">title1</h1>
  <h1 class="title-2">title2</h1>
  <h1 class="title-3">title3</h1>
</body>

CSS

body {
  margin: 0;
  font-family: 'Open Sans', sans-serif;
  margin: 0;
  color: #eec965;
  display: flex;
}

.title-1 {
  background: #dd5f40;
}

.title-2 {
  background: #3d483a;
}

.title-3 {
  background: #468e5d;
}

效果

Screen Shot 2017-04-02 at 10.49.55 PM.png

5.1 flex-basis

flex-basis可以用来定义子元素在flex-direction方向上的最优size。
比如先定义title1的width

.title-1 {
  background: #dd5f40;
  width: 200px
}
Screen Shot 2017-04-02 at 10.50.46 PM.png

现在title1的宽度变为了200px
但如果加上

.title-1 {
  background: #dd5f40;
  width: 200px;
  flex-basis: 150px;
}

title1的box宽度变成了150px。

Screen Shot 2017-04-02 at 10.51.35 PM.png

flex-basis属性覆盖了width属性(但flex-basis不会让元素超过max-width或者小于min-width)。在flex-basis没有规定值得情况下,默认为auto。那么元素在flex-direction方向上的宽度,在这里就是指的width(因为这里的flex-direction是row),如果width没有规定值,那么就默认为元素的内容宽度,这里就是title1这几个字的宽度。

总之, Flex-basis就是在有足够空间的情况下,flex-direction上的最优宽度。

5.2 flex-grow

先给每个title都设定一个flex-basis:


.title-1 {
  background: #dd5f40;
  flex-basis: 120px;
}

.title-2 {
  background: #3d483a;
  flex-basis: 40px;
}

.title-3 {
  background: #468e5d;
  flex-basis: 100px;
}

现在在row方向上,很明显是有剩余空间的。

Screen Shot 2017-04-02 at 10.52.51 PM.png

此时,flex-grow就决定了如何分配这些空间。没有给值得时候,flex-grow默认为0。
如果:

.title-1 {
  background: #dd5f40;
  flex-basis: 120px;
  flex-grow: 1
}

现在title-1占用了全部的多余空间。

Screen Shot 2017-04-02 at 10.53.42 PM.png

如果把titile2的flex-grow变成2,那么titile-1会占用总的多余空间的1/3,title2占用2/3。

5.3 flex-shrink

flex-shrink会定义当总的flex-basis之和大于能够被分配的空间时,该如何缩减这些子元素。

默认的flex-shrink值是1,意思是每个元素都同等份额的缩减宽度。

比如给title1,title2,title3的flex-basis都设为200px,当总宽度小于600时:
给title1的flex-shrink设为2,那么title1减少的宽度将是其他元素的2倍,但如果设为100,1000,并不会奏效,因为不会让元素的宽度小于元素内容的宽度。

如果不想让元素的宽度因为总宽度的改变而减少,可以给flex-shrink的宽度设为0,若将所有元素的宽度都设为0,那么为导致overflow。

5.4 flex-basis,flex-grow,flex-shrink的缩写规范

注释部分写了该缩写对应的flex-grow,flex-shrink,flex-basis。

.title-1 {
  background: #dd5f40;
  flex: 1;
    /* flex-grow: 1;
       flex-shrink: 1;
       flex-basis: 0;
    */
}

当flex:1时,flex-grow为1,flex-shrink为1(因为是默认值),比较奇怪的是flex-basis此时为0(其默认值应该为auto)。

.title-2 {
  background: #3d483a;
  flex: 20px;
    /* flex-grow: 1;
       flex-shrink: 1;
       flex-basis: 20px;
    */
}

flex:20px时,很明显只有flex-basis可以规定具体size。flex-grow是1,这也有点奇怪,因为flex-grow默认值是0。

.title-3 {
  background: #468e5d;
  flex: 0 80px;
    /* flex-grow: 0;
       flex-shrink: 1;
       flex-basis: 80px;
    */
}

当先给一个无单位的值,再给一个有单位的值时,flex-grow得到第一个值,flex-basis得到第二个值。flex-shrink保持默认值。

其实最常用的方法还是,h1 { flex: 1; }这样的缩写方式。这样会让所有元素同等的获得多余空间,总是保持宽度一致且填满空间。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,539评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,911评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,337评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,723评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,795评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,762评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,742评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,508评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,954评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,247评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,404评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,104评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,736评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,352评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,557评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,371评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,292评论 2 352

推荐阅读更多精彩内容

  • H5移动端知识点总结 阅读目录 移动开发基本知识点 calc基本用法 box-sizing的理解及使用 理解dis...
    Mx勇阅读 4,481评论 0 26
  • 移动开发基本知识点 一.使用rem作为单位 html { font-size: 100px; } @media(m...
    横冲直撞666阅读 3,462评论 0 6
  • 前言 FlexBox是css3的一种新的布局方式,天生为解决布局问题而存在的它,比起传统的布局方式,我们使用Fle...
    zevei阅读 1,418评论 23 3
  • CSS 3中弹性盒布局的最新版概述 在CSS 3中,CSS Flexible Box模块为一个非常重要的模块,该模...
    吾名无双阅读 1,228评论 0 5
  • 进入考试周,为不影响毕业,强制自己停止绘画,所以也没办法更新了 为了说这句话,投几张之前的画吧 觉得很清秀,想着自...
    蘅春水生阅读 506评论 9 12