11.22 CSS 弹性布局对齐(Alignment)

弹性布局对齐

8. Alignment

在弹性容器处理完内容伸缩和弹性项目的尺寸确定后,将开始处理内容对齐。

和block布局中类似,flex布局中的margin属性可以用来调整项目,但功能要更强大。 弹性项目也遵循CSS Box Alignment Level 3中定义的对齐属性,在主轴线和垂直轴线方向使用简单的基于关键字的项目对齐。 这些属性使得一些常用的对齐方式变得极其简单,比如水平、垂直居中,而这在CSS2.1中实现起来则麻烦得多。

使用 auto margin对齐

弹性项目上的自动边距(auto margins)和block布局中的功能非常相似:

  • 在计算弹性长度时,auto margins被当作0

  • 在通过justify-content和align-self属性对齐之前,任何剩余空间被分布在该维度的auto margins上。

  • 对于内容溢出的box,auto margins被忽略。

请注意,如果剩余空间被分配到auto margins,该维度上的对齐属性将没有效果,因为margins已占用全部可用空间。

使用auto margins把弹性项目沿主轴线分成了不同的“组”。 下面的示例演示如何使用该特性来重新实现一个常用用户界面模式:一些操作项靠左对齐,而一些靠右对齐。这在非弹性布局中常使用float来实现。

自动边距(auto margins)和对齐(alignment)属性的效果有所不同,下面的例子演示其中的差异:

上例代码中包含两个导航条,且都处于内容溢出状态。导航条1中使用了弹性布局的自动边距特性(auto margins),导航条2中使用了自我对齐(align-self)属性的center值来居中。 可以看到在使用自动边距时,对于靠近页面左边的菜单条,可以看到菜单名的全部,而使用align-self: center后,由于是居中对齐,部分菜单被遮挡。但是其他情况下,居中显示是合适的。

主轴线(一般是水平轴线)对齐:justify-content 属性

justify-content: flex-start | flex-end | center | space-between | space-around

justify-content属性应用在弹性容器上,把弹性项沿着弹性容器的主轴线对齐。该操作发生在弹性长度以及自动边距被解决后。 它用来在所有的弹性项目已经到达最大尺寸或者不具有伸缩性时,帮助分配剩余空间。也会在发生内容溢出时影响项目的对齐。

flex-start
弹性项目向行头紧挨着填充。这个是默认值。第一个弹性项的main-start外边距边线被放置在该行的main-start边线,而后续弹性项依次平齐摆放。
flex-end
弹性项目向行尾紧挨着填充。第一个弹性项的main-end外边距边线被放置在该行的main-end边线,而后续弹性项依次平齐摆放。
center
弹性项目居中紧挨着填充。(如果剩余的自由空间是负的,则弹性项目将在两个方向上同时溢出)。
space-between
弹性项目平均分布在该行上。如果剩余空间为负或者只有一个弹性项,则该值等同于flex-start。否则,第1个弹性项的外边距和行的main-start边线对齐,而最后1个弹性项的外边距和行的main-end边线对齐,然后剩余的弹性项分布在该行上,相邻项目的间隔相等。
space-around
弹性项目平均分布在该行上,两边留有一半的间隔空间。如果剩余空间为负或者只有一个弹性项,则该值等同于center。否则,弹性项目沿该行分布,且彼此间隔相等(比如是20px),同时首尾两边和弹性容器之间留有一半的间隔(1/2*20px=10px)。

下面的例子很直观的演示了上述几个取值的实际效果和差异:

垂直轴线对齐:align-items 和 align-self 属性

align-items: flex-start | flex-end | center | baseline | stretch

align-self: auto | flex-start | flex-end | center | baseline | stretch

弹性项目可以按弹性容器当前行的cross axis来对齐,和justify-content类似,但在垂直方向上。其中align-items属性用于弹性容器,而align-self用于弹性项目。 align-items 为弹性容器中所有项目设置缺省对齐属性,包括匿名弹性项目。align-self 可以为单独的弹性项目设置对齐来覆盖缺省值。 (对于匿名弹性项目,align-self总是匹配对应弹性容器的align-items的值。)

如果弹性项的cross-axis外边距是auto,align-self属性没有效果。

align-self属性取值auto时,将计算为其父元素的align-items值,或者为stretch如果没有父元素的话。对齐属性的取值定义如下:

