CSS布局神器——伸缩盒(语法篇)

这是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
2
3
4
5
6
.container {
display: flex;
display: -webkit-flex;
}

/* 假设绝大多用户使用的浏览器版本较高,所以这里使用优雅降级的书写方式 */

(1).伸缩容器

伸缩容器中的每个子元素都是一个伸缩项目。伸缩项目的数量可以是任意的,且和BFC一样,容器内的元素和容器外的元素互不影响。

伸缩容器内部有两个轴方向,分别是主轴(main axis)和侧轴(cross axis)。主轴决定了伸缩项目的排列方向,默认是水平方向。我们可以通过容器属性 flex-direction 进行设置。侧轴和主轴是相对应的。我们来看看MDN上的一张经典图片:

flex model

简单的来说,伸缩容器基于两个轴的方向定义了它内部的flex item如何布局。

①. 容器属性

伸缩容器有六个可以设置的属性,分别是:

  1. flex-direction:定义了伸缩容器中flex item的排列方向
  2. flex-wrap:定义了主轴方向排列的item是否换行
  3. flex-flow:前两个属性的简写。
  4. justify-content:主轴方向的对齐方式
  5. align-items:侧轴方向的对齐方式
  6. align-content:多根轴线的对齐方式

对于第一、二属性,当某一个需要设置为非默认值时,我们常常将它们一起设置,比如 flex-flow: row nowrap。属性四、五常常用来设置容器在主轴和侧轴的对齐方式。例如,当希望容器中的item两侧间距相同时(在主轴方向上),我们可以设置属性 display: flex; justify-content: space-around;align-items 常常用来设置item在侧轴方向居中,例如 align-items: center;。我们常见的问题:如何让一个元素在容器中实现居中?一个简单的方法就是:

1
2
3
4
5
.container {
display: flex;
justify-container: center;
align-items: center;
}

box center

②. 主要的两个属性

关于伸缩容器,主要需要了解的就是 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;
}

justify-content

需要说明的是,在不同的浏览器中,所支持的值并不是完全一样的。比如,space-between 在 Edge的一些版本中就不被支持,再比如Chrome不支持 startendrightleft。最安全的三个值是 flex-startflex-endcenter

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;
}

align-items

相信大家对前五个属性还是比较熟悉的,那我们就来讲讲这个 baseline。它其实也很简单,就是根据文本的基线对齐:

baseline

③. 你可能不知道的两个属性值—— safeunsafe

你可能会对 safeunsafe 这两个值感到陌生。Box Alignment规范新增了Safe和Unsafe对齐的概念,对应这两个关键字。

我们以 align-items 的值来探讨一下。在下面的代码中,最后一项对于Flexbox来说太长了,左右都发生了溢出,且这种对齐方式是不安全的。

1
2
3
4
5
6
7
8
9
10
.container {  
display: flex;
flex-direction: column;
width: 100px;
align-items: unsafe center;
}

.item:last-child {
width: 200px;
}

unsafe

不安全的对齐方式导致的对齐结果可能会发生数据丢失

而安全对齐方式会避免数据丢失的出现,将溢出转移到一边(可控的一边)。

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;
}

safe

注:Chrome目前(Version 80.0.3987.116)暂不支持这两个值。
browser support

(2).伸缩项目

①. 项目属性:

现在我们来讲讲flex item的属性。项目属性用来定义每个伸缩容器中项目的动作。总共有六个:

  1. order
  2. flex-grow
  3. flex-shrink
  4. flex-basis
  5. flex
  6. 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-grow

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-growflex-shrinkflex-basis 的简写。后两个属性可选。

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

flex 有两个快捷值:autonone。前者是 1 1 auto 的简写,后者是0 0 auto的简写。我们建议优先使用 flex ,而不是单独使用某一个属性,因为简写形式可以自动地设置其它值。

align-self:它允许单个项目与其它项目设置不一样地对齐方式,并且它可以覆盖父元素的 align-items,默认值为 auto,表示继承。若没有父元素,则等同于 stretch

align-self

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

最后,floatclear 以及 vertical-align 等布局属性在伸缩项目中是不起作用的。

三、浏览器兼容

虽然伸缩容器几乎可以满足我们的所有的布局效果,但是要注意它的浏览器的兼容性。Flexbox只支持IE 10+,所以在开发中还是要根据情况来使用。

flex browser support

可以这样使用:

1
2
display: 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 给我~

0%