編寫模式和 CSS 佈局
已發表: 2022-03-10這不是一篇關於此屬性的實際或創造性應用的文章。 相反,我想說明為什麼理解書寫模式如此重要——即使對於我們這些很少需要更改頁面或組件的書寫模式的人來說也是如此。 對多種書寫模式的支持是我們設計 Flexbox 和 Grid Layout 的新佈局方法的關鍵。 理解這一點可以更好地理解這些佈局方法是如何工作的。
什麼是寫作模式?
文檔或組件的書寫方式是指文本流動的方向。 在 CSS 中,要使用書寫模式,我們使用writing-mode
屬性。 此屬性可以採用以下值:
-
horizontal-tb
-
vertical-rl
-
vertical-lr
-
sideways-rl
-
sideways-lr
如果你正在閱讀 Smashing Magazine 上的這篇英文文章,那麼這篇文檔的寫作模式是horizontal-tb
,或者Horizontal Top To Bottom 。 在英語中,句子是水平書寫的——每行的第一個字母從左邊開始。
諸如阿拉伯語之類的語言也具有horizontal-tb
書寫模式。 它是水平書寫的,從上到下,但是阿拉伯文字是從右到左書寫的,因此阿拉伯語的句子從右邊開始。
中文、日文和韓文是豎寫的,第一句話的第一個字符在右上角。 以下句子被添加到左側。 因此,使用的寫入模式是vertical-rl
。 從右到左運行的垂直書寫模式。
蒙古語也是豎寫的,但從左到右。 因此,如果你想排版蒙古文字,你會使用寫作模式vertical-lr
。
writing-mode
的其他兩個值更多地是為了創造性目的而設計的,而不是為了排版垂直腳本。 使用sideways-lr
和sideways-rl
將文本橫向翻轉——即使是通常垂直和直立書寫的字符。 不幸的是,這些值目前僅在 Firefox 中受支持。 以下 CodePen 顯示了writing-mode
的所有不同值,如果您想查看sideways-*
的實際操作,則需要使用 Firefox。
在創建使用使用該書寫模式編寫的語言的文檔時,可以使用書寫模式。 它們也可以創造性地使用,例如,在某些內容的側面垂直設置標題。 然而,在本文中,我想看看支持垂直語言和垂直文本的可能性對 CSS 佈局以及整個 CSS 的影響。
在我這樣做之前——如果你對垂直文本的書寫模式感興趣——這裡有一些有用的資源:
- W3C 國際化站點有大量有用的信息。 閱讀有關 RTL 腳本和垂直文本的信息。
- Jen Simmons 寫了一篇關於 CSS Writing Modes 的優秀文章,其中還包括了幾個使用這些模式的示例。
- 關於世界和我們的書寫系統的思考——陳慧靜
- 重新審視垂直排版與寫作模式 - 陳慧靜
- MDN 上的 writing-mode 屬性
塊和內聯維度
當我們改變一個文檔的書寫模式時,我們所做的就是切換塊流的方向。 因此,理解塊和內聯的含義很快對我們非常有用。
我們了解 CSS 的第一件事是有些元素是塊元素,例如段落。 這些元素在塊方向上一個接一個地顯示。 內聯元素,例如句子中的一個單詞,在內聯方向上一個接一個地顯示。 在水平書寫模式下工作,我們習慣了塊尺寸從上到下垂直運行,而內聯尺寸從左到右水平運行的事實。
然而,由於塊和內聯元素與我們文檔的書寫模式有關,因此只有在我們處於水平書寫模式時,內聯尺寸才是水平的。 它與寬度無關,而是與內聯大小有關。 塊尺寸僅在水平書寫模式下是垂直的。 因此它與高度無關,而是與塊大小有關。
邏輯,流相關屬性
這些術語,內聯大小和塊大小也被用作新 CSS 屬性的名稱,旨在反映我們新的書寫模式感知世界。 如果在水平書寫模式下您使用屬性inline-size
而不是width
,它將以與 width 完全相同的方式起作用 - 直到您切換組件的書寫模式。 如果您使用的width
始終是物理尺寸,則它始終是組件的水平尺寸。 如果您使用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
- 內聯結束
Flexbox 行和列
如果您使用 Flexbox 並將display: flex
添加到容器中,您的項目將顯示為一行,因為flex-direction
屬性的初始值為row
。 一行將遵循正在使用的書寫模式的內聯尺寸。 因此,如果您的寫作模式是horizontal-tb
那麼一行會水平運行。 如果當前腳本的文本方向是從左到右,那麼項目將從左開始排列,如果是從右到左,它們將從右側開始排列。
但是,使用垂直書寫模式,例如vertical-rl
和flex-direction: row
將導致項目垂直佈局,因為內聯方向是垂直的。 在下一個 CodePen 中,所有示例都有flex-direction: row
,只有書寫模式或方向發生了變化。
添加flex-direction: column
,以及在您的書寫模式的塊維度中的項目佈局。 在水平書寫模式中,塊尺寸是從上到下的,因此一列是垂直的。 使用vertical-rl
的書寫模式,一列是水平的。 與前面的示例一樣,以下 flex 佈局之間的唯一區別是使用的書寫模式。
網格自動放置
在網格中使用自動放置時,您會看到與 flex 佈局中類似的行為。 網格項目根據文檔的書寫模式自動放置。 默認情況下將項目放置在行中,這將是內聯方向 - 在水平書寫模式下是水平方向,在垂直方向是垂直方向。
嘗試將項目流更改為column
,如下例所示。 這些項目現在將在塊維度中流動——在水平書寫模式下垂直流動,在垂直書寫模式下水平流動。
網格線放置
基於行的放置也尊重書寫模式。 我們網格的行從 1 開始,行和列都是如此。 如果我們將一個項目從第 1 列定位到第 3 列,並且處於從左到右方向的水平書寫模式,則該項目將從最左邊的列線水平延伸穿過兩個網格軌道。 因此跨越兩列。
將書寫模式更改為vertical-rl
,第 1 列將位於網格的頂部,該項目垂直跨越兩個軌道。 仍然跨越兩列,但列現在水平運行。
網格和 Flexbox 中的對齊
許多人首先會接觸到 Flexbox 處理書寫模式的方式之一,就是在 flex 佈局中對齊項目時。 如果我們採用上面的flex-direction: row
示例,並使用justify-content
屬性將所有項目對齊以flex-end
項目移動到其行的末尾。 這意味著在從左到右的水平書寫模式中,所有項目都向右移動,因為該行的末尾在右側。 如果方向是從右到左,那麼它們都向左移動。
在垂直書寫模式下,他們會移動到底部,假設有空間讓他們這樣做。 我在這個例子中的組件上設置了一個inline-size
以確保我們的彈性容器中有空閒空間來查看對齊的效果。
對齊在網格佈局中更容易理解,因為我們總是有兩個軸可以玩。 網格是二維的,這兩個維度是塊和內聯。 因此,如果您想知道是使用以align-
justify-
的屬性,您可以記住一條規則。 在網格佈局中align-
-properties:- align-content
, align-items
, align-self
用於塊軸對齊。 在表示垂直的水平書寫模式中,以及在水平的垂直書寫模式中。
再一次,我們不使用左右或上下,因為我們希望我們的網格佈局以完全相同的方式工作,無論是什麼書寫模式。 所以我們使用start
和end
對齊。 如果我們對齊以start
塊維度開始,則在horizontal-tb
時將是top
,但在vertical-rl
時將是right
的。 看看下面的例子,兩個網格中的對齊值是相同的,唯一的區別是使用的書寫模式。
屬性justify-content
、 justify-items
、 justify-self
始終用於網格佈局中的內聯對齊。 這在水平書寫模式下是水平的,在垂直書寫模式下是垂直的。
Flexbox 對齊有點複雜,因為主軸可以從行切換到列。 因此,在 Flexbox 中,我們需要將對齊方式視為主軸與交叉軸。 align-
屬性用於交叉軸。 在主軸上,你所擁有的只是justify-content
,因為我們在 Flexbox 中將項目作為一個組來處理。 在交叉軸上,如果您有多個 flex 線和flex 容器中的空間來分隔它們,您可以使用align-content
。 您還可以使用align-items
和align-self
來移動交叉軸上的彈性項目,使其與彼此及其彈性線相關。
有關 CSS 佈局對齊的更多信息,請參閱我之前的 Smashing Magazine 文章:
- 如何在 CSS 中對齊事物
- 關於 Flexbox 對齊你需要知道的一切
編寫模式意識和舊 CSS
並非所有的 CSS 都完全趕上了這種與流程相關、與編寫模式無關的工作方式。 當你在塊和內聯、開始和結束方面考慮得更多時,它還沒有開始變得不尋常的地方。 例如,在多列佈局中,我們指定column-width
,這實際上意味著列內聯大小,因為在垂直書寫模式下工作時它不會映射到物理寬度。
如您所見,書寫模式是我們在 CSS 中所做的大部分工作的基礎,即使我們從不使用除horizontal-tb
之外的書寫模式。
我發現以這種與書寫模式無關的方式思考 CSS 佈局非常有幫助。 雖然將我們所有的屬性和值轉換為邏輯屬性和值可能還為時過早,但在處理新的佈局方法時,我們已經處於一個與流相關的世界中。 讓您的心智模型成為塊和內聯、開始和結束之一,而不是綁定到屏幕的四個角,這可以澄清我們在使用 FlexBox 和網格時遇到的許多事情。