处理不同的文本方向
到目前为止,我们在 CSS 学习中遇到的许多属性和值都与屏幕的物理尺寸相关。例如,我们为一个盒子创建上、右、下和左边框。这些物理尺寸非常适合水平查看的内容,而且默认情况下,Web 更倾向于支持从左到右的语言(例如英语或法语),而不是从右到左的语言(例如阿拉伯语)。
然而,近年来,CSS 已经发展到能更好地支持不同内容方向,包括从右到左,以及从上到下的内容(例如日语)——这些不同的方向性被称为书写模式。随着你的学习深入并开始使用布局,理解书写模式会对你非常有帮助,因此我们现在将介绍它们。
什么是书写模式?
CSS 中的书写模式指的是文本是水平还是垂直排列。writing-mode 属性允许我们从一种书写模式切换到另一种。你不需要使用垂直书写模式的语言来做这件事——你也可以出于创意目的更改布局部分的书写模式。
在下面的示例中,我们使用 writing-mode: vertical-rl 显示了一个标题。文本现在垂直排列。垂直文本在图形设计中很常见,可以为你的网页设计增添更有趣的外观和感觉。
<h1>Play with writing modes</h1>
body {
font-family: sans-serif;
height: 300px;
}
h1 {
writing-mode: vertical-rl;
color: white;
background-color: black;
padding: 10px;
}
writing-mode 属性的三个可能值是:
horizontal-tb:块流方向从上到下。句子水平排列。vertical-rl:块流方向从右到左。句子垂直排列。vertical-lr:块流方向从左到右。句子垂直排列。
所以 writing-mode 属性实际上设置了块级元素在页面上显示的方向——要么从上到下,要么从右到左,要么从左到右。这反过来又决定了文本在句子中的流向。
书写模式与块和内联布局
我们已经讨论了块级和内联布局,以及有些内容显示为块级元素,有些显示为内联元素的事实。正如我们上面所述,块级和内联与文档的书写模式相关联,而不是物理屏幕。只有在使用水平显示文本(如英语)的书写模式时,块级才从页面顶部到底部显示。
如果我们看一个例子,这会更清楚。在下一个例子中,我有两个包含标题和段落的盒子。第一个盒子使用 writing-mode: horizontal-tb,这是一种水平书写、从上到下的书写模式。第二个盒子使用 writing-mode: vertical-rl;这是一种垂直书写、从右到左的书写模式。
<div class="wrapper">
<div class="box horizontal">
<h2>Heading</h2>
<p>A paragraph demonstrating writing modes in CSS.</p>
</div>
<div class="box vertical">
<h2>Heading</h2>
<p>A paragraph demonstrating writing modes in CSS.</p>
</div>
</div>
body {
font-family: sans-serif;
height: 300px;
}
.wrapper {
display: flex;
}
.box {
border: 1px solid #cccccc;
padding: 0.5em;
margin: 10px;
}
.horizontal {
writing-mode: horizontal-tb;
}
.vertical {
writing-mode: vertical-rl;
}
当我们切换书写模式时,我们正在改变哪个方向是块级,哪个是内联。在 horizontal-tb 书写模式下,块方向从上到下运行;在 vertical-rl 书写模式下,块方向水平从右到左运行。因此,块维度始终是块在所使用的书写模式下在页面上显示的方向。内联维度始终是句子流动的方向。
此图显示了水平书写模式下的两个维度。
此图显示了垂直书写模式下的两个维度。

