flex 布局
flex
是flexible Box
的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性。任何一个容器都可以指定为flex布局。
display
.container {
display: flex | inline-flex;
}
定义一个flex
容器,为内容创建了一个新的flex环境
注意:当设置 flex
布局之后,子元素的 float
、clear
、vertical-align
的属性将会失效。
1. 父容器display: flex
2. 父容器display: inline-flex
flex: 将元素作为弹性伸缩盒显示
inline-flex: 将元素作为内联块级弹性伸缩盒显示
使用
flex
时父元素是block
元素,而声明了inline-flex
的父元素变成了inline
元素
原理
赋予父容器更改子元素宽高(或顺序)的能力,来更好的填充可用的空间(主要使其适应各种显示设备和屏幕尺寸)。一个使用flexbox
布局的父容器会伸展每个子元素来填充可用的空间,或者压缩它们来阻止超出父容器。
最重要的是,flexbox
布局在方向上是不可预知的,这一点和常归布局不同(常规布局中块是基于竖直方向排列的,而内联是基于水平方向)。这些常规布局在页面中显示都没问题,但它们缺乏灵活性,难以支撑大型复杂应用的需求,特别是响应方向、大小、伸展、收缩等这些变化。
适用场景
flexbox
最适合用在组件和小规模的布局中,如果是更复杂的布局,Grid
布局会比较好一些。
由于flexbox
是一个完整的模块,它不单单是一个属性,而是包含了一整套新的属性集。这些属性中一些是用来设置父容器的,而另外一些是设置子元素的。
flex 基本概念
flexbox
主要由父容器和它的直接子元素组成,父容器被称为flex
容器(flex container
),而其直接的子元素称作为flex子类(flex item
)以下
flex
容器简称为container
,flex
子类简称item
main axis和cross axis
在flex box
中存在两条轴,主轴main axis
,和侧轴cross axis
-
main axis:
flex
容器的主轴主要用来配置flex
项目。注意,它不一定是水平,这主要取决于flex-direction
属性。 -
main-start | main-end:
flex
项目的配置从容器的主轴起点边开始,向主轴终点边结束 - cross axis: 与主轴垂直的轴称作侧轴,是侧轴方向的延伸
- cross-start | cross-end: 伸缩行的配置从容器的侧轴起点边开始,往侧轴终点边结束
item
是沿着main axis
(起点main-start
终点main-end
)或者cross axis(起点cross-start
终点cross-end
)排列
main size和cross size
-
main size: 每个
item
占据的主轴空间为main size
,item
的主轴长度是width
还是height
,由主轴方向决定。 -
cross size: 每个
item
占据的交叉轴的空间为cross size
,item
的侧轴长度是width
或height
,由侧轴方向决定
要记住并不是宽度是main size
,高度是cross size
,是要根据主轴的方向来定义哪个是main size
。如果垂直方向是主轴,则item
的高度就是main size
下面来分别介绍flex container
和flex item
flex容器
属性
flex
容器六种属性,分别是:
1. flex-direction
2. flex-wrap
3. flex-flow
4. justfy-content
5. align-items
6. align-content
flex-direction
创建了主轴,定义了
item
在flex
容器中的方向。 flexbox
是单向布局,可以将item
放在水平行或垂直列中
.container {
flex-direction: row | row-reverse | column | column-reverse;
}
row(默认): 如果书写方式是ltr
,那么item
从左向右排列;如果书写方式是rtl
,那么item
从右向左排列
row-reverse: 如果书写方式是ltr
,那么item
从右向左排列;如果书写方式是rtl
,那么item
从左向右排列
column: 和row
类似,只不过方向是从上到下排列
column-reverse: 和row-reverse
类似,只不过方向是从下向上排列
点我看Demo
flex-wrap
默认情况下,项目都排在主轴线上,使用
flex-wrap
可实现项目的换行
.container {
flex-wrap: nowrap | wrap | wrap-reverse;
}
nowrap(默认): 不换行,所有item
会在一行
wrap: 多行显示,向下折行
wrap-reverse: 多行显示,向上折行
点我看Demo
flex-flow
flex-direction
和 flex-wrap
的简写形式,能够同时定义flex
容器的主轴和交叉轴
.container {
flex-flow: <flex-direction> || <flex-wrap>;
}
默认值: row nowrap
中间有空格
justify-content
这个属性定义了item
在主轴方向对齐方式
.container {
justify-content: flex-start | flex-end | center | space-between | space-around;
}
flex-start: 以主轴main-start
端对齐
flex-end: 以主轴main-end
方向对齐
center: 主轴居中
space-between: 两端对齐,item
之间相等间隔。如果是间距负数,或该行只有一个item
,则此值等效于flex-start
space-around: 每个item
两侧的间隔相等,所以item
之间的间隔比item
与边缘的间隔大一倍。如果剩余空间是负数,或该行只有一个item
,则该值等效于center
点我看Demo
align-items
这个属性定义了item
在侧轴上的对齐方式
.container {
align-items: flex-start | flex-end | center | stretch | baseline;
}
stretch(默认): 当cross size
未设置或者为auto时,拉伸至等于容器高度(会受到min-width/max-width
的限制)
flex-start: 以侧轴的cross-start
端对齐
flex-end: 以侧轴的cross-end
端对齐
center: 以侧轴的中点对齐
baseline: 以item
的第一行文字的基线对齐
点我看Demo
align-content
当侧轴上还有空间时,
align-content
属性可以指定container
中多行item
之间的对齐方式注意:定义了多根轴线的对齐方式,如果
item
只有一根轴线,那么该属性将不起作用如下:
当
flex-wrap: nowrap
,容器仅存在一根轴线,因为item
不会换行,就不会产生多条轴线。当
flex-wrap: wrap
,容器可能会出现多条轴线,这时候你就需要去设置多条轴线之间的对齐方式了。
.container {
align-content: flex-start | flex-end | center | space-between | space-around | stretch;
}
flex-start: 在侧轴的开始处将所有item
连接起来,最后将空间全部包含在内
flex-end: 在侧周的末端将所有item
连接起来,所有空间都在开头
center: 将所有item
拼接在十字轴的中间,每个末端的空间均等
space-between: 除了子元素之间的所有空间以及它们在交叉轴上的所有空间都是等量的
space-around: 具有非常相似的效果space-between,但Flexbox子系列的每一端都有较少的空间
点我看Demo
flex item
注意:一旦声明了flex布局,那么float, clear和vertical-align对item将无效
属性
flex item 六种属性,分别是:
1. order
2. flex-basis
3. flex-grow
4. flex-shrink
5. flex
6. align-self
order
默认情况,item
按文档顺序显示。order
属性可以改变item
的出现的位置。(索引从0开始)
.item {
order: <integer>; /* default is 0 */
}
flex-grow
定义item
放大比
.item {
flex-grow: <number>; /* default 0 */
}
flex-shrink
定义item
的收缩比例,当item
宽度之和大于容器的宽度,才会发生收缩
.item {
flex-shrink: <number>; /* default 1 */
}
number
等于负数无效
点我看Demo
flex-basis
定义item
在主轴方向上的初始大小,浏览器根据此属性,计算主轴是否有多余空间。如果不使用 box-sizing
来改变盒模型的话,那么这个属性就决定了flex
元素的内容盒(content-box)
的宽或者高(取决于主轴的方向)的尺寸大小。
.item {
flex-basis: <length> | auto; /* default auto */
}
默认值:auto
,即项目本来的大小, 这时候 item
的宽高取决于 width
或height
的值
当主轴为水平方向的时候,当设置了 flex-basis
,项目的宽度设置值会失效,flex-basis
需要跟 flex-grow
和 flex-shrink
配合使用才能发挥效果。
- 当
flex-basis
值为0 %
时,是把该项目视为零尺寸的,故即使声明该尺寸为140px
,也并没有什么用。 - 当
flex-basis
值为auto
时,则跟根据尺寸的设定值(假如为100px
),则这100px
不会纳入剩余空间。
flex
flex-grow, flex-shrink
和flex-basis
的简写
.item {
flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
}
flex-shrink
和flex-basis
为可选项
默认为0 1 auto
快捷值:auto (1 1 auto)
和 none (0 0 auto)
点我看Demo
align-self
允许单个项目有与其他项目不一样的对齐方式
.item {
align-self: auto | flex-start | flex-end | center | baseline | stretch;
}
align-self
作用在flex item
上,属性值的效果和align-items
的相似
flexbugs
浏览器前缀
flex布局需要加一些浏览器前缀来兼容大多数的浏览器。Flex布局的前缀不只是在属性前面添加浏览器前缀,不同浏览器下的属性名和属性值都不同,这是因为Flexbox布局的标准一直在变,一共有old, tweener, new 三个版本。
可能处理前缀的最好方法是使用新的语法书写CSS并通过Autoprefixer运行CSS,能够很好地处理这个问题。
Flex布局的三个版本
- new: 现在的最新版
- tweener: 2011过度版本
- old: 2009版本
兼容性
chrome | safari | firefox | Opera | IE | Edge | Android | iOS |
---|---|---|---|---|---|---|---|
20- | 3.1+ | 2-21 | 10 | 2.1+ | 3.2+ | ||
21+ | 6.1+ | 22+ | 12.1+ | 10 | 12+ | 4.4+ | 7.1+ |
21+ | 6.1+ | 22+ | 12.1+ | 11+ | 12+ | 4.4+ | 7.1+ |
混合三个版本使用可以兼容到:
- Chrome any
- Firefox any
- Safari any
- Opera 12.1+
- IE 10+
- iOS any
- Android any