编写模式和 CSS 布局

已发表: 2022-03-10
快速总结 ↬如果您想使用垂直脚本或出于创造性原因更改写作模式,了解 CSS 写作模式很有用。 但是,它们也支持我们的新布局方法,并且这些想法越来越多地应用于所有 CSS。 在本文中,了解为什么 Rachel Andrew 认为理解写作模式如此重要。

这不是一篇关于此属性的实际或创造性应用的文章。 相反,我想说明为什么理解书写模式如此重要——即使对于我们这些很少需要更改页面或组件的书写模式的人来说也是如此。 对多种书写模式的支持是我们设计 Flexbox 和 Grid Layout 的新布局方法的关键。 理解这一点可以更好地理解这些布局方法是如何工作的。

什么是写作模式?

文档或组件的书写方式是指文本流动的方向。 在 CSS 中,要使用书写模式,我们使用writing-mode属性。 此属性可以采用以下值:

  • horizontal-tb
  • vertical-rl
  • vertical-lr
  • sideways-rl
  • sideways-lr

如果你正在阅读 Smashing Magazine 上的这篇英文文章,那么这篇文档的写作模式是horizontal-tb ,或者Horizo​​ntal Top To Bottom 。 在英语中,句子是水平书写的——每行的第一个字母从左边开始。

诸如阿拉伯语之类的语言也具有horizontal-tb书写模式。 它是水平书写的,从上到下,但是阿拉伯文字是从右到左书写的,因此阿拉伯语的句子从右边开始。

中文、日文和韩文是竖写的,第一句话的第一个字符在右上角。 以下句子被添加到左侧。 因此,使用的写入模式是vertical-rl 。 从右到左运行的垂直书写模式。

蒙古语也是竖写的,但从左到右。 因此,如果你想排版蒙古文字,你会使用写作模式vertical-lr

跳跃后更多! 继续往下看↓

writing-mode的其他两个值更多地是为了创造性目的而设计的,而不是为了排版垂直脚本。 使用sideways-lrsideways-rl将文本横向翻转——即使是通常垂直和直立书写的字符。 不幸的是,这些值目前仅在 Firefox 中受支持。 以下 CodePen 显示了writing-mode的所有不同值,如果您想查看sideways-*的实际操作,则需要使用 Firefox。

