Flexbox布局

http://caniuse.com/#feat=flexbox
http://compass-style.org/reference/compass/css3/flexbox/
http://sassmeister.com/

flex container & flex item

声明一个flex容器:

.container { display: flex; }

* 为了兼容性需要添加浏览器厂商前缀,推荐用SASS去写CSS,他会帮你生成那些烦人的厂商前缀。
flex创建了一个块容器,如果需要行内容器,使用inline-flex

flex container的子元素就是flex item。
flex items默认是按照文档中文字的方向一个挨一个的排列,比如英语就是从左向右,阿拉伯语是从右向左。

flex-direction

声明在flex container上,有四个可选值:row, column, row-reverse, column-reverse
默认值是row,意思是flex items在一行上排列。column,flex items在一列上排列。

.container {
    display: flex;
    flex-direction: column;
}

上图


flex-direction
flex-direction

order

声明在flex item上,其值是数值,默认值是0,用来控制flex item在flex container中的显示顺序,数值越小越靠前。如果flex items有相同的order属性值,则按照他们在文档流中的顺序排列。
有一点需要注意,order属性只是改变了元素的显示顺序,他们在文档流中的位置没有发生任何改变,所以像div:nth-child(1)这种选择器依然是按照元素在文档流中的顺序

.flex_item {
    order: 1;
}

当flex items沿着main axis的总长度大于或小于flex container的宽度时,怎么办呢?看下面这些伸缩属性。

flex-grow

该属性声明在flex item上,其值是数值,默认值是0,用来分配flex container未被占用的空间给flex item。

.flex_item { flex-grow: 1; }

示例:

   <div id="container">
       <div class="flex_item">A</div>
       <div class="flex_item">B</div>
       <div class="flex_item">C</div>
       <div class="flex_item">D</div>
   </div>
#container {
    display: flex;
    flex-direction: row;
    background-color: darkgrey;
    width: 600px;
    height: 100px;
    margin: 50px auto;
}
#container div {
    width: 100px;
    text-align: center;
    font-size: 30px;
    font-weight: bold;
    line-height: 100px;
}
#container div:nth-child(1) { background-color: aquamarine; }
#container div:nth-child(2) { background-color: coral; }
#container div:nth-child(3) { background-color: #eeff11; }
#container div:nth-child(4) { background-color: #a168ff; }

如果为四个flex item分别设置,flex-grow为0,1,3,1,那么:
flex container的宽度是600px,四个flex item的宽度和是400px,所以还有200px的未占用空间。

flex item 增加的宽度 最终宽度
A 0/(0+1+3+1) * 200px = 0px 100 + 0 = 100px
B 1/(0+1+3+1) * 200px = 40px 100 + 40 = 140px
C 3/(0+1+3+1) * 200px = 120px 100 + 120 = 220px
D 1/(0+1+3+1) * 200px = 40px 100 + 40 = 140px
#container div:nth-child(1) { background-color: aquamarine; flex-grow: 0;}
#container div:nth-child(2) { background-color: coral; flex-grow: 1;}
#container div:nth-child(3) { background-color: #eeff11; flex-grow: 3;}
#container div:nth-child(4) { background-color: #a168ff; flex-grow: 1;}

效果图:


flex-grow
flex-grow

flex-shrink

该属性声明在flex item上,其值是数值,默认值是1,当flex items的宽度和大于flex container的宽度时,用此属性来收缩flex item的宽度。

.flex_item { flex-shrink: 1; }

还用前面的例子,修改flex item的宽度为330px,分别设置flex-shrink为3,2,3,0,那么:
flex container的宽度是600px,四个flex item的宽度和是1320px,超出了720px。

