1、简介
Flexbox 模块提供了一个有效的布局方式,即使不知道视窗大小或者未知元素情况下都可以智能的,灵活的调整和分配元素和空间两者的关系。简单来说就是,可以自动调整,计算元素在容器空间中的大小。
上图是一个横向的,文本流从左到右的弹性布局示意图。这里有几个概念:
(1)弹性容器(Flex container),指一个声明为 flex 或者 inline-flex 的元素,是所有 Flex items 的父元素。
(2)弹性项目(Flex item),指 flex 容器内的直接孩子元素;弹性容器中的直接文本项默认为弹性项目。
(3)主轴(main axis)和侧轴(cross axis),类似于二维中的 X 和 Y 轴,主轴由属性 flex-direction 来定义,与主轴垂直的轴则是侧轴。
2、使用
要使用弹性布局,需要定义一个弹性容器,通过声明 display 属性为 flex 或 inline-flex 来将此元素定义为弹性容器。即将父元素定义为弹性容器。(IE 系列浏览器中 IE10+ 支持)
<style type="text/css">
ul{
display: flex;
}
li{
width: 100px;
height: 100px;
background-color: #ccc;
margin: 8px;
list-style-type: none;
}
</style>
<ul>
<li></li>
<li></li>
<li></li>
</ul>
上图可看出,子元素并排显示,默认情况下
li
是垂直显示,此时使用
display:flex
使其并排显示,从左到右,就像你使用了
float
一样。此时,
ul
为 flex 容器,而其子元素
li
就变成了 flex 项目。
3、Flex 容器属性
Flex 容器属性有:
- flex-direction 定义排列方向
- row 默认值,主轴为水平方向,从左到右排列
- row-reverse 主轴为水平方向,从右到左排列
- column 主轴为垂直方向,从上到下排列
- column-reverse 主轴为垂直方向,从下到上排列
- flex-wrap 定义是否新行显示,以及新行的排列方向
- nowrap 默认值,显示在同一行,不换行
- wrap 一行显示不了时使用新行显示
- wrap-reverse 同 wrap ,但是从下向上显示
- flex-flow 是 flex-direction 和 flex-wrap 的简写方式
- 使用方法 flex-flow: <’flex-direction’> || <’flex-wrap’>
- 默认值为:row nowrap
- justify-content 定义弹性项目在主轴上的对齐方式
- flex-start 默认值,从起始位置对齐,通常为左对齐
- flex-end 从结束位置对齐,通常为右对齐
- center 居中对齐
- space-between 两端对齐,平均间隔
- space-around 每个元素都有相等的外边距,相邻元素外边距不会叠加
- align-items 定义弹性项目在侧轴上的对齐方式
- stretch 默认值,弹性项目在没指定高度或者高度为 auto 的情况下,则高度会占满空间
- flex-start 侧轴起点开始对齐(顶部对齐)
- flex-end 从侧轴结束位置对齐(底部对齐)
- center 相对侧轴居中对齐(居中对齐)
- baseline 与基线对齐
- align-content 定义多行在侧轴的对齐方式,当只有一行是,不起作用
- stretch 默认值,各行会伸展以占满整个纵轴空间
- flex-start 对齐到纵轴起点
- flex-end 对齐到纵轴终点
- center 相对纵轴中间对齐
- space-between 各行相对纵轴两端对齐,各行间隔相等
- space-around 各行都有相等的外边距,各行的外边距不会叠加
4、flex 项目属性
Flex 项目属性有:
- flex-grow 数字,定义弹性项目的放大比例,默认0
- flex-shrink 数字,定义弹性项目的缩小比例,默认1, 值 0 表示不缩小
- flex-basis 数字,定义弹性项目的默认尺寸,默认 auto(根据内容大小计算)
-
flex 是 flex-grow flex-shrink flex-basis 的缩写,默认值为 0 1 auto
flex:正数 与 flex: 正数 1 0 相同
- align-self 定义此弹性项目本身的对齐方式,会覆盖弹性容器 align-items 定义的对齐方式
- auto 从弹性容器继承
- stretch 弹性项目在没指定高度或高度为 auto 的情况下,则高度会占满空间
- flex-start 侧轴起点开始对齐
- flex-end 从侧轴结束位置对齐
- center 相对侧轴居中对齐
- baseline 与基线对齐
- order 数字,定义弹性项目的显示顺序,数字越小越靠前
(1)相对和绝对的 Flex 项目
flex 项目属性中的 flex 属性值只设置 flex-grow 和 flex-shrink 值 或 只有 flex-grow 值,这就是绝对 flex 项目,此时, flex-basis 默认为 0。只有设置了 flex-basis 就是一个相对 flex 项目
li{/* 这是一个绝对的 flex 项目*/
flex: 1 1; /* flex-basis 默认为 0*/
}
li{/* 这是一个相对的 flex 项目*/
flex-basis: 100px; /* 只设置了 flex-basis */
}
相对 flex 项目内的间距是根据它的内容大小来计算。而绝对 flex 项目中,只根据 flex 属性来计算,而不是内容。
相对 flex 项目,此时,各个 flex 项目大小不一致,都根据自身的内容计算宽度。
<style type="text/css">
ul {
display: flex; /*触发弹性盒*/
list-style: none;
}
li {
flex: auto; /*记住这与 flex: 1 1 auto; 相同*/
border: 2px solid red;
margin: 2em;
}
</style>
<ul>
<li>
This is just some random text to buttress the point being explained.
Some more random text to buttress the point being explained.
</li>
<li>This is just a shorter random text.</li>
</ul>
绝对 flex 项目,此时各个 flex 项目大小一致,都是根据 flex 属性计算宽度。
li {
flex: 1; /*记住这与 flex: 1 1 0; 相同*/
border: 2px solid red;
margin: 2em;
}
(2)margin: auto 对齐
当在 flex 项目上使用 margin: auto 时,值为 auto 的方向(左、右或两者都是)会占据所有空间。
<style type="text/css">
ul {
display: flex; /*触发弹性盒*/
list-style: none;
border: 2px solid red;
}
li {
flex: 0 0 auto;
border: 2px solid black;
}
</style>
<ul>
<li>Area A</li>
<li>Area B</li>
</ul>
上图可以看到,没加 margin: auto 时,右边会有一些多余空间。
下面给 A 区域加上 margin-right: auto
li:nth-child(1){
margin-right: auto;
}
上图可以看到,加 margin:auto 后,A 区域的 margin 将剩余空间占满
注意:当在一个 flex 项目上使用自动外边距(margin: auto)时,justify-content 属性将不起作用。
5、注意
(1)margin: auto 对齐
当在 flex 项目上使用 margin: auto 时,值为 auto 的方向(左、右或两者都是)会占据所有空间。
(2)设置 flex-direction: column 后主、侧轴交换。
未设置 flex-direction: column 时,主轴方向是从左到右,侧轴方向是从上到下。
设置 flex-direction: column 时,主轴方向从上到下,侧轴方向从右到左。
下面是默认情况:
<style type="text/css">
ul {
display: flex; /*触发弹性盒*/
list-style: none;
border: 2px solid red;
}
li {
flex: 0 0 auto;
border: 2px solid black;
}
</style>
<ul>
<li>Area A</li>
<li>Area B</li>
</ul>
设置设置 flex-direction: column
ul {
display: flex; /*触发弹性盒*/
list-style: none;
border: 2px solid red;
flex-direction: column;
}
此时,可以看到,项目的宽度填满了空间。如果使用 flex-basis 来使项目变窄时,将发现,此时的 flex-basis 影响的不在是宽度,而是高度,因为主、侧轴发生了变化。
li {
flex: 0 0 auto;
border: 2px solid black;
flex-basis: 50px;
}
此时,要想正确的减少 flex 项目的宽度,应该使用 width 属性。
li {
flex: 0 0 auto;
border: 2px solid black;
width: 50px;
}
此时,要将 flex 项目居中,应该使用 align-items: center 属性。即主、纵轴交换,则原来影响主轴的属性,改变后将影响侧轴的属性。原来影响侧轴的属性,改变后将影响主轴的属性。
ul {
display: flex; /*触发弹性盒*/
list-style: none;
border: 2px solid red;
flex-direction: column;
align-items: center;
}
参考理解 Flexbox:你需要知道的一切