Flex Flexible Box 伸缩盒


CSS3 弹性盒子(Flexible Box 或 Flexbox)是一种用于在页面上布置元素的布局模式, 使得当页面布局 适应不同的屏幕尺寸和不同的显示设备时,元素可预测地运行。弹性盒子模型提供了对块模型的改进,因为它不使用浮动,flex容器的边缘也不会与其内容的边缘折叠。

弹性盒子中的子元素可以在各个方向上进行布局, 并且能以弹性尺寸来适应显示空间。

由于元素的显示顺序可以与它们在源代码中的顺序无关,定位子元素将变得更容易

特性 Firefox (Gecko) Chrome Internet Explorer Opera Safari
基础支持(单行弹性框) 18.0 ~ 22.0 需前缀-moz 21.0~29.0 需前缀-webkit 11支持最终版 12.10 需前缀-webkit 6.1需前缀-webkit
iOS 7+支持最终版
多行弹性框 28.0 21.0~29.0 需前缀-webkit 11支持最终版 12.15 需前缀-webkit
Opera 17 无需前缀
6.1需前缀-webkit
iOS 7+支持最终版

基本概念

采用Flex布局的元素,称为Flex容器(flex container),简称"容器"。

它的所有子元素自动成为容器成员,称为Flex项目(flex item),简称"项目"。

容器默认存在两根轴:水平的主轴(main axis)和垂直的交叉轴(cross axis)。

主轴的开始位置(与边框的交叉点)叫做main start,结束位置叫做main end;

交叉轴的开始位置叫做cross start,结束位置叫做cross end。

项目默认沿主轴排列。单个项目占据的主轴空间叫做main size,占据的交叉轴空间叫做cross size。

图中是一个 flex-direction 属性为 row的弹性容器,意味着其内的弹性项目将根据既定书写模式沿主轴水平排列,其方向为元素的文本流方向,在这个例子里,为从左到右。

弹性容器(Flex container)

包含着弹性项目的父元素。通过设置 display 属性的值为 flexinline-flex 来定义弹性容器。

弹性项目(Flex item)

弹性容器的每个子元素都称为弹性项目。弹性容器直接包含的文本将被包覆成匿名弹性单元。

轴(Axis)

每个弹性框布局包含两个轴。弹性项目沿其依次排列的那根轴称为主轴(main axis)。垂直于主轴的那根轴称为侧轴(cross axis)。

方向(Direction)

弹性容器的主轴起点(main start)/主轴终点(main end)和侧轴起点(cross start)/侧轴终点(cross end)描述了弹性项目排布的起点与终点。它们具体取决于弹性容器的主轴与侧轴中,由 writing-mode 确立的方向(从左到右、从右到左,等等)。

行(Line)

根据 flex-wrap 属性,弹性项目可以排布在单个行或者多个行中。此属性控制侧轴的方向和新行排列的方向。

尺寸(Dimension)

根据弹性容器的主轴与侧轴,弹性项目的宽和高中,对应主轴的称为主轴尺寸(main size) ,对应侧轴的称为 侧轴尺寸(cross size)。

定义

任何一个容器都可以指定为 Flex 布局。查看示例
.box{
  display: flex;
}
				
行内元素也可以使用 Flex 布局查看示例
.box{
  display: inline-flex;
}
				

Webkit 内核的浏览器,必须加上-webkit前缀。

容器的属性

以下6个属性设置在容器上。

# 开启flex布局
display: flex | inline-flex;
# 流 两个css属性的组合缩写属性
flex-flow: <flex-direction> || <flex-wrap>
	- flex-flow: row nowrap;
# 设置主轴方向
flex-direction: row(向右) | row-reverse(向左) | column(向下) | column-reverse(向上);
# 开启多行
flex-wrap: nowrap(不换行) | wrap(小到大) | wrap-reverse(大到小);
# 水平对齐(起始方向有左右, 下面以左到右, 即flex-direction: row;)
justify-content: flex-start(左对齐) | flex-end(右对齐) | center(居中) | space-between(两端对齐,间隔相等) | space-evenly(两端对齐, 但两边预留与flex items想等的距离) | space-around(两端对齐, 但两边预留flex items之间距离的一半);
# 垂直对齐
align-items: flex-start(顶部) | flex-end(底部) | center(垂直居中) | baseline(垂直两端对齐) | stretch(第一行文字的基线对齐);
# 多行在交叉轴的对齐方式
align-content: flex-start | flex-end | center | space-between | space-evenly | space-around | stretch(默认值, 拉伸);
				