flex item 收缩的宽度 最终宽度
A 3/(3+2+3+0) * 720px = 270px 330 - 270 = 60px
B 2/(3+2+3+0) * 720px = 180px 330 - 180 = 150px
C 3/(3+2+3+0) * 720px = 270px 330 - 270 = 60px
D 0/(3+2+3+0) * 720px = 0px 330 - 0 = 330px
#container div:nth-child(1) { background-color: aquamarine; width: 330px; flex-shrink: 3;}
#container div:nth-child(2) { background-color: coral; width: 330px; flex-shrink: 2;}
#container div:nth-child(3) { background-color: #eeff11; width: 330px; flex-shrink: 3;}
#container div:nth-child(4) { background-color: #a168ff; width: 330px; flex-shrink: 0;}

效果图:

flex-shrink
flex-shrink

* 这里有个疑问,如果第一个flex item的flex-shrink设置为1,那么发现在第一个item的宽度都不够收缩的了,收缩的太多了,这种情况下,又是如何计算宽度值的??

flex-basis

该属性声明在flex item上,其值是长度值,默认值是auto
前面介绍的flex-growflex-shrink都是基本flex item的宽度值(width)来计算的,如果flex item设置了flex-basis属性,那么会直接忽略flex item的宽度,来基于此属性设置的长度值计算。

.flex_item { flex-basis: 100px; }
#container div:nth-child(1) { background-color: aquamarine; flex-basis:80px;flex-grow: 0;}
#container div:nth-child(2) { background-color: coral; flex-grow: 1;}
#container div:nth-child(3) { background-color: #eeff11; flex-grow: 3;}
#container div:nth-child(4) { background-color: #a168ff; flex-grow: 1;}

由于设置了flex-basis,所以flex-items的宽度和是380px,容器剩余可分配的空间为600 - 380 = 220px.

flex item 增加的宽度 最终宽度
A 0/(0+1+3+1) * 220px = 0px 80 + 0 = 80px
B 1/(0+1+3+1) * 220px = 44px 100 + 44 = 144px
C 3/(0+1+3+1) * 220px = 132px 100 + 132 = 232px
D 1/(0+1+3+1) * 220px = 44px 100 + 44 = 144px

设置成如下的值,解释不通了....?

#container div:nth-child(1) { background-color: aquamarine; width: 330px; flex-basis: 260px; flex-shrink: 1;}
#container div:nth-child(2) { background-color: coral; width: 330px; flex-shrink: 2;}
#container div:nth-child(3) { background-color: #eeff11; width: 330px; flex-shrink: 2;}
#container div:nth-child(4) { background-color: #a168ff; width: 330px; flex-shrink: 0;}

flex

flex是个shorhand property,默认是0 1 auto,分别对应flex-grow, flex-shrink, flex-basis这三个属性。


上面几个是伸缩属性,下面来讨论布局(alignment)属性

justify-content

此属性声明在flex container上。

flex-direction justify-content的使用场景
row 当flex items的宽度和小于flex container的宽度时,控制flex items在main axis上如何分布
column 当flex items的高度和小于flex container的高度时,控制flex items在main axis上如何分布
.flex_container { justify-content: keyword; }

下例以flex-direction: row来说明:

justify-content 图示
flex-start(默认值)
flex-end
center
space-between
space-around

对应代码:

#container {
    display: flex;
    flex-direction: row; /*row*/
    background-color: darkgrey;
    width: 600px;
    height: 100px;
    margin: 50px auto;
    justify-content: flex-end; /*justify-content*/
}
#container div {
    width: 100px;
    text-align: center;
    font-size: 30px;
    font-weight: bold;
    line-height: 100px;
}

下例以flex-direction: column来说明:

justify-content 图示
flex-start(默认值)
flex-end
center
space-between
space-around

对应代码:

#container {
    display: flex;
    flex-direction: column; /*column*/
    background-color: darkgrey;
    width: 600px;
    height: 100px;
    margin: 50px auto;
    justify-content: flex-end; /*justify-content*/
}
#container div {
    width: 100px;
    text-align: center;
    /*font-size: 30px;*/
    font-weight: bold;
    /*line-height: 100px;*/
}

align-items

此属性声明在flex container上。

