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

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-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 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章的读书笔记,但是写着写着,总结的内容比原文多了许多。

你可能感兴趣的:(Flexbox布局)