前言
CSS 在 2024 年终于引入了 align-content 属性,使得在默认布局(流布局)中实现垂直居中变得可能,不再需要依赖于 flexbox 或 grid 布局。今日前端早读课文章由 @飘飘翻译分享。
正文从这开始~~
在 2024 年的默认布局中, align-content
只需使用一个 CSS 属性即可实现垂直居中。
<div style="align-content: center; height: 100px;">
<code>align-content</code> just works!
</div>
浏览器支持情况:Chrome: 123,Firefox: 125,Safari: 17.4
新事物是什么?
CSS 布局的现状是切换到 flexbox 或 grid,因为 align-content
在默认布局 (流) 中不起作用。到 2024 年,浏览器将实现 align-content
用于流布局。这有一些优点:
你不需要使用 flexbox 或 grid,只需要一个 CSS 属性来进行对齐即可。
因此,内容不需要包裹在 div 标签中。
<!-- Works -->
<div style="display: grid; align-content: center;">
Content.
</div>
<!-- FAIL! -->
<div style="display: grid; align-content: center;">
Content with <em>multiple</em> nodes.
</div>
<!-- Works with the content wrapper -->
<div style="display: grid; align-content: center;">
<div> <!-- The extra wrapper -->
Content with <em>multiple</em> nodes.
</div>
</div>
<!-- Works without the content wrapper -->
<div style="align-content: center;">
Content with <em>multiple</em> nodes.
</div>
令人惊叹的是,经过几十年的发展,CSS 终于有了一个可以控制垂直对齐的单一属性!
垂直居中 —— 一段历史
浏览器很有趣,像对齐等基本需求很久都没有简单的解决方案。以下是如何在 LibreOffice 中对齐内容的方法:
以下是如何在浏览器中垂直居中的方法(水平居中是另一个话题)
方法 1:表格单元格
稳健性:★★★★☆
共有四种主要布局:流式布局(默认)、表格布局、弹性布局和网格布局。如何对元素进行对齐取决于容器的布局。弹性布局和网格布局是较晚才添加的,因此表格布局是首选。
<div style="display: table;">
<div style="display: table-cell; vertical-align: middle;">
Content.
</div>
</div>
一张表格完全可以仅通过 CSS 来创建,但需要通过这种间接方式来实现,这实在令人遗憾。
方法 2:绝对定位
稳健性:☆☆☆☆☆
原因不明,人们不断发明越来越间接的做事方式。
<div style="position: relative;">
<div style="position: absolute; top: 50%; transform: translateY(-50%);">
Content.
</div>
</div>
这个例子使用了绝对定位来绕过布局,因为流动布局对我们没有帮助:
用
position: relative
标记参考容器。使用
position: absolute; top: 50%
将内容的边缘置于中心位置。使用
transform: translateY(-50%)
将内容偏移到边缘。
方法 3:内联内容
稳健性:☆☆☆☆☆
虽然流式布局有助于内容的填充,但它无法帮助进行内容对齐。它允许在同一行内进行垂直对齐。那么为什么不让每一行的高度与容器相同呢?
<div class="container">
::before
<div class="content">Content.</div>
</div>
.container::before {
content: '';
height: 100%;
display: inline-block;
vertical-align: middle;
}
.content {
display: inline-block;
vertical-align: middle;
}
这存在一些缺点:除了牺牲一个伪元素外,还有一个零宽度的 “支柱” 字符位于开头,可能会导致混乱。
方法 4:单行弹性布局
稳健性:★★★★☆
弹性布局是在万维网兴起 20 年后才开始广泛应用的。它有两种模式:单行模式(默认模式)和多行模式。在单行模式下,行填充垂直空间,并且会将行内的元素进行对齐。
<div style="display: flex; align-items: center;">
<div>Content.</div>
</div>
或者,将线条排列成列状,并使用 justify-content
对项目进行对齐。
<div style="display: flex; flex-flow: column; justify-content: center;">
<div>Content.</div>
</div>
方法 5:多行 flexbox
稳健性:★★★★☆
在多行弹性布局中,每一行不再占据垂直空间,因此,只有一项内容的行可以与 align-content
对齐。
<div style="display: flex; flex-flow: row wrap; align-content: center;">
<div>Content.</div>
</div>
方法 6:网格布局
稳健性:★★★★☆
网格出现得更晚,对齐变得更加简单。
<div style="display: grid; align-content: center;">
<div>Content.</div>
</div>
方法 7:网格单元
稳健性:★★★★☆
注意与前面一个例子之间的细微差别:
align-content:它将单元格居中放置在容器中。
align-items:它会将内容居中放置在单元格中,同时让单元格伸缩以适应容器的大小。
<div style="display: grid; align-items: center;">
<div>Content.</div>
</div>
做同一件事情似乎有很多种方法。
方法 8:自动边距
稳健性:★★★★☆
在流式布局中, margin:auto
水平居中,但垂直居中不是默认行为。而 flexbox 和 grid 则不会出现这种荒谬的情况。
<div style="display: grid;">
<div style="margin-block: auto;">
Content.
</div>
</div>
不过,我还是不明白为什么边距也被设计用来控制对齐方式。
方法 9:align-content: center;
稳健性:★★★★★
为什么浏览器一开始没有添加这个功能呢?
<div style="align-content: center;">
<code>align-content</code> just works!
</div>
第一种方法中的表格单元格也是如此,不需要内容容器(虽然需要表格容器)。我们又回到了原点!
二维化
有没有一个用于水平对齐的单一属性?align-content 的对应属性是什么?让我们来看看各种对齐属性:
表格:不同布局中的对齐属性
flow | flexbox | grid | |
---|---|---|---|
align-content | block axis | cross axis (line) | block axis (grid) |
justify-content | no effect | main axis | inline axis (grid) |
align-items | no effect | cross axis (item) | block axis (cell) |
justify-items | no effect | no effect | inline axis (cell) |
背景:CSS 轴线术语
块轴通常是垂直的,而内联轴是水平的。需要使用这些术语是因为垂直方向确实存在,因此块轴和内联轴是相对于文本方向而言的。这与弹性布局项目方向中的主轴和交叉轴之间的关系类似。
关于命名
从 CSS 的属性名称中,我们可以推断出 CSS 的设计理念:
align-*
大部分是垂直的,而justify-*
大部分是水平的。*-content
和*-items
控制不同层次的对象?
justify-content
是 align-content
的对应元素,它在网格布局中非常有用,但在流动布局中没有效果。而 place-content
简写符同时设置了这两个属性。
"Align" vs. "justify"
为什么 align
和 justify
在 CSS 中指的是轴线?justify-*
是否受到文本对齐的启发?考虑到还有 text-align: justify
,这让人感到混乱。
通常人们说 “对齐” 时,他们指的是单个对象的位置,而 “justify” 意味着多个对象的分布。
在 CSS 中, justify-*
和 align-*
与文本对齐类似,因为它们都可以接受类似于 space-between 的值;只是它们的轴线不同而已!
如何记忆:文本对齐是水平的,所以也是 justify-*
。
“Content” vs. “items”
在 flexbox 中,“content” 和 “items” 容易让人混淆:
主轴:
justify-content
控制 items,而justify-items
无效。交叉轴:单行模式与多行模式之间的差异
结论:“items” 是用来表示可以单独对齐的项目。在主轴上,flex items 不能单独对齐,所以是 “content”。
为什么 CSS 如此令人困惑?
即使我们忽略历史遗留问题,CSS 对我们大多数人来说还是太复杂了。它有数百个命名不佳的属性,每个属性都能以不可预料的方式影响最终结果。
软件项目失控
这是一个关于软件设计范式的案例研究:
Unix:具有正交性、可组合的基本功能,可以独立地对其进行推理。
CSS(中央软件系统):只是通过不断添加越来越多的选项来修改软件。
早期的万维网只是一些互相链接的文档。CSS 是为了在不考虑布局的情况下而对文档进行格式化而创建的。随着时间的推移,CSS 获得了一些随机的布局功能,但缺乏一个连贯的愿景。
通常在 CSS 中,你可以用很多种方法来完成某件事情,但可能没有一种方法是合理的。本文将介绍一种新的垂直对齐方式,而水平轴仍然有所不同。
相比之下,LibreOffice 遵循的是正交、可组合的基本原则:
线条排列整齐,垂直方向与水平方向完全一致。
统一对齐是可能的,因为 “对齐” 和 “居中” 是相互独立的,而不是混在一起的。
“Align” 是容器的一个属性。
"Justify" 是段落的一个属性。
"对齐" 和 "justify" 可以以任何方式组合。
libreoffice justify LibreOffice
示例:https://codepen.io/byo-books/pen/Porpmab
关于本文
译者:@飘飘
作者:@James Smith
原文:https://build-your-own.org/blog/20240813_css_vertical_center/
这期前端早读课
对你有帮助,帮” 赞 “一下,
期待下一期,帮” 在看” 一下 。