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;
}
上图
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; }
示例:
A
B
C
D
#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-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 item的
flex-shrink
设置为1,那么发现在第一个item的宽度都不够收缩的了,收缩的太多了,这种情况下,又是如何计算宽度值的??
flex-basis
该属性声明在flex item上,其值是长度值,默认值是auto
。
前面介绍的flex-grow
和flex-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-content
和 align-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-direction
和 flex-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章的读书笔记,但是写着写着,总结的内容比原文多了许多。