1.1 flex-direction 排列方向

flex-direction属性决定主轴的方向(即项目的排列方向)。查看示例

.box {
  flex-direction: row | row-reverse | column | column-reverse;
}
它可能有4个值:
row(默认值):主轴为水平方向,起点在左端。
row-reverse:主轴为水平方向,起点在右端。
column:主轴为垂直方向,起点在上沿。
column-reverse:主轴为垂直方向,起点在下沿。
				

1.2 flex-wrap 换行排列顺序

默认情况下,项目都排在一条线(又称"轴线")上。flex-wrap属性定义,如果一条轴线排不下,如何换行。查看示例

.box{
  flex-wrap: nowrap | wrap | wrap-reverse;
}
它可能取三个值:
nowrap(默认):不换行。
wrap:换行,第一行在上方。(正序)
wrap-reverse:换行,第一行在下方。(倒序)
				

1.3 flex-flow css组合属性: 排列方向+换行顺序

flex-flow属性是flex-direction属性和flex-wrap属性的简写形式,默认值为row nowrap

.box {
  flex-flow:  <flex-direction> || <flex-wrap>;
}
/* 例如 flex-flow: row nowrap; */
				

1.4 justify-content 水平对齐

justify-content属性定义了项目在主轴上的对齐方式。查看示例

.box {
  justify-content: flex-start | flex-end | center | space-between | space-evenly | space-around;
}
它可能取5个值,具体对齐方式与轴的方向有关。下面假设主轴为从左到右:
flex-start(默认值):左对齐
flex-end:右对齐
center: 居中
space-between:两边对齐,item之间的间隔都相等。
space-evenly: 两边预留与items之间相同的间距
space-around:两边预留与items之间间距一半的留白
				

1.5 align-items 垂直对齐

align-items属性定义项目在交叉轴上如何对齐。查看示例

.box {
  align-items: flex-start | flex-end | center | baseline | stretch;
}
它可能取5个值。具体的对齐方式与交叉轴的方向有关,下面假设交叉轴从上到下:
flex-start:交叉轴的起点对齐。
flex-end:交叉轴的终点对齐。
center:交叉轴的中点对齐。
baseline: 项目的第一行文字的基线对齐。
stretch(默认值):如果项目未设置高度或设为auto,将占满整个容器的高度。
				

1.6 align-content 垂直与水平对齐

align-content属性定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用。需要开启多行. 查看示例

.box {
  align-content: flex-start | flex-end | center | space-between | space-around | stretch;
}
				

项目的属性

以下6个属性设置在项目上:

# 项目显示属性 简写属性
flex : none | [ <'flex-grow'> <'flex-shrink'> <'flex-basis'> ]
	- flex: 0 1 auto;
# 增长比例, 当有剩余空间时; 所有item的总和大于1将占满宽度. 小于1将不占满.
flex-grow: 0(默认) | 正小数0.2 | 正整数;
# 缩小比例, 当空间不足时;
flex-shrink: 1(默认) | 正小数0.2 | 正整数;
# 主轴占用大小 
flex-basis: auto | 350px;
# item排序id, 值越小排在前面
order: 0 | 整数  | 负数;
# 单独对齐方式, 覆盖flex容器上的align-items设置 (交叉轴对齐)
align-self: auto(默认) | flex-start | flex-end | center | baseline | stretch;
				

1.1 order 排序ID

order属性定义项目的排列顺序。数值越小,排列越靠前,默认为0。可设置任意整数(整数,负数,0)

.item {
  order: ;
}
				

1.2 flex-grow 放大比例

flex-grow属性定义项目的放大比例,可以设置任意非负数字(正小数, 正整数, 0 ) , 默认值0,即如果存在剩余空间,也不放大。

.item {
  flex-grow: ; /* default 0 */
}
				

