在 CSS 中,咱們常常會與各類方向方位打交道。css
譬如 margin
、padding
,它們就會有 margin-left
、margin-right
或者是 padding-left
、padding-right
。還有定位中的 left
、top
、right
、bottom
,它們表示了上下左右不一樣的方位。html
還有一種狀況是從x方位到x方位,譬如 writing-mode
、direction
,它表明了一種順序,表示塊流動方向,或者文字書寫的方向等。前端
本文將捋一捋 CSS 世界中的方位與順序,探尋其中一些有意思的點。git
writing-mode
& direction
& unicode-bidi
在 CSS 世界中,這 3 個屬性都與排版順序相關,互有關聯但做用各異。github
writing-mode
:定義了文本水平或垂直排布以及在塊級元素中文本的行進方向。direction
:設置文本排列的方向。 rtl 表示從右到左 (相似希伯來語或阿拉伯語), ltr 表示從左到右。unicode-bidi
:它與 direction
很是相似,兩個會常常一塊兒出現。在現代計算機應用中,最經常使用來處理雙向文字的算法是Unicode 雙向算法。而 unicode-bidi
這個屬性是用來重寫這個算法的。單純看定義有點懵逼,咱們簡單的看幾個應用示意圖:web
writing-mode
示意writing-mode
基本只須要留意最多見的 horizontal-tb
、vertical-lr
、vertical-rl
。表示文本的行進方向,下圖表示瀏覽器對 writing-mode
的支持完整的狀況下輸出的外觀:算法
direction
示意OK,那 direction
又爲什麼呢?它表示文本排列的方向。瀏覽器
direction: ltr
:默認屬性。可設置文本和其餘元素的默認方向是從左到右。direction: rtl
:可設置文本和其餘元素的默認方向是從右到左。有點繞,因此上 Demo 最爲直觀。假設,咱們有以下結構:ide
<ul class="wrap"> <li>1</li> <li>2</li> <li>3</li> <li>4</li> </ul> <p>這是一段正常順序的文本</p>
簡單的 CSS 以下:wordpress
p, ul { background: #ff00ff50; padding: 10px; } ul { display: flex; justify-content: space-between; & > li { border: 1px solid #333; } }
正常狀況下的樣式以下:
咱們分別給兩組元素的父容器 <p>
和 <ul>
加上 direction: ltr
及 direction: rtl
,則最終效果以下:
能夠看到,direction
能夠改變子元素的排列方向,可是它確沒法改變單段文本內(或是內聯元素內),每個文字的書寫順序。
那若是,我但願 這是一段正常順序的文本
這段文字,不是從左向右進行書寫,而是反過來,從右到左進行書寫,又該如何設置呢?
unicode-bidi
示意這就須要請出 unicode-bidi
了。
單獨使用 direction: rtl
沒法使單段文本內(或是內聯元素內),文字的書寫順序改成從右至左。須要配合 unicode-bidi
。
CSS 中的 unicode-bidi
屬性,和 direction
屬性,共同決定如何處理文檔中的雙書寫方向文本。
仍是上述的代碼,咱們改造一下:
<p>這是一段正常順序的文本</p>
p { direction: rtl; unicode-bidi: bidi-override; }
結果以下:
放到一塊兒比較:
這裏除了 unicode-bidi: bidi-override
,unicode-bidi: isolate-override
也能獲得一樣的效果。
這裏涉及了一個很是重要的知識 -- Unicode 雙向算法。
雙向文字就是一個字符串中包含了兩種文字,既包含從左到右的文字又包含從右到左的文字。
對於文字書寫習慣,分爲:
在現代計算機應用中,最經常使用來處理雙向文字的算法是 Unicode 雙向算法(Unicode Bidirectional Algorithm)。
一個區域內有整體方向,決定從這個區域的哪邊開始書寫文字,一般稱爲基礎方向。瀏覽器會根據你的默認語言來設置默認的基礎方向,如英語、漢語的基礎方向爲從左到右,阿拉伯語的基礎方向爲從右到左。
在 Web 中,咱們有 3 種方式能夠控制文字方向:
‎
與 ‏
)<bid>
與 <bdo>
標籤 與 dir
屬性direction
+ unicode-bidi
本文介紹的就是 CSS 中的 direction
+ unicode-bidi
方式控制文字的書寫方向。關於 Unicode 雙向算法(Unicode Bidirectional Algorithm)自己仍是很是複雜的,本文也僅僅只是簡單說起,更爲詳盡的內容,你能夠參考 UNICODE BIDIRECTIONAL ALGORITHM
writing-mode
& direction
& unicode-bidi
的一些應用除去自己的功能,下面咱們來看看它們其它的一些應用場景。
writing-mode
進行創意排布布局writing-mode
很是適合用於進行一些創意排版。
基礎的相似中國古詩詞的一些豎向展現:
<div class="g-wrap"> <h2>涼州詞</h2> <p>葡萄美酒夜光杯,</p> <p>欲飲琵琶立刻催。</p> <p>醉臥沙場君莫笑,</p> <p>古來征戰幾人回。</p> </div>
給 .g-wrap
分別添加 writing-mode: vertical-rl
或者 writing-mode: vertical-lr
獲得不一樣的效果:
.rl { writing-mode: vertical-rl; } .lr { writing-mode: vertical-lr; }
CodePen Demo -- display poems by writing-mode
又或者像是這樣,利用 writing-mode:vertical-rl
實現標題的豎向排列,搭配內容造成有意思的報紙排版:
<div> <h2>Title Loomings</h2> <p>Call me Ishmael. Some years ago- never mind ho.... </p> </div>
div { width: 750px; padding-left: 150px; } h2 { position: absolute; writing-mode: vertical-rl; }
獲得這樣的排版佈局:
CodePen Demo -- writing-mode Layout Demo
咱們都知道,本文超長溢出的省略,經過都是在文本的最末尾。像是這樣:
<p>Make CSS Ellipsis Beginning of String</p>
p { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
這裏,咱們能夠經過 direction
,將省略打點的位置,從尾部移動至頭部:
p { direction: rtl; }
結果以下:
嘗試了下運用在多行省略中,多行省略的打點會出如今最後一行的左側,不符合需求。
CodePen Demo -- CSS Ellipsis Beginning of String
writing-mode
改變元素方位這個小技巧是在張老師的博客中學到的:改變CSS世界縱橫規則的writing-mode屬性
咱們能夠經過 writing-mode: vertical-rl
,將元素轉一個 90° 角:
<div>➤</div>
div:hover { writing-mode: vertical-rl; }
看看效果,當 hover 的時候,將箭頭從向右➡️改成向下🔽 :
固然,如今這個功能徹底能夠用
transform
替代,可是在以前須要兼容 IE 系列的時候,不失爲一個有意思的小技巧。
下面一個章節,咱們聊聊 CSS 中的邏輯位置。
咱們知道,在咱們使用相似 margin
和 padding
的時候,能夠單獨控制每一個方向,例如 margin-top
、padding-left
。
然而,這種使用了 top
/left
/bottom
/right
物理方向維度定義的屬性,在不一樣的排版規則下,就很是容易出問題。
思考以下這樣一個 DEMO,咱們但願給古詩的題目的上方,添加一個 padding 值:
<div class="g-wrap pt"> <h2>涼州詞</h2> <p>葡萄美酒夜光杯,</p> <p>欲飲琵琶立刻催。</p> <p>醉臥沙場君莫笑,</p> <p>古來征戰幾人回。</p> </div> <div class="g-wrap pt rl"> <h2>涼州詞</h2> <p>葡萄美酒夜光杯,</p> <p>欲飲琵琶立刻催。</p> <p>醉臥沙場君莫笑,</p> <p>古來征戰幾人回。</p> </div>
.pt { padding-top: 100px; } .rl { writing-mode: vertical-rl; }
能夠看到,不管 writing-mode
如何,padding-top
始終指代物理方向的上方。
基於這種不一樣排版規則,物理方向可能會帶來必定的困擾這個問題,CSS 在 CSS Logical Properties and Values Level 1 規範中,推出了 CSS 邏輯屬性。
CSS 邏輯屬性與值是 CSS 的一個新的模塊,其引入的屬性與值能作到從邏輯角度控制佈局,而不是從物理、方向或維度來控制。
仍是上述的 DEMO,咱們可使用 padding-block-start
替代 padding-top
。
重點:使用 padding-block-start
替代 padding-top
:
.pt { - padding-top: 100px; + padding-block-start: 100px; } .rl { writing-mode: vertical-rl; }
此次再看看效果:
padding
的位置由物理上的上方,變成了邏輯上的上方。
完整的 Demo 你能夠戳這裏:CodePen Demo-- 物理方向與邏輯方向展現
相似這樣的屬性,在規範中定義了挺多的,簡單羅列一下具體的映射規則:
margin
物理屬性到邏輯屬性的映射:Property 屬性 | Logical Property 邏輯屬性 |
---|---|
margin-top | margin-block-start |
margin-left | margin-inline-start |
margin-right | margin-inline-end |
margin-bottom | margin-block-end |
padding
物理屬性到邏輯屬性的映射:Property 屬性 | Logical Property 邏輯屬性 |
---|---|
padding-top | padding-block-start |
padding-left | padding-inline-start |
padding-right | padding-inline-end |
padding-bottom | padding-block-end |
border
物理屬性到邏輯屬性的映射:Property 屬性 | Logical Property 邏輯屬性 |
---|---|
border-top{-size|style|color} | border-block-start{-size|style|color} |
border-left{-size|style|color} | border-inline-start{-size|style|color} |
border-right{-size|style|color} | border-inline-end{-size|style|color} |
border-bottom{-size|style|color} | border-block-end{-size|style|color} |
relative
物理屬性到邏輯屬性的映射:Property 屬性 | Logical Property 邏輯屬性 |
---|---|
top | inset-block-start |
left | inset-inline-start |
right | inset-inline-end |
bottom | inset-block-end |
在邏輯屬性中沒有方向性的概念,只有開始(start)和結束(end)、塊(block)和內聯(inline)的概念。好比說,在從左到右(LTR)中,start 是 left,但在從右到左(RTL),它是 right。
考慮到不一樣排版帶來的邏輯問題,整個盒子模型也能夠隨之進行改變。
下圖,左邊是物理盒子模型,右邊是邏輯屬性下的盒子模型。
固然,還有這樣一種狀況,就是設置的邏輯方向和物理方向重疊,譬如咱們給一個正常從左往右,從上至下的元素同時設置 padding-top
和 padding-block-start
,看看會發生什麼:
div { padding-top: 120px; padding-block-start: 100px; }
這裏若是物理方向與邏輯方向設置的 padding
重疊,將會取兩個值中後面定義的那個。這裏因爲 padding-block-start
後於 padding-top
定義,因此 padding
的值爲 100px
。
margin
和 border
同理。這裏個人理解是,同個方向上仍是隻能存在一個 margin\padding\border
,不管是邏輯方向仍是物理方向,取後定義的值爲準。
CodePen Demo-- 物理方向與邏輯方向重疊 DEMO 展現
總結一下,當項目開始國際化,當國內更多的業務開始出海,國際化兼容適配也會愈來愈重要。好在 CSS 也一直在緊跟時代,推陳出新,當你的排版佈局須要考慮不一樣的 writing-mode
的時,你須要開始考慮使用邏輯屬性替代物理屬性!
好了,本文到此結束,但願對你有幫助 😃
想 Get 到最有意思的 CSS 資訊,千萬不要錯過個人公衆號 -- iCSS前端趣聞 😄
更多精彩 CSS 技術文章彙總在個人 Github -- iCSS ,持續更新,歡迎點個 star 訂閱收藏。
若是還有什麼疑問或者建議,能夠多多交流,原創文章,文筆有限,才疏學淺,文中如有不正之處,萬望告知。