原文連接:https://medium.com/@elad/new-...
原文做者:Elad Shechtercss
在過去,大多數程序猿在思考佈局時老是習慣於從「上下左右」的角度出發。這是由於在早期,互聯網主要用於上傳文檔,而不是爲了實現咱們如今熟知的複雜網站架構。html
這也是爲何沒有人思考多語言網站的需求。git
目前爲止,支持相似 RTL/LTR
這種多方向網站的最佳方式,依然是使用 SASS
和 SASS
變量。
(若是你但願瞭解更多內容,能夠閱讀個人另外一篇文章《The Best Way to RTL Websites with SASS!》)。github
這些新的邏輯屬性讓咱們可以在改動最少樣式的狀況下控制咱們的網站,而不用擔憂網站使用的是何種語言(不管是英語、阿拉伯語、日語仍是其餘語言)。web
如今讓咱們開始吧!瀏覽器
當咱們討論盒模型時,咱們已經對下面這張圖很熟悉了:sass
<font color=#999>盒模型物理屬性(舊方案)架構
它在之前和如今一直是正確的,但相似 margin-left
, padding-right
, border-top
等經典物理特性其實已經時日很少了。佈局
在你開始使用新的邏輯屬性以前,你須要中止從 left/right
或者 top/bottom
來思考問題,而是使用 inline-start/inline-end
和 block-start/block-end
來替代它們。學習
<font color=#999>邏輯屬性(新方案)
讓咱們用英文做爲例子,英文的閱讀方向是從左到右,這是屬性的內聯部分。當咱們想要把一系列元素排在同一行時,咱們一般會使用 display: inline
,照這個思路就很容易記住 inline axis
的含義了。
舉例來講,padding-inline-start 會在當前語句開始位置的旁邊設置一個內邊距:
在英語中: padding-inline-start
= padding-left
在阿拉伯語中:padding-inline-start
= padding-right
在日語中: padding-inline-start
= padding-top
讓咱們忘掉 top 和 bottom 相關屬性的含義(再也不表示「上下」),而是把 top 當作網站的開始,把 bottom 當作網站的結束。只要想像幾個 display:block
的元素首尾相連,就很容易記住這點了。
到這時你仍然會問本身,難道這不是一向的作法嗎?
這個問題解釋起來有點複雜。由於目前並無其餘解決方案,因此目前全部的網站,不論是使用的是什麼語言,都是這麼處理的。
要知道使用日文或者其餘東方語言的網站(按佈局方向)多是從右到左,而非從上到下的!爲了理解這種網站的表現,咱們能夠想象一下將瀏覽器向右旋轉90度,咱們會發現網站的滾動條再也不是垂直方向了,它變成了水平方向!
舉個例子(block cases):
在英語和阿拉伯語中: padding-block-start
= padding-top
在日語中: padding-block-start
= padding-right
<font color=#999>(日文網站)
(margin, padding and border)
在理解了 inline 和 block axis 以後,你就能夠根據須要來使用它們了。
用英文網站舉例來講:
margin margin-block-start
= margin-top
margin-block-end
= margin-bottom
margin-inline-start
= margin-left
margin-inline-end
= margin-left
padding padding-block-start
= padding-top
padding-block-end
= padding-bottom
padding-inline-start
= padding-left
padding-liline-end
= padding-right
border border-block-start
= border-top
border-block-end
= border-bottom
border-inline-start
= border-left
border-inline-end
= border-right
Width
和 Height
被 inline-size
和 block-size
所取代。
Width
和 Height
屬性一樣須要適應新的尺寸表達方法。一旦咱們理解了 inline/block 方法,就很是容易理解它們的尺寸要如何用新屬性來表示。在英文網站,寬度屬性用 inline-size
表示,高度屬性用 block-size
表示。
舉個栗子(inline/block size):
在英文與阿拉伯語中(LTR/RTL) width
= inline-size
height
= block-size
在一個閱讀順序是每行裏自上而下的語言中,好比日語,咱們會看到相反的表達方式:inline-size
= height
,block-size
= width
。
對於 min/max 屬性,只須要把 min/max 書寫在屬性前面:min-inline-size: 300px;
max-block-size: 100px;
。
<font color=#999>新舊盒模型屬性對比
top/right/bottom/left
這些舊的位置屬性已經發展出了一組新的屬性名,它們都帶有 inset
前綴,分別是: inset-block-start / inset-inline-end / inset-block-end / inset-inline-start
在英文網站中(LTR): top
= inset-block-start
bottom
= inset-block-end
left
= inset-inline-start
right
= inset-inline-end
/* OLD TECHIQUE */ .popup { position: fixed; top: 0; bottom: 0; left: 0; right: 0; } /* NEW TECHIQUE */ .popup { position: fixed; inset-block-start: 0; /*top - in English*/ inset-block-end: 0; /*bottom - in English*/ inset-inline-start: 0; /*left - in English*/ inset-inline-end: 0; /*right - in English*/ }
第一眼看到這些代碼,你可能會質疑爲何咱們須要如此複雜的命名?!其實這是有充分理由的。在新的屬性名中,這些屬性依然可使用相似 padding/margin/border
的書寫方式混合起來,而這種新的位置簡寫特性在之前是不存在的(以下所示)。
.popup{ position:fixed; inset:0 0 0 0; /*top, right, bottom, left - in English*/ }
Float 很是簡單,它只有2個值 left/right
,分別用 inline-start/inline-end
來代替。
在英文網站中(LTR): float: left
= float: inline-start
float: right
= float: inline-end
它比 floats 更簡單,只須要用 start/end
代替 left/right
便可。
在英文網站中(LTR): text-align: left
= text-align: start
text-align: right
= text-align: end
Resize:經常使用於 <textarea>
,它的值 horizontal/vertical
升級爲 inline/block
代替。
在英文網站中(LTR): resize: horizontal
= resize: inline
resize: vertical
= resize: block
background-position:目前爲止尚未任何瀏覽器中針對該屬性進行過修改,但若是你研究的足夠深刻,你就會在 Mozilla 的 MDN 中找到有關 background-position-inline & background-position-block
的資料。雖然這些文檔還不夠完善,但工做人員已經在進行相關的工做了。
其餘:正如其餘與方向有關的屬性同樣,咱們還能夠預測相似 transform-origin
這樣的屬性也會被更新。
這兩個特性自己已經使用了新的邏輯屬性方法進行構建,所以若是你以前已經使用了這兩個特性,那麼沒有必要用本文提到的新方法去替代它們。
雖然剛開始看起來很複雜,但其實是很是容易使用的。在寫樣式時,再也不須要考慮跨語言支持的問題。你只須要使用邏輯屬性替代舊的物理屬性,而後讓它們匹配你喜歡的語言便可。
當咱們學習了全部新邏輯屬性的更新後,咱們就能夠運用2個特性來分別定義塊軸對齊(block axis alignment)(網站文檔流方向)和內聯軸對齊(文字閱讀方向)。
在定義網站文檔流時,大多數時候是從上到下的。但正如上文提到的,特定語言有可能從右到左(日語),甚至從左到右(蒙語)。在這兩種狀況中,咱們就得使用水平滾動條來替代慣用的垂直滾動條。
注意:writing-mode
有3個主要的值:horizontal-tb / vertical-rl / vertical-lr
。
這3個值的名稱有一點使人困惑。這是由於他們既能夠表示塊軸方向,還能夠表示內聯軸的文字對齊(inline-axis)。這顯然讓人很不爽,由於文字對齊實際上是多餘的,這隻能讓人感到困惑。
爲了消除這個困惑,建議忽略屬性值內表示內聯軸的部分,只關注塊軸部分。
舉例來講:
writing-mode: horizontal-tb;
= Top to Bottom Flow,英文(默認)writing-mode: vertical-rl;
= Right to Left Flow,日語writing-mode: vertical-lr;
= Left to Right Flow,蒙語就我而言,我更傾向於讓屬性值只包括:tb/rl/lr (block-axis part),以此消除潛在的困惑。
日語中 writing-mode
是這麼定義的:
html { writing-mode: vertical-rl; }
只有在 writing-mode
屬性處於默認的水平模式時,方向屬性纔可以定義文字方向是 left-to-right 仍是 right-to-left。若是咱們將 writing-mode
改成垂直模式中的一種後,文字方向就會發生改變:
left-to-right 會變爲 top-to-bottom,right-to-left 會變爲 bottom-to-top。
以阿拉伯語爲例:
html { direction: rtl; }
使人驚奇的是,將一個自上而下的網站變爲一個帶有橫向滾動條的自右向左的網站是多麼的容易。
這裏是我寫的一個demo,在 Firefox 中瀏覽最佳(目前爲止 Firefox 支持更多的新屬性)
Live Example (試試選擇其餘語言選項):
margin / padding / border
)以及新的 width / height (inline-size, block-size)
屬性。text-align
的新屬性值。Floats / Positions / Resize
的值或屬性只被 Firefox 所支持。隨着這些新屬性的誕生,咱們也必須面對隨之而來的新問題。好比,當咱們想用簡寫的方式把全部 margin 屬性寫出來時,像這樣:
margin: 1px 2px 3px 4px;
你是沒法預測它會如何被瀏覽器解析的。
由於若是網站使用的是物理屬性,這些屬性值就會被解析爲:margin-top / margin-right / margin-bottom / margin-left
,但若是網站使用的是邏輯屬性,這些值就應該是:margin-block-start / margin-inline-end / margin-block-end / margin-inline-start
。
在英文網站中,物理屬性與邏輯屬性的表現是一致的。在使用其餘語言的網站中,當咱們使用相似 margin
的簡寫時,咱們但願它可以根據 direction
屬性或 writing-mode
屬性來工做。
但如何能讓簡寫自動根據direction
或 writing-mode
去解析呢?這一直是個懸而未決的問題。針對該問題,我曾給出一些建議:++suggestion that can solve the issue at github csswg-drafts++。若是你有更好的解決方案,歡迎你在連接中評論!
若是你如今要使用邏輯屬性,那你就必須把它們的屬性名完整地寫出來,而不能使用簡寫。
在這裏我給出一個可選的解決方案:
html{ flow-mode:physical; /*or*/ flow-mode:logical; } .box{ /*will be interpreted according to the HTML flow-mode value*/ margin:10px 5px 6px 3px; padding:5px 10px 2px 7px; }
爲了製做一個完善的 demo,我嘗試在媒體查詢裏使用 max-width
的新屬性 max-inline-size
,在 left-to-right 的條件下,max-inline-size
的效果會與 max-width
同樣,而在 right-to-left 的條件下,好比日語這樣的語言,新屬性的效果就會與 max-height
同樣。有點遺憾的是目前瀏覽器並不支持在媒體查詢(media query)中解析新屬性。
/*Not Working*/ @media (max-inline-size:1000px){ .main-content{ background:red; grid-template-columns:auto; } }
在深刻學習並理解了邏輯屬性的概念後,我一邊寫文章一邊想,還有一些被忽略的改動也應該被歸入將來的更新範圍中:
line-height
能夠改成 line-size
border-width
能夠改成 border-size
不過真實狀況彷佛不太同樣,至少 border-width
和我想的不同。它更新爲邏輯屬性後,屬性名中依然帶有 width
。
舉個例子:border-block-start-width
。