请参阅 Rachel Andrew 的 Pen [书写模式演示](https://codepen.io/rachelandrew/pen/dxVVRj)。

请参阅 Rachel Andrew 的钢笔写作模式演示。

在创建使用使用该书写模式编写的语言的文档时,可以使用书写模式。 它们也可以创造性地使用,例如,在某些内容的侧面垂直设置标题。 然而,在本文中,我想看看支持垂直语言和垂直文本的可能性对 CSS 布局以及整个 CSS 的影响。

在我这样做之前——如果你对垂直文本的书写模式感兴趣——这里有一些有用的资源:

  • W3C 国际化站点有大量有用的信息。 阅读有关 RTL 脚本和垂直文本的信息。
  • Jen Simmons 写了一篇关于 CSS Writing Modes 的优秀文章,其中还包括了几个使用这些模式的示例。
  • 关于世界和我们的书写系统的思考——陈慧静
  • 重新审视垂直排版与写作模式 - 陈慧静
  • MDN 上的 writing-mode 属性

块和内联维度

当我们改变一个文档的书写模式时,我们所做的就是切换块流的方向。 因此,理解块和内联的含义很快对我们非常有用。

我们了解 CSS 的第一件事是有些元素是块元素,例如段落。 这些元素在块方向上一个接一个地显示。 内联元素,例如句子中的一个单词,在内联方向上一个接一个地显示。 在水平书写模式下工作,我们习惯了块尺寸从上到下垂直运行,而内联尺寸从左到右水平运行的事实。

然而,由于块和内联元素与我们文档的书写模式有关,因此只有在我们处于水平书写模式时,内联尺寸才是水平的。 它与宽度无关,而是与内联大小有关。 块尺寸仅在水平书写模式下是垂直的。 因此它与高度无关,而是与块大小有关。

逻辑,流相关属性

这些术语,内联大小和块大小也被用作新 CSS 属性的名称,旨在反映我们新的书写模式感知世界。 如果在水平书写模式下您使用属性inline-size而不是width ,它将以与 width 完全相同的方式起作用 - 直到您切换组件的书写模式。 如果您使用的width始终是物理尺寸,则它始终是组件的水平尺寸。 如果您使用inline-size ,那将是内联维度中的大小,如下例所示。

请参阅 Rachel Andrew 的 Pen [width vs. inline-size](https://codepen.io/rachelandrew/pen/RXLLyd)。

请参阅 Rachel Andrew 的 Pen width vs. inline-size。

height也是如此。 height属性将始终是垂直大小。 它与物品的高度有关。 然而, block-size属性给出了块维度中的大小,如果我们处于水平书写模式,则为垂直,而在垂直模式中为水平。

正如我在“理解逻辑属性和值”一文中所描述的,所有物理属性都有映射,这些物理属性与屏幕的尺寸相关。 一旦你开始考虑它,就会发现很多 CSS 都是与屏幕的物理布局相关的。 我们使用顶部、右侧、底部和左侧设置定位、边距、填充和边框。 我们左右浮动。 有时将事物与物理维度联系起来是我们想要的,但是我们越来越多地考虑我们的布局而不参考物理位置。 逻辑属性和值规范推出了这种跨 CSS 的与书写模式无关的工作方式。

编写模式、网格和 Flexbox

当我们的新布局方法出现在现场时,它们带来了一种不可知论的方式,可以将组件的书写模式视为 flex 或 grid 布局。 人们第一次被要求考虑开始和结束,而不是左右、顶部和底部。

当我第一次开始介绍 CSS Grid 的主题时,我早期的介绍是对规范中所有属性的概述。 我提到了grid-area属性可以用来设置所有四行来放置一个网格项。 然而,这些行的顺序并不是我们用来设置所有四个边距的熟悉的上、右、下和左。 相反,我们需要使用上、左、下、右——与该顺序相反! 在我了解网格和书写模式之间的联系之前,这似乎是一个非常奇怪的决定。 我开始意识到我们正在做的是设置两条起始线,然后设置两条结束线。 如果我们处于水平书写模式,使用 top、right、bottom 和 left 可以正常工作,但是将网格翻转到一边,这没有任何意义。 如果我们使用grid-area: 1 / 2 / 3 / 5; 如在笔下面的行设置如下:

  • grid-row-start: 1; - 块开始
  • grid-column-start: 2 - 内联开始
  • grid-row-end: 3 - 块结束
  • grid-column-end: 5 - 内联结束

请参阅 Rachel Andrew 的 Pen [grid-area](https://codepen.io/rachelandrew/pen/zgEEQW)。

请参阅 Rachel Andrew 的 Pen 网格区域。

Flexbox 行和列

如果您使用 Flexbox 并将display: flex添加到容器中,您的项目将显示为一行,因为flex-direction属性的初始值为row 。 一行将遵循正在使用的书写模式的内联尺寸。 因此,如果您的写作模式是horizontal-tb那么一行会水平运行。 如果当前脚本的文本方向是从左到右,那么项目将从左开始排列,如果是从右到左,它们将从右侧开始排列。

但是,使用垂直书写模式,例如vertical-rlflex-direction: row将导致项目垂直布局,因为内联方向是垂直的。 在下一个 CodePen 中,所有示例都有flex-direction: row ,只有书写模式或方向发生了变化。

请参阅 Rachel Andrew 的 Pen [flex-direction: row](https://codepen.io/rachelandrew/pen/XvezrE)。

请参阅 Rachel Andrew 的 Pen flex-direction:行。

添加flex-direction: column ,以及在您的书写模式的块维度中的项目布局。 在水平书写模式中,块尺寸是从上到下的,因此一列是垂直的。 使用vertical-rl的书写模式,一列是水平的。 与前面的示例一样,以下 flex 布局之间的唯一区别是使用的书写模式。

请参阅 Rachel Andrew 的 Pen [flex-direction: column](https://codepen.io/rachelandrew/pen/RXLjbX)。

请参阅 Pen flex-direction:Rachel Andrew 的专栏。

网格自动放置

在网格中使用自动放置时,您会看到与 flex 布局中类似的行为。 网格项目根据文档的书写模式自动放置。 默认情况下将项目放置在行中,这将是内联方向 - 在水平书写模式下是水平方向,在垂直方向是垂直方向。

请参阅 Rachel Andrew 的 Pen [Grid auto-placement row](https://codepen.io/rachelandrew/pen/eqGeYV)。

请参阅 Rachel Andrew 的 Pen Grid 自动放置行。

尝试将项目流更改为column ,如下例所示。 这些项目现在将在块维度中流动——在水平书写模式下垂直流动,在垂直书写模式下水平流动。

请参阅 Rachel Andrew 的 Pen [Grid auto-placement column](https://codepen.io/rachelandrew/pen/xvXPby)。

请参阅 Rachel Andrew 的 Pen Grid 自动放置专栏。

网格线放置

基于行的放置也尊重书写模式。 我们网格的行从 1 开始,行和列都是如此。 如果我们将一个项目从第 1 列定位到第 3 列,并且处于从左到右方向的水平书写模式,则该项目将从最左边的列线水平延伸穿过两个网格轨道。 因此跨越两列。

将书写模式更改为vertical-rl ,第 1 列将位于网格的顶部,该项目垂直跨越两个轨道。 仍然跨越两列,但列现在水平运行。

请参阅 Rachel Andrew 的 Pen [边距:相邻兄弟姐妹](https://codepen.io/rachelandrew/pen/mNBqEy)。

请参阅笔边距:Rachel Andrew 的相邻兄弟姐妹。

网格和 Flexbox 中的对齐

许多人首先会接触到 Flexbox 处理书写模式的方式之一,就是在 flex 布局中对齐项目时。 如果我们采用上面的flex-direction: row示例,并使用justify-content属性将所有项目对齐以flex-end项目移动到其行的末尾。 这意味着在从左到右的水平书写模式中,所有项目都向右移动,因为该行的末尾在右侧。 如果方向是从右到左,那么它们都向左移动。

在垂直书写模式下,他们会移动到底部,假设有空间让他们这样做。 我在这个例子中的组件上设置了一个inline-size以确保我们的弹性容器中有空闲空间来查看对齐的效果。

对齐在网格布局中更容易理解,因为我们总是有两个轴可以玩。 网格是二维的,这两个维度是块和内联。 因此,如果您想知道是使用以align- justify-的属性,您可以记住一条规则。 在网格布局中align- -properties:- align-content , align-items , align-self用于块轴对齐。 在表示垂直的水平书写模式中,以及在水平的垂直书写模式中。

再一次,我们不使用左右或上下,因为我们希望我们的网格布局以完全相同的方式工作,无论是什么书写模式。 所以我们使用startend对齐。 如果我们对齐以start块维度开始,则在horizontal-tb时将是top ,但在vertical-rl时将是right的。 看看下面的例子,两个网格中的对齐值是相同的,唯一的区别是使用的书写模式。

请参阅 Rachel Andrew 的 Pen [边距:相邻兄弟姐妹](https://codepen.io/rachelandrew/pen/jgGaML)。

请参阅笔边距:Rachel Andrew 的相邻兄弟姐妹。

属性justify-contentjustify-itemsjustify-self始终用于网格布局中的内联对齐。 这在水平书写模式下是水平的,在垂直书写模式下是垂直的。

请参阅 Rachel Andrew 的 Pen [边距:相邻兄弟姐妹](https://codepen.io/rachelandrew/pen/RXLjpP)。

请参阅笔边距:Rachel Andrew 的相邻兄弟姐妹。

Flexbox 对齐有点复杂,因为主轴可以从行切换到列。 因此,在 Flexbox 中,我们需要将对齐方式视为主轴与交叉轴。 align-属性用于交叉轴。 在主轴上,你所拥有的只是justify-content ,因为我们在 Flexbox 中将项目作为一个组来处理。 在交叉轴上,如果您有多个 flex 线flex 容器中的空间来分隔它们,您可以使用align-content 。 您还可以使用align-itemsalign-self来移动交叉轴上的弹性项目,使其与彼此及其弹性线相关。

请参阅 Rachel Andrew 的 Pen [Flexbox 对齐](https://codepen.io/rachelandrew/pen/YmrExP)。

请参阅 Rachel Andrew 的 Pen Flexbox 对齐。

有关 CSS 布局对齐的更多信息,请参阅我之前的 Smashing Magazine 文章:

  • 如何在 CSS 中对齐事物
  • 关于 Flexbox 对齐你需要知道的一切

编写模式意识和旧 CSS

并非所有的 CSS 都完全赶上了这种与流程相关、与编写模式无关的工作方式。 当你在块和内联、开始和结束方面考虑得更多时,它还没有开始变得不寻常的地方。 例如,在多列布局中,我们指定column-width ,这实际上意味着列内联大小,因为在垂直书写模式下工作时它不会映射到物理宽度。

请参阅 Rachel Andrew 的 Pen [Multicol and writing-mode](https://codepen.io/rachelandrew/pen/pMWdLL)。

请参阅 Rachel Andrew 的 Pen Multicol 和写作模式。

如您所见,书写模式是我们在 CSS 中所做的大部分工作的基础,即使我们从不使用除horizontal-tb之外的书写模式。

我发现以这种与书写模式无关的方式思考 CSS 布局非常有帮助。 虽然将我们所有的属性和值转换为逻辑属性和值可能还为时过早,但在处理新的布局方法时,我们已经处于一个与流相关的世界中。 让您的心智模型成为块和内联、开始和结束之一,而不是绑定到屏幕的四个角,这可以澄清我们在使用 FlexBox 和网格时遇到的许多事情。