一旦你开始研究 CSS 布局,尤其是较新的布局方法,这种块级和内联的概念就会变得非常重要。我们将在后面重新讨论它。
方向
除了书写模式,我们还有文本方向。如上所述,一些语言,如阿拉伯语,是水平书写的,但方向是从右到左。这不太可能在创意上使用——如果你想将某些东西对齐到右边,还有其他方法可以做到——然而,理解这是 CSS 性质的一部分很重要。Web 不仅仅适用于从左到右显示的语言!
由于书写模式和文本方向可以改变,较新的 CSS 布局方法不提及左右、上下。相反,它们会讨论开始和结束以及内联和块的概念。现在不必过于担心,但在你开始研究布局时,请记住这些概念;你会发现它对你理解 CSS 非常有帮助。
逻辑属性和值
在学习的这个阶段讨论书写模式和方向的原因是,我们已经看过很多与屏幕物理尺寸相关的属性,而这些属性在水平书写模式下更有意义。
我们再来看看我们的两个盒子——一个使用 horizontal-tb 书写模式,一个使用 vertical-rl。我给这两个盒子都设置了 width。你可以看到当盒子处于垂直书写模式时,它仍然有一个宽度,这导致文本溢出。
<div class="wrapper">
<div class="box horizontal">
<h2>Heading</h2>
<p>A paragraph demonstrating writing modes in CSS.</p>
<p>These boxes have a width.</p>
</div>
<div class="box vertical">
<h2>Heading</h2>
<p>A paragraph demonstrating writing modes in CSS.</p>
<p>These boxes have a width.</p>
</div>
</div>
body {
font-family: sans-serif;
height: 300px;
}
.wrapper {
display: flex;
}
.box {
border: 1px solid #cccccc;
padding: 0.5em;
margin: 10px;
width: 100px;
}
.horizontal {
writing-mode: horizontal-tb;
}
.vertical {
writing-mode: vertical-rl;
}
在这种情况下,我们真正想要的是根据书写模式来交换高度和宽度。当我们在垂直书写模式下时,我们希望盒子在块级维度上扩展,就像它在水平模式下一样。
为了简化这一点,CSS 最近开发了一组映射属性。这些属性本质上是用逻辑或流相对版本替换了物理属性——例如 width 和 height。
当处于水平书写模式时,映射到 width 的属性称为 inline-size——它指内联维度的尺寸。height 的属性名为 block-size,是块维度的尺寸。你可以从下面的示例中看到它是如何工作的,我们用 inline-size 替换了 width。
<div class="wrapper">
<div class="box horizontal">
<h2>Heading</h2>
<p>A paragraph demonstrating writing modes in CSS.</p>
<p>These boxes have inline-size.</p>
</div>
<div class="box vertical">
<h2>Heading</h2>
<p>A paragraph demonstrating writing modes in CSS.</p>
<p>These boxes have inline-size.</p>
</div>
</div>
.wrapper {
display: flex;
}
.box {
border: 1px solid #cccccc;
padding: 0.5em;
margin: 10px;
inline-size: 100px;
}
.horizontal {
writing-mode: horizontal-tb;
}
.vertical {
writing-mode: vertical-rl;
}
逻辑外边距、边框和内边距属性
在过去的两节课中,我们学习了 CSS 盒模型和 CSS 边框。在外边距、边框和内边距属性中,你会发现许多物理属性的实例,例如 margin-top、padding-left 和 border-bottom。就像我们有宽度和高度的映射一样,这些属性也有映射。
margin-top 属性映射到 margin-block-start — 这将始终指块维度的起始外边距。
padding-left 属性映射到 padding-inline-start,这是应用于内联方向起始的内边距。这将是句子在该书写模式中开始的位置。border-bottom 属性映射到 border-block-end,这是块维度末尾的边框。
你可以在下面看到物理属性和逻辑属性之间的比较。
如果你通过将 .box 上的 writing-mode 属性切换为 vertical-rl 来改变盒子的书写模式,你会看到物理属性如何保持与其物理方向绑定,而逻辑属性则随书写模式切换。
你还可以看到 h2 有一个黑色的 border-bottom。你能想出如何在两种书写模式下都让这个下边框始终在文本下方吗?
<div class="wrapper">
<div class="box physical">
<h2>Physical Properties</h2>
<p>A paragraph demonstrating logical properties in CSS.</p>
</div>
<div class="box logical">
<h2>Logical Properties</h2>
<p>A paragraph demonstrating logical properties in CSS.</p>
</div>
</div>
.wrapper {
display: flex;
border: 5px solid #cccccc;
}
.box {
margin-right: 30px;
inline-size: 200px;
writing-mode: horizontal-tb;
}
.logical {
margin-block-start: 20px;
padding-inline-end: 2em;
padding-block-start: 2px;
border-block-start: 5px solid pink;
border-inline-end: 10px dotted rebeccapurple;
border-block-end: 1em double orange;
border-inline-start: 1px solid black;
}
.physical {
margin-top: 20px;
padding-right: 2em;
padding-top: 2px;
border-top: 5px solid pink;
border-right: 10px dotted rebeccapurple;
border-bottom: 1em double orange;
border-left: 1px solid black;
}
h2 {
border-bottom: 5px solid black;
}
考虑到所有单独的边框长手属性,属性的数量非常庞大,你可以在 MDN 页面 逻辑属性和值上看到所有映射属性。
逻辑值
到目前为止,我们已经研究了逻辑属性名称。还有一些属性采用 top、right、bottom 和 left 的物理值。这些值也有映射,映射到逻辑值——block-start、inline-end、block-end 和 inline-start。
例如,你可以向左浮动图像,使文本环绕图像。你可以用 inline-start 替换 left,如下例所示。
将此示例中的书写模式更改为 vertical-rl,以查看图像会发生什么。将 inline-start 更改为 inline-end 以更改浮动
<div class="wrapper">
<div class="box logical">
<img
alt="star"
src="https://mdn.github.io/shared-assets/images/examples/big-star.png" />
<p>
This box uses logical properties. The star image has been floated
inline-start, it also has a margin on the inline-end and block-end.
</p>
</div>
</div>
.wrapper {
display: flex;
}
.box {
margin: 10px;
padding: 0.5em;
border: 1px solid #cccccc;
inline-size: 200px;
writing-mode: horizontal-tb;
}
img {
float: inline-start;
margin-inline-end: 10px;
margin-block-end: 10px;
}
在这里,我们还使用逻辑外边距值来确保无论书写模式如何,外边距都处于正确的位置。
你应该使用物理属性还是逻辑属性?
逻辑属性和值比其物理对应物新,因此最近才在浏览器中实现。你可以在 MDN 上的任何属性页面上查看浏览器支持的范围。如果你不使用多种书写模式,那么目前你可能更喜欢使用物理版本。然而,最终我们期望人们在大多数情况下过渡到逻辑版本,因为一旦你开始处理 flexbox 和 grid 等布局方法,它们就非常有意义了。
总结
本课程中解释的概念在 CSS 中变得越来越重要。理解块和内联方向——以及文本流如何随书写模式的变化而变化——将在未来非常有用。即使你从未使用过除水平书写模式之外的任何书写模式,它也将帮助你理解 CSS。