这是HTML&CSS重点知识点合集第三篇。其余文章见文末。
一、伸缩盒(Flexible Box)
伸缩盒(Flexible Box),看名字就知道,一个“有弹性”的盒子啦~(笑)
好啦,正紧一点。首先,伸缩盒是啥?伸缩盒是对传统布局方案的补充。传统的布局解决方案是基于盒状模型,依赖 display
属性 + position
属性 + float
属性。但是它对于一些特殊复杂的布局实现起来就比较吃力,或者就没办法实现。比如:
- 在父内容里面垂直居中一个块内容。
- 使容器的所有子项占用等量的可用宽度/高度,而不管有多少宽度/高度可用。
- 使多列布局中的所有列采用相同的高度,即使它们包含的内容量不同。
可能你已经猜到了,弹性布局就能够使很多布局任务变得方便且灵活。下面就让我们来看看弹性布局是如何来实现的吧!
二、语法概念
系统的熟悉一下Flexbox的语法是有必要的。当然,相信有很多人在项目中都已经用过Flexbox了,那就再复习一下吧,或许会有惊喜发现哦!
Flexbox是由 伸缩容器(flex container)和 伸缩项目(flex item)组成。通过将元素的 display
属性设置为 flex
或者 inline-flex
就可以得到一个伸缩容器。display
被设置为 flex
时,伸缩容器就会被渲染成一个块级元素,而被设置为 inline-flex
时,容器会被渲染成一个行内元素。
我们可以举个例子:
1 | .container { |
(1).伸缩容器
伸缩容器中的每个子元素都是一个伸缩项目。伸缩项目的数量可以是任意的,且和BFC一样,容器内的元素和容器外的元素互不影响。
伸缩容器内部有两个轴方向,分别是主轴(main axis)和侧轴(cross axis)。主轴决定了伸缩项目的排列方向,默认是水平方向。我们可以通过容器属性 flex-direction
进行设置。侧轴和主轴是相对应的。我们来看看MDN上的一张经典图片:
简单的来说,伸缩容器基于两个轴的方向定义了它内部的flex item如何布局。
①. 容器属性
伸缩容器有六个可以设置的属性,分别是:
flex-direction
:定义了伸缩容器中flex item的排列方向flex-wrap
:定义了主轴方向排列的item是否换行flex-flow
:前两个属性的简写。justify-content
:主轴方向的对齐方式align-items
:侧轴方向的对齐方式align-content
:多根轴线的对齐方式
对于第一、二属性,当某一个需要设置为非默认值时,我们常常将它们一起设置,比如 flex-flow: row nowrap
。属性四、五常常用来设置容器在主轴和侧轴的对齐方式。例如,当希望容器中的item两侧间距相同时(在主轴方向上),我们可以设置属性 display: flex; justify-content: space-around;
。align-items
常常用来设置item在侧轴方向居中,例如 align-items: center;
。我们常见的问题:如何让一个元素在容器中实现居中?一个简单的方法就是:
1 | .container { |
②. 主要的两个属性
关于伸缩容器,主要需要了解的就是 justify-content
以及 align-items
这两个属性几个值的排布特征。
justify-content:1
2
3
4/* justify-content*/
.container {
justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly | start | end | left | right ...+ safe | unsafe;
}
需要说明的是,在不同的浏览器中,所支持的值并不是完全一样的。比如,space-between
在 Edge的一些版本中就不被支持,再比如Chrome不支持 start
、end
、right
、left
。最安全的三个值是 flex-start
、flex-end
、center
。
align-items:
说完了 justify-content
,现在我们来说说 align-items
。1
2
3
4.container {
/* align-items */
align-items: stretch | flex-start | flex-end | center | baseline | first baseline | last baseline | start | end | self-start | self-end + ...safe | unsafe;
}
相信大家对前五个属性还是比较熟悉的,那我们就来讲讲这个 baseline
。它其实也很简单,就是根据文本的基线对齐:
③. 你可能不知道的两个属性值—— safe
和 unsafe
你可能会对 safe
和 unsafe
这两个值感到陌生。Box Alignment规范新增了Safe和Unsafe对齐的概念,对应这两个关键字。
我们以 align-items
的值来探讨一下。在下面的代码中,最后一项对于Flexbox来说太长了,左右都发生了溢出,且这种对齐方式是不安全的。
1 | .container { |
不安全的对齐方式导致的对齐结果可能会发生数据丢失
而安全对齐方式会避免数据丢失的出现,将溢出转移到一边(可控的一边)。1
2
3
4
5
6
7
8
9
10.container {
display: flex;
flex-direction: column;
width: 100px;
align-items: safe center;
}
.item:last-child {
width: 200px;
}
注:Chrome目前(Version 80.0.3987.116)暂不支持这两个值。
(2).伸缩项目
①. 项目属性:
现在我们来讲讲flex item的属性。项目属性用来定义每个伸缩容器中项目的动作。总共有六个:
order
flex-grow
flex-shrink
flex-basis
flex
align-self
order:定义了每个item在主轴上的排列顺序。值越小的item排在越前面,默认值为 0
,可以设置负值。1
2
3.item {
order: <interger>; /* 默认为0 */
}
flex-grow:定义项目的放大比例。默认值为 0
,即如果有剩余空间元素也不进行放大。若值被设置为 1
,说明当有剩余位置时,剩余位置将被所有item平分。该属性不能设置为负值。1
2
3.item {
flex-grow: <number>; /* 默认为0 */
}
flex-shrink:定义了项目的缩小比例。默认值为1
,即如果空间不足,该项目将缩小。该属性不能设置为负值。1
2
3.item {
flex-shrink: <number>; /* 默认为1 */
}
flex-basis:定义了在分配多余空间之前,项目占据的主轴空间(main-size)。浏览器会根据这个属性计算主轴是否有多余空间。默认值为 auto
。1
2
3.item {
flex-basis: <length> | auto; /* 默认为auto */
}
值得注意的是,当 width
被设置且 flex-basis
的值比 width
大时,width
的值将会被覆盖。若 width
没有被设置,且当长度大于内容长度设置的 flex-basis
才会生效。例如,当 flex-basis
被设置为 0
时,且 width
没有被设置,则item的长度为所占内容的长度。(虽然 width
没有被设置,但 flex-item
的值为 0
,小于内容的长度,则 flex-basis
不生效)。可以点击链接进行实操。
flex,是属性 flex-grow
,flex-shrink
,flex-basis
的简写。后两个属性可选。1
2
3.item {
flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
}
flex
有两个快捷值:auto
、none
。前者是 1 1 auto
的简写,后者是0 0 auto
的简写。我们建议优先使用 flex
,而不是单独使用某一个属性,因为简写形式可以自动地设置其它值。
align-self:它允许单个项目与其它项目设置不一样地对齐方式,并且它可以覆盖父元素的 align-items
,默认值为 auto
,表示继承。若没有父元素,则等同于 stretch
。
1 | .item { |
最后,float
、clear
以及 vertical-align
等布局属性在伸缩项目中是不起作用的。
三、浏览器兼容
虽然伸缩容器几乎可以满足我们的所有的布局效果,但是要注意它的浏览器的兼容性。Flexbox只支持IE 10+,所以在开发中还是要根据情况来使用。
可以这样使用:1
2display: flex;
display: -webkit-flex;
这是HTML&CSS重点知识点合集的其中一篇,合集其它文章:
1.语义化HTML的重要性
2.传说中的BFC
4.网格布局 ——(语法篇)
5.CSS三栏布局实现(实践篇)
推荐阅读:
1.A Complete Guide to Flexbox-2020-02-3
2.译·Flexbox都在这里-2019-07-23
有问题?发送 issues 给我~