寫在前面
writing-mode 是一個強大的 CSS 屬性,能讓文字豎排(實際上能讓任何東西豎排,因為能改變預設佈局流),例如:
泉眼無聲惜細流
樹陰照水愛晴柔
小荷才露尖尖角
早有蜻蜓立上頭
Demo 見:http://ayqy.net/temp/writing-mode.html
起關鍵作用的 CSS 規則為:
/* 豎直 - 從右向左 */
-webkit-writing-mode: vertical-rl;
writing-mode: vertical-rl;
把 writing-mode 從預設的 horizontal top-to-bottom mode 改為 vertical right-to-left mode。看起來好像除了特殊文字排版場景之外,再沒什麼用了,但實際上要強大得多,如果給 html 元素應用該規則,整頁都會切換成從右向左豎排模式,包括滾動方向、下拉列表方向等等都會受到影響
強大歸強大,但為什麼要了解這個東西?
-
世界上的語言多種多樣,除了英文、中文這些橫的,還有阿拉伯文、希伯來文等等豎的,而一些場景(比如多語言混排)下需要雙向排列(
bidi) -
writing-mode能改變「CSS 世界的縱橫規則,可以說是最逆天的 CSS 屬性」,「理論上講,有了writing-mode,我們能夠做的事情比以前多了 50%」。這是一個具有無限創造力的屬性,不僅能改變現有的東西,未來的東西也將受到影響,例如margin-start/end -
有助於理解 Flexbox 和 CSS Grid
一。屬性值及兼容性
從目前(2017-1-21)的 草案 來看,屬性可選值如下:
/* 預設 horizontal-tb */
writing-mode: horizontal-tb | vertical-rl | vertical-lr | sideways-rl | sideways-lr
預設是 horizontal-tb 橫向從上到下排列,也就是 CSS 裡最基本的規則,元素從左向右,從上到下依次排列。vertical-rl/lr 分別表示縱向從右向左排列、縱向從左向右排列。剩餘 2 個,不一定有沒有:
This value is at-risk and may be dropped during CR.
sideways-rl:縱向從右向左排列,但印刷方式(typographic mode)是橫向的
sideways-lr:縱向從左向右排列,但印刷方式是橫向的
writing-mode 屬性還處於草案階段,但因為 IE 老早就提出了這個東西,後來其它瀏覽器跟進,目前兼容性很不錯:
sideways-rl | sideways-lr 目前沒有支持
horizontal-tb | vertical-rl | vertical-lr 廣泛支持,Android[3+],iOS[5.1+],都需要 -webkit-
IE[6-10] 只支持老版本值:lr-tb | rl-tb | tb-rl | tb-lr,其中與上面 3 個廣泛支持的對應的是 lr-tb | tb-rl | tb-lr
移動端可以帶著前綴放心使用,關於兼容性的詳細信息,請查看 Can I use writing-mode ?
P.S.IE 老版本值見 CSS3 Text Module W3C Candidate Recommendation 14 May 2003
二。內聯方向、塊方向和字符方向
內聯方向:預設 writing-mode 下,塊從頁面頂部開始縱向排列
內聯方向是指文本流每一行的排列方向,預設從左向右排列,想像打字機效果,字符一個一個出來,就是內聯方向
字符方向是說字符指向哪邊,輸入一個大 A(這個指向太明顯了,像箭頭一樣),字符指向頁面頂部,但不同語言會指向不同方向
[caption id="attachment_1295" align="alignnone" width="625"]
three concepts[/caption]
圖中,塊方向從上到下,內聯方向從左向右,字符方向是指向頁面頂部
三。4 大文字系統
CSS Writing Mode 從設計上滿足了 4 大主要文字系統:拉丁文,阿拉伯文,中文和蒙古文
1. 拉丁文系統
世界上最大的文字系統,70% 人都用這個。文字從左向右排列,塊方向是向上到下(見上圖)
拉丁文系統很龐大,包括了所有用拉丁字母的其它語言,例如英文、西班牙文、德文、法文等等。此外,很多不用拉丁字母的語言也屬於拉丁文系統,包括用希臘字母、西里爾(Cyrillic)字母的,例如俄文、烏克蘭文、保加利亞文、塞爾維亞文等等,以及婆羅米系文字(Brahmic scripts),例如梵文、泰文、藏文等等
不需要通過 CSS 來觸發這種模式,預設就是這樣。但最好聲明語言和排列方向,例如:
<html lang='en-gb' dir='ltr'>
好讓瀏覽器知道內容是英國版英文,從左向右排列
2. 阿拉伯文系統
阿拉伯文、希伯來文是少數內聯方向是從右向左的,稱為 RTL
注意內聯方向還是橫向的,塊方向從上到下,字符方向向上:
[caption id="attachment_1296" align="alignnone" width="625"]
arabic system[/caption]
不僅文本流從右向左,佈局相關的所有東西都是從右向左的,從右上角開始,眼睛從右向左瀏覽,所以一般 RTL 站點的佈局與 LTR 類似,只是水平翻轉一下
RTL 下的 CSS 佈局
一般為了支持 RTL,需要做很多準備工作,比如先找到所有的 margin-left/right, padding-left/right, float: left/right,標記出來,再弄一份樣式表把左右反過來。這個工作很枯燥且容易出錯,CSS 需要提供一種只寫一次佈局代碼,能夠通過簡單指令方便切換語言方向的方式
新的 CSS 佈局系統就在做這個事情,Flexbox,Grid 和 Alignment 用 start 和 end 來代替 left 和 right。這樣就能根據文字系統定義佈局,很容易切換方向。例如 justify-content: flex-start; justify-items: end; margin-inline-start: 1rem 都不需要再動。這種方式更好,雖然用 start 和 end 替換 left 和 right 比較迷惑,但有益於多語言項目,也有益於 web 大環境
所以花一點點時間弄清楚內聯方向、塊方向,把 start 和 end 用起來,很快就會習慣的
如何聲明方向
應該在 HTML 裡聲明方向,而不是 CSS 裡,這樣即便 CSS 沒加載完,瀏覽器也能正確顯示內容。主要通過 html 元素完成,同時還應該聲明語言,例如:
<html lang='ar' dir='rtl'>
表示頁面內容是阿拉伯文,用 RTL 佈局
無論是拉丁文系統還是阿拉伯文系統,writing-mode 屬性應該用一樣的:
writing-mode: horizontal-tb;
因為內聯文本流都是橫向的,塊方向也都是從上到下,用 CSS 表示出來就是 horizontal-tb,也是預設 writing-mode,所以不需要手動聲明,除非想覆蓋其它的或者想要更高的級聯優先級。所以可以想像以前做的每個頁面都有一行:
html {
writing-mode: horizontal-tb;
}
3. 漢字系統
漢字系統包括 CJK 語言,中文、日文、韓文等等,有兩種佈局方式,有時會一起出現
很多 CJK 文字佈局和拉丁文語言一樣,塊方向從上到下,內聯方向從左向右。佈局需要的 CSS 與上面相同:
section {
writing-mode: horizontal-tb;
}
或者什麼都不寫,預設就是這樣
另外,漢字系統也可以縱向排列,內聯方向是豎向,塊方向從右向左,如圖:
[caption id="attachment_1297" align="alignnone" width="625"]
han system[/caption]
注意橫向文本流從左向右,而縱向文本流從右向左
整頁的預設設置取決於場景,但每個元素,每行標題,每節,每篇文章都可以設置成與預設的相反。例如,預設設置為 horizontal-tb,再對豎直元素設置:
div.articletext {
writing-mode: vertical-rl;
}
或者可以把頁面預設設置為縱向排列,然後給某些元素設置 horizontal-tb,例如:
html {
writing-mode: vertical-rl;
}
h2, .photocaptions, section {
writing-mode: horizontal-tb;
}
如果頁面有側向滾動的話,writing-mode 會讓頁面佈局從左上角開始,向右滾動(horizontal-tb),或者頁面佈局從右上角開始,向左滾動顯示溢出的部分
有一個切換 writing-mode 的例子:文字的故事,比較有意思的是切換是通過選擇器實現的(日常猥瑣扒代碼):
.c-switcher:not(:checked)~main figure {
-ms-flex-wrap: wrap;
flex-wrap: wrap;
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
text-align: center
}
.c-switcher:checked~main figure {
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
-ms-flex-wrap: nowrap;
flex-wrap: nowrap
}
4. 蒙古文系統
蒙古文也是一種縱向文字語言,文本在頁面上縱向排列,像漢字系統一樣。有 2 點主要差異
首先塊方向不同,蒙古文塊級元素從左向右排列。塊方向屏幕左邊開始,向右邊排列。內聯方向從上到下,和 RTL 文本很像,想像把這個頁面逆時針旋轉 90 度的樣子。
另一個差異是,字符方向上下反過來,蒙古文字符的頂部不是指向左邊(指向塊方向的起始邊),而是指向右邊,如圖:
[caption id="attachment_1298" align="alignnone" width="625"]
mongolian system[/caption]
writing-mode: vertical-lr 就是為了處理這種情況,是為蒙古文量身定做的,所以 writing-mode: vertical-lr 實際效果可能與想像的不同:
[caption id="attachment_1299" align="alignnone" width="625"]
vertical actual[/caption]
因為 vertical-rl 確實是把頁面順時針旋轉 90 度的結果,而 vertical-lr 逆時針旋轉 90 度後,還要把文字方向反轉。屬性值的含義是根據文字系統表現來定義的,而不是字面意思
還有例外情況,在 writing-mode: vertical-rl/lr 下,拉丁文都順時針旋轉,writing-mode 沒辦法讓它逆時針旋轉
如果要排版蒙古文內容的話,CSS 應用方式與漢字系統相同,在 html 元素上設置整頁的,或者聲明指定元素的:
section {
writing-mode: vertical-lr;
}
如果把 writing-mode 用作非橫向語言的平面設計效果的話,writing-mode: vertical-lr 可能沒什麼用,如果文本換行了,排列方式會很奇怪。所以可能經常用 vertical-rl,而不怎麼用 vertical-lr
四。Writing Mode 與平面設計
那要怎麼才能用 writing-mode 把英文標題行側過來?可以用 transform: rotate() 搞定(因為 vertical-rl/lr 會反轉字符方向,所以需要 vertical-rl + rotate 模擬)
/* 順時針旋轉 90 度效果 */
h1 {
writing-mode: vertical-rl;
}
/* 逆時針旋轉 90 度效果 */
h1 {
writing-mode: vertical-rl;
transform: rotate(180deg);
text-align: right;
}
這裡不用 writing-mode: vertical-lr,因為前面提到的換行時文本排列會很奇怪(親測沒有發現奇怪的地方,也不知道指的是什麼),所以用 vertical-rl + rotate 實現,text-align: right; 是為了讓文本貼住容器頂部,這裡是針對 vertical-rl 的,算是 hack
另外,可以配合 text-orientation: upright; 讓字符方向保持向上
這樣可以讓小節標題豎排在側邊,閱讀體驗「可能」會更好一些
五。Writing Mode 技巧
利用 Writing Mode 把橫向規則搬到縱向,例如 margin: auto 0; 實現豎直居中:
/* 容器 */
-webkit-writing-mode: vertical-rl;
writing-mode: vertical-rl;
/* 元素 */
height: 100px;
margin: auto 0;
或者更粗暴的:
/* 容器 */
-webkit-writing-mode: vertical-rl;
writing-mode: vertical-rl;
text-align: center;
/* 元素 */
display: inline-block;
text-align: left;
但是在有 transfrom 的時代,一些技巧也不很實用,例如:
-
縱向
text-indent實現按下按鈕時文字下沉 -
縱向 iconfont 實現展開/收起箭頭
text-indent 在多字情況下會換行,縱向字體只能順時��旋轉,做不到逆時針旋轉
如果沒有 transform 的話,writing-mode 在佈局效果上會大放光彩,例如 [IE6+] 環境,writing-mode 就像魔法一樣
但 writing-mode 確實增加了 50% 的可能性,是另一扇門
暫無評論,快來發表你的看法吧