flex-start
弹性项的cross-start margin的边紧挨着该行的cross-start的边(一般来说,就是挨着弹性容器顶部)。
flex-end
弹性项的cross-end margin的边紧挨着该行的cross-end的边(一般来说,就是挨着弹性容器底部)。
center
弹性项的margin box在该行的cross axis上居中(垂直居中对齐)。(如果该弹性行的cross size小于弹性项,将在两个方向上同时溢出。)
baseline
如果弹性项的行内轴(inline axis)和垂直轴(cross axis)一致,该值等同于flex-start。否则,它参与基线对齐(baseline alignment):所有参与的弹性项按基线对齐,而基线和cross-start margin的边距离最大的项目被放在该行cross-start的边上(一般来说,就是基线和容器顶部距离最大的项目被定位在最上边)。

stretch
如果弹性项的垂直尺寸(cross size)属性(一般来说,就是高度)是auto,并且没有垂直外边距(cross-axis margin)是auto的,该弹性项被拉伸以适应容器高度, 其所使用的值是使项目的外边框(margin box)的垂直尺寸尽可能接近和行相同的尺寸,并依然遵循min-height/min-width/max-height/max-width属性的限制。

注意:如果弹性容器的高度被限制,该值可能会导致该项的内容溢出。


弹性项的顶部挨着容器的顶部。

上图说明了上述几个取值的实际效果和差异。每个例子中有4个不同颜色和尺寸的弹性项目。你也通过下面这个在线实例自己调试代码:

包装弹性行:align-content 属性

align-content: flex-start | flex-end | center | space-between | space-around | stretch

align-content属性应用于多行弹性容器,当垂直轴线方向有额外的空间时,该属性将弹性容器中的弹性行对齐,和justify-content类似,不过不是用来对齐水平方向上的弹性项,而是用来对齐垂直方向上的弹性行(Lines)。

请注意,此属性对单行弹性容器没有任何影响,因为单行会自动拉伸来填充弹性容器空间,不会有剩余空间。align-content可以有如下取值:

flex-start
从弹性容器顶部(cross-start)开始放置。第一行顶部和容器的顶部边界对齐,后续行紧挨着前面的行。
flex-end
从弹性容器底部(cross-end)开始放置。最后一行底部和容器的底部边界对齐,前面的行紧挨着后续行。
center
从弹性容器中间放置。这些行紧挨彼此,并且和弹性容器的中线对齐。第一行和弹性容器顶部边界的间隔和最后一行和弹性容器底部的间隔相等。
space-between
行被平均分布在弹性容器中。相邻行之间的间隔相等。弹性容器的顶部和底部边线分别和第一行和最后一行的边线贴在一起。
space-around
和space-between类似,只不过顶部和底部各多出一部分间隔,等于相邻行间隔的一半。
stretch
行被拉伸以适应可用空间。自由空间(free-space)被平均分割给所有的行。

上图演示align-content各个取值的效果和差异。你也通过下面这个在线实例自己调试代码:

弹性基线(Flex Baselines)

弹性容器的基线确定如下(在使用orders属性重新排序后):

主轴基线(main-axis baseline)
  1. 如果弹性容器的第一行中的任意项目参与基线对齐,则弹性容器主轴基线就是这些弹性项目的基线。
  2. 否则,如果第一个弹性项有一条基线和弹性容器主轴线平行,则弹性容器的主轴基线就是该基线。
  3. 否则,弹性容器的主轴基线从第一个弹性项的内容框(content box)中"合成",如果获取失败,则从弹性容器的内容框合成。
垂直轴基线(cross-axis baseline)
  1. 如果第一个弹性项有一条基线和弹性容器垂直轴平行,则弹性容器的垂直轴基线就是该基线。
  2. 否则弹性容器的垂直轴基线从第一个弹性项的内容框(content box)中"合成",如果获取失败,则从弹性容器的内容框合成。

上述描述中的"合成"一词含义,请参考阅读行内基线相关章节。

根据上述规则计算基线时,如果其中有一个框的overflow属性允许滚动,则该框必须被视为其初始滚动位置以确定其基线。

当包含在表格单元中时,弹性容器提供和一个行框(line box)和表格行(table-row)一样的基线。

关于基线规则的更多内容,请参考阅读[CSS3-ALIGN]模块的 基线规则(Baseline Rules)

上面的内容描述比较严谨,但不够形象,这里有一个CSS3 Flexbox在线实例,以所见即所得的方式很好的演示了弹性框布局的各属性取值的实际效果。