flex-direction align-items的使用场景
row 当flex items的高度和小于flex container的高度时,控制flex items在cross axis上如何分布
column 当flex items的宽度和小于flex container的宽度时,控制flex items在cross axis上如何分布
.flex_container { align-items: keyword; }

下例以flex-direction: row来说明:

align-items 图示
stretch(默认值)
flex-start
flex-end
center

对应代码:

#container {
    display: flex;
    flex-direction: row; /*row*/
    background-color: darkgrey;
    width: 600px;
    height: 100px;
    margin: 50px auto;
    align-items: center; /*以center为例*/
}
#container div {
    width: 100px;
    text-align: center;
    font-size: 30px;
    font-weight: bold;
    /*line-height: 100px;*/
}

下例以flex-direction: column来说明:

align-items 图示
stretch(默认值)
flex-start
flex-end
center

对应代码:

#container {
    display: flex;
    flex-direction: column; /*column*/
    background-color: darkgrey;
    width: 600px;
    height: 100px;
    margin: 50px auto;
    align-items: center; /*以center为例*/
}
#container div {
    /*width: 100px;*/
    text-align: center;
    font-size: 30px;
    font-weight: bold;
    /*line-height: 100px;*/
}

justify-contentalign-items 写了这么多,其实道理很简单,justify-content控制flex item在main axis方向的布局;align-items控制flex item在cross axis方向的布局。

align-self

此属性声明在flex item上,其值与 align-items 的值一样。 align-items 是控制所有的flex item,而 align-self 只控制设置了此属性的flex item。

.flex_item { align-self: keyword; }

flex-wrap

此属性声明在flex container上,有三个关键字:wrap, nowrap, wrap-reverse,默认值是 nowrap,控制是否允许flex items换行。

.flex_container { flex-wrap: wrap; }

对应代码:

#container {
    display: flex;
    flex-direction: row; 
    flex-wrap: wrap-reverse; /*以wrap-reverse为例*/
    background-color: darkgrey;
    width: 600px;
    /* height: 100px; */
    margin: 50px auto;
}
#container div {
    width: 250px;
    text-align: center;
    font-size: 30px;
    font-weight: bold;
    line-height: 100px;
}

flex-flow

此属性声明在flex container上,是 flex-directionflex-wrap 的shorthand property.

.flex_container {
    flex-flow: row wrap;
}

align-content

此属性声明在flex container上,其值可以是 flex-start, flex-end, center, space-between, space-around, stretch ,默认是 stretch
当flex items在flex container中以多行显示时,align-content 控制这些行在cross axis上的布局,这里总结下:所有以align-*开头的属性,都是控制item在cross axis上的布局。

下例以flex-direction: row来说明:

align-content 图示
stretch(默认值)
flex-start
flex-end
center
space-between
space-around

对应代码:

#container {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;        /*允许换行*/
    align-content: stretch; /*以stretch为例*/
    background-color: darkgrey;
    width: 600px;
    height: 100px;
    margin: 50px auto;
}
#container div {
    width: 250px;
    text-align: center;
    font-size: 20px;
    font-weight: bold;
    /* line-height: 100px; */
}

此文本是《The Book of CSS3 2nd edition》第15章的读书笔记,但是写着写着,总结的内容比原文多了许多。

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

推荐阅读更多精彩内容

  • 前言 FlexBox是css3的一种新的布局方式,天生为解决布局问题而存在的它,比起传统的布局方式,我们使用Fle...
    zevei阅读 1,408评论 23 3
  • H5移动端知识点总结 阅读目录 移动开发基本知识点 calc基本用法 box-sizing的理解及使用 理解dis...
    Mx勇阅读 4,392评论 0 26
  • title: flex布局date: 2017-07-07 14:13:33tags: css笔记 flexbox...
    Gary23阅读 1,522评论 0 0
  • 移动开发基本知识点 一.使用rem作为单位 html { font-size: 100px; } @media(m...
    横冲直撞666阅读 3,452评论 0 6
  • W3C解释: In the flex layout model, the children of a flex c...
    Echo_Du阅读 296评论 0 0