一、弹性盒模型
1. 为什么要用弹性盒模型?
弹性盒子是一种用于按行或按列布局元素的一维布局方法 。元素可以膨胀以填充额外的空间, 收缩以适应更小的空间。 ————MDN文档《弹性盒子》
换句话说,运用弹性盒模型能跨浏览器更方便的调整元素内容的布局,使布局任务变得更为方便和容易。
在弹性盒模型创建之前,能够跨浏览器调整布局的只有 floats 和 positioning 属性
2. 弹性盒模型可以做什么?
- 在父元素内单个元素水平居中,垂直居中
- 在父元素内多个元素等量或成比例占用可用宽度/高度(不管有多少宽度/高度可用)
- 在父元素内多个元素调整对齐方式()
3. 模型说明
felx item容器: 设置了display:flex的父元素,被称之为flex容器
main axis主轴: flex元素放置方向延伸的轴。轴的开始和结束分别为main start和main end
cross axis交叉轴: 垂直于主轴方向的轴。轴的开始和结束分别为cross start和cross end
flex item: 容器中的弹性元素
二、属性应用
1. 列和行的基本布局(弹性盒子的属性)
flex-direction属性 指定主轴的方向。
可选的值有:
row
(default)row-reverse
column
column-reverse
flex-wrap属性 规定能否换行。弹性盒模型中的弹性元素一般为单行排列,当元素在布局中使用定宽或定高时,元素将溢出而破坏布局。换行可以改善这一种情况。可选的值有:nowrap
(default)wrap
wrap-reverse
flex-flow属性 上述两个属性的缩写。
2. 弹性项的尺寸调整(弹性项的属性)
flex属性 值为一个无单位的比例数值,表示flex项沿主轴所占的可用空间。例子:
<html>
<header>
......
<style>
article {
padding: 10px;
margin: 10px;
background: aqua;
flex: 1
}
section {
display: flex;
}
</style>
</header>
<body>
<section>
<article>
1111111111111111111111111
</article>
<article>
2222222222222222222222222
</article>
<article>
3333333333333333333333333
</article>
<article>
4444444444444444444444444
</article>
</section>
</body>
</html>
此时为等距排列。可以为不同的<article>的flex属性设置不同的数值以实现成比例的排列。使用CSS选择器:article.nth-of-type(2)来选择第二个<article>元素。
也可以指定flex的最小值,添加一个数值即可,例如:
article {
flex: 1 200px;
}
article:nth-of-type(3) {
flex: 2 200px;
}
上述规则会首先给出200px的可用空间,剩余的空间再按比例共享。
(注意:flex属性本身也是一个缩写属性,可以最多指定三个不同的值:flex-grow,flex-shrink,flex-basis。 flex-grow就是上面讨论的无单位比例的情况,flex-basis就是上面讨论的最小值的情况。flex-shrink比较高级,请参考MDN文档《flex-shrink》)
3. 对齐方式
(1)水平上的对齐(行列默认布局)
align-items属性: 控制flex项在交叉轴(竖直轴)的对齐方式。可选的值有:
stretch
(default) 如果容器有固定高度,所有flex项沿交叉轴拉伸以填充;如果容器没有固定高度,则所有flex项的高度与最长的flex项的高度一致。center
每个felx项保持原有高度,但在交叉轴上居中。flex-start
flex-end
(可以使用align-self属性覆盖align-items的行为,即定制单个元素的行为)
(2)竖直上的对齐(行列默认布局)
justify-content属性: 控制flex项在主轴(水平轴)的对齐方式。可选的值有:
flex-start
(default)所有flex项位于主轴开始处排列。flex-end
所有flex项位于主轴开始处排列center
space-around
所有flex项沿主轴均匀分布,第一个元素和最后一个元素距离容器边界的距离是相邻元素之间距离的一半。space-between
所有flex项沿主轴均匀分布,但不会在两端留下任何空间
4. 弹性项的排序
例子:
section:first-child{
order:1;
}
则第一个<article>元素的内容移到了主轴的末尾。
order属性实现的细节:
- 所有 flex 项默认的
order
值是 0。 - order 值大的 flex 项比 order 值小的在显示顺序中更靠后。
- 相同 order 值的 flex 项按源顺序显示。所以假如你有四个元素,其 order 值分别是2,1,1和0,那么它们的显示顺序就分别是第四,第二,第三,和第一。
- 第三个元素显示在第二个后面是因为它们的 order 值一样,且第三个元素在源顺序中排在第二个后面。
三、flex嵌套
借鉴一下MDN中的例子:
section - article
article
article - div - button
div button
div button
button
button
上述是一个简单的子节点布局,我们让三个<article>元素为<section>中的弹性项,也让三个<div>元素为第三个<article>中的弹性项,五个<button>元素为第一个<div>中的弹性项.
如此布局需要的代码:
section {
display: flex;
}
article {
flex: 1 200px;
}
article:nth-of-type(3) {
flex: 3 200px;
display: flex;
flex-flow: column;
}
article:nth-of-type(3) div:first-child {
flex: 1 100px;
display: flex;
flex-flow: row wrap;
align-items: center;
justify-content: space-around;
}
button {
flex: 1;
margin: 5px;
font-size: 18px;
line-height: 1.5;
}
四、关于兼容性
大多数浏览器都支持 弹性盒子,诸如 Firefox, Chrome, Opera, Microsoft Edge 和 IE 11,较新版本的 Android/iOS 等等。但是你应该要意识到仍旧有被人使用的老浏览器不支持 弹性盒子(或者支持,但是只是支持非常非常老版本的 弹性盒子)。弹性盒子相较其他一些 CSS 特性可能更为棘手。例如,如果浏览器缺少 CSS 阴影,则该网站可能仍然可用。 但是假如不支持 弹性盒子功能就会完全打破布局,使其不可用。 ——MDN文档《弹性盒子》