流式布局和书写模式

CSS 2.1 规范详细描述了普通流的行为方式,并假设采用水平书写模式。布局属性在垂直书写模式下也应以相同方式工作。在本指南中,我们将探讨流式布局与不同文档书写模式结合使用时的行为方式。

这不是一份关于 CSS 中书写模式使用的全面指南,其目的在于记录流式布局可能以意想不到的方式与书写模式交互的区域。另请参阅部分提供了更多书写模式资源的链接。

书写模式规范

CSS 书写模式级别 3 规范定义了文档书写模式更改对流式布局的影响。在书写模式简介中,规范指出

“CSS 中的书写模式由 writing-modedirectiontext-orientation 属性决定。它主要根据其行内基方向和块流方向进行定义。”

规范将行内基方向定义为内容在行中排列的方向。这定义了行内方向的起始和结束。起始是句子开始的地方,结束是一行文本在换行之前结束的地方。

块流方向是框(例如段落)在该书写模式中堆叠的方向。CSS writing-mode 属性控制块流方向。如果你想将你的页面或页面的一部分更改为 vertical-lr,你可以在元素上设置 writing-mode: vertical-lr,这将改变块的方向,从而也改变行内方向。

虽然某些语言会使用特定的书写模式或文本方向,但我们也可以使用这些属性来达到创意效果,例如垂直运行标题。

html
<div class="box">
  <h1>A heading</h1>
  <p>
    One November night in the year 1782, so the story runs, two brothers sat
    over their winter fire in the little French town of Annonay, watching the
    grey smoke-wreaths from the hearth curl up the wide chimney. Their names
    were Stephen and Joseph Montgolfier, they were papermakers by trade, and
    were noted as possessing thoughtful minds and a deep interest in all
    scientific knowledge and new discovery.
  </p>
</div>
css
body {
  font: 1.2em sans-serif;
}
h1 {
  writing-mode: vertical-lr;
  float: left;
}

块流方向

writing-mode 属性接受 horizontal-tbvertical-rlvertical-lr 值。这些值控制块在页面上流动的方向。初始值是 horizontal-tb,这是一种从上到下的块流方向,具有水平行内方向。从左到右的语言(例如英语)和从右到左的语言(例如阿拉伯语)都是 horizontal-tb

以下示例明确显示了使用初始 horizontal-tb 值的块

html
<div class="box">
  <p>
    One November night in the year 1782, so the story runs, two brothers sat
    over their winter fire in the little French town of Annonay, watching the
    grey smoke-wreaths from the hearth curl up the wide chimney. Their names
    were Stephen and Joseph Montgolfier, they were papermakers by trade, and
    were noted as possessing thoughtful minds and a deep interest in all
    scientific knowledge and new discovery.
  </p>
  <p>
    Before that night—a memorable night, as it was to prove—hundreds of millions
    of people had watched the rising smoke-wreaths of their fires without
    drawing any special inspiration from the fact.
  </p>
</div>
css
body {
  font: 1.2em sans-serif;
}
.box {
  writing-mode: horizontal-tb;
}

将其与 vertical-rl 值进行比较,后者提供从右到左的块流方向和垂直行内方向,如下一个示例所示。

css
body {
  font: 1.2em sans-serif;
}
.box {
  writing-mode: vertical-rl;
}

最后一个示例演示了 writing-mode 的第三个可能值——vertical-lr。这会给你一个从左到右的块流方向和垂直行内方向。

css
body {
  font: 1.2em sans-serif;
}
.box {
  writing-mode: vertical-lr;
}

嵌套书写模式

当嵌套框被指定与其父级不同的书写模式时,行内级别框将显示为具有 display: inline-block

html
<div class="box">
  <p>
    One <span>November</span> night in the year 1782, so the story runs, two
    brothers sat over their winter fire in the little French town of Annonay,
    watching the grey smoke-wreaths from the hearth curl up the wide chimney.
    Their names were Stephen and Joseph Montgolfier, they were papermakers by
    trade, and were noted as possessing thoughtful minds and a deep interest in
    all scientific knowledge and new discovery.
  </p>
