【第3412期】CSS 终于在 2024 年添加了垂直居中功能

科技   2024-11-08 08:01   福建  

前言

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 的对应属性是什么?让我们来看看各种对齐属性:

表格:不同布局中的对齐属性


flowflexboxgrid
align-contentblock axiscross axis (line)block axis (grid)
justify-contentno effectmain axisinline axis (grid)
align-itemsno effectcross axis (item)block axis (cell)
justify-itemsno effectno effectinline 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/

这期前端早读课
对你有帮助,帮” 
 “一下,
期待下一期,帮”
 在看” 一下 。

前端早读课
探索前端技术,体验产品的情感, 项目思考的指引,塑造独立开发者的未来。
 最新文章