如果所有项目的flex-grow属性都为1,则它们将等分剩余空间(如果有的话)。如果一个项目的flex-grow属性为2,其他项目都为1,则前者占据的剩余空间将比其他项多一倍。

1.3 flex-shrink 缩小比例

flex-shrink属性定义了项目的缩小比例,可以设置任意非负数数字(正小数, 正整数, 0) 默认值是1,即如果空间不足,该项目将缩小。

.item {
  flex-shrink: ; /* default 1 */
}
				

如果所有项目的flex-shrink属性都为1,当空间不足时,都将等比例缩小。如果一个项目的flex-shrink属性为0,其他项目都为1,则空间不足时,前者不缩小。

1.4 flex-basis 预占空间

flex-basis属性定义了在分配多余空间之前,项目占据的主轴空间(main size)。浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto,即项目的本来大小。

.item {
  flex-basis:  | auto; /* default auto */
}
				

它可以设为跟width或height属性一样的值(比如350px),则项目将占据固定空间。

1.5 flex css组合属性=放大比例+缩小比例+占用大小

flex属性是flex-grow, flex-shrink 和 flex-basis的简写,默认值为0 1 auto。后两个属性可选。

.item {
  flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
}
				

该属性有两个快捷值:auto (1 1 auto) 和 none (0 0 auto)。

建议优先使用这个属性,而不是单独写三个分离的属性,因为浏览器会推算相关值。

1.6 align-self 单独对齐

align-self属性允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性。默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch。

.item {
  align-self: auto | flex-start | flex-end | center | baseline | stretch;
}
				

该属性可能取6个值,除了auto,其他都与align-items属性完全一致。

弹性项目须知

Flex兼容


flex布局分为旧版本dispaly: box;,过渡版本dispaly: flex box;,以及现在的标准版本display: flex;

盒子的兼容性写法

.box{
    display: -webkit-flex;  /* 新版本语法: Chrome 21+ */
    display: flex;          /* 新版本语法: Opera 12.1, Firefox 22+ */
    display: -webkit-box;   /* 老版本语法: Safari, iOS, Android browser, older WebKit browsers. */
    display: -moz-box;      /* 老版本语法: Firefox (buggy) */
    display: -ms-flexbox;   /* 混合版本语法: IE 10 */   
}
				

子元素的兼容性写法

.flex1 {  
    -webkit-flex: 1;        /* Chrome */  
    -ms-flex: 1             /* IE 10 */  
    flex: 1;                /* NEW, Spec - Opera 12.1, Firefox 20+ */
    -webkit-box-flex: 1     /* OLD - iOS 6-, Safari 3.1-6 */  
    -moz-box-flex: 1;       /* OLD - Firefox 19- */       
}
				

这种兼容写法不一定起效的。尤其是在底版本安卓系统中。因为什么呢?因为所有都是向下兼容的,所以写法的顺序一定要写好了才起作用。就是把旧语法写在底下,个别不兼容的移动设置才会识别,哪些是旧的语法,你懂的。那些带box的一定要写在最下面即可。

					
.flex {
 
display: box; /* OLD - Android 4.4- */
 
display: -webkit-box; /* OLD - iOS 6-, Safari 3.1-6 */
 
display: -moz-box; /* OLD - Firefox 19- (buggy but mostly works) */
 
display: -ms-flexbox; /* TWEENER - IE 10 */
 
display: -webkit-flex; /* NEW - Chrome */
 
display: flex;
 
}
 
 
/* 父元素-水平居中(主轴是横向才生效) */
 
.flex-hc {
 
/* 09版 */
 
-webkit-box-pack: center;
 
/* 12版 */
 
-webkit-justify-content: center;
 
-moz-justify-content: center;
 
-ms-justify-content: center;
 
-o-justify-content: center;
 
justify-content: center;
 
/* 其它取值如下:
align-items 主轴原点方向对齐
flex-end 主轴延伸方向对齐
space-between 等间距排列,首尾不留白
space-around 等间距排列,首尾留白
*/
 
}
 
 
/* 父元素-竖直居中(主轴是横向才生效) */
 