</div>
css
body {
  font: 1.2em sans-serif;
}
.box {
  writing-mode: vertical-rl;
}
.box span {
  writing-mode: horizontal-tb;
  padding: 10px;
  border: 1px solid rebeccapurple;
}

块级框将建立一个新的块格式化上下文,这意味着如果其内部显示类型是 flow,它将获得计算的显示类型 flow-root。这在下一个示例中显示,其中显示为 horizontal-tb 的框包含一个浮动元素,该浮动元素由于其父级建立新的 BFC 而被包含。

html
<div class="box">
  <p>
    One November night in the year 1782, so the story runs, two brothers sat
    over their winter fire in the little French town of Annonay, watching the
    grey smoke-wreaths from the hearth curl up the wide chimney.
  </p>

  <div>
    <div class="float"></div>
    This box should establish a new BFC.
  </div>

  <p>
    Their names were Stephen and Joseph Montgolfier, they were papermakers by
    trade, and were noted as possessing thoughtful minds and a deep interest in
    all scientific knowledge and new discovery.
  </p>
</div>
css
body {
  font: 1.2em sans-serif;
}
.box {
  writing-mode: vertical-rl;
}
.box > div {
  writing-mode: horizontal-tb;
  padding: 10px;
  border: 1px solid rebeccapurple;
}
.float {
  width: 100px;
  height: 150px;
  background-color: rebeccapurple;
  float: left;
}

替换元素

替换元素(例如图像)不会根据 writing-mode 属性改变其方向。但是,包含文本的替换元素(例如表单控件)应与正在使用的书写模式匹配。

html
<div class="box">
  <p>
    One November night in the year 1782, so the story runs, two brothers sat
    over their winter fire in the little French town of Annonay, watching the
    grey smoke-wreaths from the hearth curl up the wide chimney.
  </p>

  <img
    alt="a colorful hot air balloon against a clear sky"
    src="https://mdn.github.io/shared-assets/images/examples/balloon.jpg" />

  <p>
    Their names were Stephen and Joseph Montgolfier, they were papermakers by
    trade, and were noted as possessing thoughtful minds and a deep interest in
    all scientific knowledge and new discovery.
  </p>
</div>
css
body {
  font: 1.2em sans-serif;
}
.box {
  writing-mode: vertical-rl;
}

逻辑属性和值

一旦你在 horizontal-tb 以外的书写模式下工作,许多映射到屏幕物理尺寸的属性和值就会显得很奇怪。例如,如果你给一个框设置 100px 的宽度,在 horizontal-tb 中,它将控制行内方向的尺寸。在 vertical-lr 中,它控制块方向的尺寸,因为它不随文本旋转。

html
<div class="box">
  <div class="box1">Box 1</div>
  <div class="box2">Box 2</div>
</div>
css
body {
  font: 1.2em sans-serif;
}
.box1 {
  writing-mode: horizontal-tb;
  border: 5px solid rebeccapurple;
  width: 100px;
  margin: 10px;
}
.box2 {
  writing-mode: vertical-lr;
  border: 5px solid rebeccapurple;
  width: 100px;
  margin: 10px;
}

因此,我们有了新的属性 block-sizeinline-size。如果我们给块设置 100px 的 inline-size,无论我们处于水平还是垂直书写模式,inline-size 始终表示行内方向的尺寸。

html
<div class="box">
  <div class="box1">Box 1</div>
  <div class="box2">Box 2</div>
</div>
css
body {
  font: 1.2em sans-serif;
}
.box1 {
  writing-mode: horizontal-tb;
  border: 5px solid rebeccapurple;
  inline-size: 100px;
  margin: 10px;
}
.box2 {
  writing-mode: vertical-lr;
  border: 5px solid rebeccapurple;
  inline-size: 100px;
  margin: 10px;
}

CSS 逻辑属性和值模块包括控制边距、内边距和边框的属性的逻辑版本,以及我们通常使用物理方向指定的其他映射。

总结

在大多数情况下,当你更改文档或文档部分的写入模式时,流式布局会按你预期的方式工作。这可用于正确排版垂直语言或出于创意原因。CSS 通过引入逻辑属性和值使其变得更容易,这样在垂直写入模式下工作时,大小可以基于元素的行内和块大小。这对于创建可以在不同写入模式下工作的组件将非常有用。

另见