.flex-vc {
 
/* 09版 */
 
-webkit-box-align: center;
 
/* 12版 */
 
-webkit-align-items: center;
 
-moz-align-items: center;
 
-ms-align-items: center;
 
-o-align-items: center;
 
align-items: center;
 
}
 
 
/* 子元素-平均分栏 */
 
.flex1 {
 
-webkit-box-flex: 1; /* OLD - iOS 6-, Safari 3.1-6 */
 
-moz-box-flex: 1; /* OLD - Firefox 19- */
 
width: 20%; /* For old syntax, otherwise collapses. */
 
-webkit-flex: 1; /* Chrome */
 
-ms-flex: 1; /* IE 10 */
 
flex: 1; /* NEW, Spec - Opera 12.1, Firefox 20+ */
 
}
 
 
/* 父元素-横向排列(主轴) */
 
.flex-h {
 
display: box; /* OLD - Android 4.4- */
 
display: -webkit-box; /* OLD - iOS 6-, Safari 3.1-6 */
 
display: -moz-box; /* OLD - Firefox 19- (buggy but mostly works) */
 
display: -ms-flexbox; /* TWEENER - IE 10 */
 
display: -webkit-flex; /* NEW - Chrome */
 
display: flex; /* NEW, Spec - Opera 12.1, Firefox 20+ */
 
/* 09版 */
 
-webkit-box-orient: horizontal;
 
/* 12版 */
 
-webkit-flex-direction: row;
 
-moz-flex-direction: row;
 
-ms-flex-direction: row;
 
-o-flex-direction: row;
 
flex-direction: row;
 
}
 
 
 
/* 父元素-横向换行 */
 
.flex-hw {
 
/* 09版 */
 
/*-webkit-box-lines: multiple;*/
 
/* 12版 */
 
-webkit-flex-wrap: wrap;
 
-moz-flex-wrap: wrap;
 
-ms-flex-wrap: wrap;
 
-o-flex-wrap: wrap;
 
flex-wrap: wrap;
 
}
 
 
/* 父元素-纵向排列(主轴) */
 
.flex-v {
 
display: box; /* OLD - Android 4.4- */
 
display: -webkit-box; /* OLD - iOS 6-, Safari 3.1-6 */
 
display: -moz-box; /* OLD - Firefox 19- (buggy but mostly works) */
 
display: -ms-flexbox; /* TWEENER - IE 10 */
 
display: -webkit-flex; /* NEW - Chrome */
 
display: flex; /* NEW, Spec - Opera 12.1, Firefox 20+ */
 
/* 09版 */
 
-webkit-box-orient: vertical;
 
/* 12版 */
 
-webkit-flex-direction: column;
 
-moz-flex-direction: column;
 
-ms-flex-direction: column;
 
-o-flex-direction: column;
 
flex-direction: column;
 
}
 
 
/* 父元素-纵向换行 */
 
.flex-vw {
 
/* 09版 */
 
/*-webkit-box-lines: multiple;*/
 
/* 12版 */
 
-webkit-flex-wrap: wrap;
 
-moz-flex-wrap: wrap;
 
-ms-flex-wrap: wrap;
 
-o-flex-wrap: wrap;
 
flex-wrap: wrap;
 
}
 
 
/* 子元素-显示在从左向右(从上向下)第1个位置,用于改变源文档顺序显示 */
 
.flex-1 {
 
-webkit-box-ordinal-group: 1; /* OLD - iOS 6-, Safari 3.1-6 */
 
-moz-box-ordinal-group: 1; /* OLD - Firefox 19- */
 
-ms-flex-order: 1; /* TWEENER - IE 10 */
 
-webkit-order: 1; /* NEW - Chrome */
 
order: 1; /* NEW, Spec - Opera 12.1, Firefox 20+ */
 
}
 
 
/* 子元素-显示在从左向右(从上向下)第2个位置,用于改变源文档顺序显示 */
 
.flex-2 {
 
-webkit-box-ordinal-group: 2; /* OLD - iOS 6-, Safari 3.1-6 */
 
-moz-box-ordinal-group: 2; /* OLD - Firefox 19- */
 
-ms-flex-order: 2; /* TWEENER - IE 10 */
 
-webkit-order: 2; /* NEW - Chrome */
 
order: 2; /* NEW, Spec - Opera 12.1, Firefox 20+ */