摘要:本篇則會分享的邏輯屬性以及盒子模型。的邏輯屬性年月日,的工作組發布了邏輯屬性和值的首份工作草案。那么按著這個規則去修改文本屬性時,就會出現上述這種不符合語法規則的狀態。大概也是基于這個原因,所以發布了新的邏輯屬性與值。因此稱為匿名盒子。
作者:陳大魚頭
github: KRISACHAN
在上一篇【Hello CSS】的第一章CSS的語法與工作流中介紹了CSS的語法規則以及基本的渲染流程。本篇則會分享CSS的邏輯屬性以及盒子模型。
首先開篇之前先提個問題:
為什么Flex box跟Grid box的是以start、end為排列規則,而不是常規的top 、right 、bottom 跟left?
先不要急著往下翻,大家先思考一下。
這個問題的答案,魚頭會在文章中給出,歡迎大家帶著這個問題往下翻閱,如果已經知道答案,也可以看看跟大家所知道的答案是否一致。
CSS的邏輯屬性2017年5月18日,W3C的 CSS工作組(CSS Working Group) 發布了 CSS邏輯屬性和值(CSS Logical Properties and Values Level 1) 的首份工作草案(First Public Working Draft)。不同的書寫模式(writing mode)中,可以抽取出共性的抽象概念(如開始位置,或行),這些邏輯抽象概念需要在不同書寫模式下映射到左或右、上或下等物理的概念上。一些CSS布局可能依賴這些共性的邏輯概念。該 CSS 模塊給出了用于通過邏輯方式(而不是基于物理坐標、書寫方向和維映射等)控制布局的邏輯屬性和取值(logical properties and values)。這個模塊來源于CSS21中關于邏輯屬性和值的特性。
上面復制粘貼了W3C 中國里的內容。
對于前端來說,我們一直習慣于使用top 、 right 、 bottom、 left來定義我們的HTML元素,這跟我們物理上的概念是一致的。但是對于CSS這個原本是為了服務于圖文展示才誕生的語言來說,其實是不匹配的,為什么這么說?
writing-modewriting-mode:定義了文本水平或垂直排布以及在塊級元素中文本的行進方向。
writing-mode一共有以下5個改變HTML文本書寫規則的值(還有幾個是用在SVG上的,本文不予討論):
writing-mode: horizontal-tb;writing-mode: horizontal-tb 定義了內容從左到右水平流動,從上到下垂直流動。下一條水平線位于上一條線下方。
writing-mode: vertical-rl;writing-mode: vertical-rl 定義了內容從上到下垂直流動,從右到左水平流動。下一條垂直線位于上一行的左側。
writing-mode: vertical-lr;writing-mode: vertical-lr定義了內容從上到下垂直流動,從左到右水平流動。下一條垂直線位于上一行的右側。
writing-mode: sideways-rl; (僅Firefox41+實現)writing-mode: sideways-rl定義了內容從上到下垂直流動,所有字形,甚至是垂直腳本中的字形,都設置在右側。
writing-mode: sideways-lr;(僅Firefox41+實現)writing-mode: sideways-lr內容從上到下垂直流動,所有字形,甚至是垂直腳本中的字形,都設置在左側。
上述效果請看DEMO
源碼如下:
.wm-htb { writing-mode: horizontal-tb; } .wm-vrl { writing-mode: vertical-rl; } .wm-vlr { writing-mode: vertical-lr; } .wm-srl { writing-mode: sideways-rl; } .wm-slr { writing-mode: sideways-lr; } .text-content { width: 200px; padding: 20px; border: 1px solid; display: inline-block; vertical-align: top; padding-right: 100px; }writing-mode: horizontal-tb;writing-mode: vertical-rl;writing-mode: vertical-lr;writing-mode: sideways-rl;writing-mode: sideways-lr;
圖示如下:
從上圖可以發現,當我們設置了padding-right: 100px;的時候,不同的書寫規則,展示效果是不一樣的。
在最開始的時候,HTML與CSS只服務于英語國家,但是隨著互聯網的發展,逐漸各個不同書寫規則的國家也開始流行了起來。
我們原來的CSS邏輯屬性是按照物理邏輯,從上(top)、右(right)、下(bottom)、左(left)劃分的。
那么按著這個規則去修改文本屬性時,就會出現上述這種不符合語法規則的狀態。
大概也是基于這個原因,所以W3C發布了新的邏輯屬性與值。
新舊邏輯屬性對比CSS新舊邏輯屬性是完全不同的兩種模型。
我們首先來看看新舊有的邏輯屬性的對比圖示(圖片來自medium):
左舊右新
通過上圖可以得知新舊邏輯屬性對應關系如下:
舊的邏輯屬性 | 新的邏輯屬性 |
---|---|
margin-top | margin-block-start |
margin-right | margin-inline-end |
margin-bottom | margin-block-end |
margin-left | margin-inline-start |
border-top | border-block-start |
border-right | border-inline-end |
border-bottom | border-block-end |
border-left | border-inline-start |
padding-top | padding-block-start |
padding-right | padding-inline-end |
padding-bottom | padding-block-end |
padding-left | padding-inline-start |
width | inline-size |
height | block-size |
由上表可以得知,把Y軸方向的屬性都改為了block,X軸方向的屬性都改為了inline。
對于不同語系的國家,書寫順序會可能有很大的差異,意思就是block跟inline的方向不同。例如:
在英語國家 padding-inline-start = padding-left
在阿拉伯padding-inline-start = padding-right
在日本 padding-inline-start = padding-top
這就意味著舊的邏輯屬性,在某些國家里會變得不合常理。
CSS定位CSS的定位屬性變化如下:
舊的邏輯屬性 | 新的邏輯屬性 |
---|---|
top | inset-block-start |
bottom | inset-block-end |
left | inset-inline-start |
right | inset-inline-end |
例子如下:
/* 舊的邏輯屬性 */ .popup{ position:fixed; top:0; bottom:0; left:0; right:0; } /* 新的邏輯屬性 */ .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*/ } /* 新的邏輯屬性支持簡寫 */ .popup{ position:fixed; inset:0 0 0 0; /*top, right, bottom, left - in English*/ }
圖示:(圖片來自medium):
浮動float的屬性也改了。
舊的邏輯屬性 | 新的邏輯屬性 |
---|---|
float: left | float: inline-start |
float: right | float: inline-end |
文本text-align的屬性也改了。
舊的邏輯屬性 | 新的邏輯屬性 |
---|---|
text-align: left | text-align: start |
text-align: right | text-align: end |
除了writing-mode,還有一個排版屬性就是direction,跟writing-mode類似,不一樣的是writing-mode是控住網頁布局方向的,而direction是控制文本對齊方向的。屬性如下:
direction: ltr;默認值,讓文本和其他元素從左到右顯示。
direction: rtl;讓文本和其他元素從右到左顯示。
吐槽一下,看到這里的切圖仔們,抓緊 跑路 重構吧,等哪天此屬性正式被啟用,就真的GG了。不過我想應該會立個屬性來選擇性開啟物理屬性還是邏輯屬性,不然這對前端來說將會是一場災難!
當瀏覽器對一個render tree進行渲染時,瀏覽器的渲染引擎就會根據基礎盒模型(CSS basic box model),將所有元素劃分為一個個矩形的盒子,這些盒子的外觀,屬性由CSS來決定。
我們在瀏覽器控制臺輸入如下代碼就可以看到頁面的每一個元素都是由一個矩形來包裹的,這些就是盒子
$$("*").forEach(e => { e.style.border = "1px solid"; })
圖示如下:
每個盒子都由四個部分組成:
內容(content)盒子(box) 的內容,顯示標簽內一切的文本,圖案或者別的內容。
內邊距(padding)盒子(box) 內的填充物,樣式為透明,主要負責擴展盒子內區域大小。
外邊距(margin)盒子(box) 外部的區域,樣式為透明,負責隔離相鄰的元素。
邊框(border)盒子(box) 的邊界,負責隔離外邊距以及內邊距。
盒子模型的值盒子模型一共有三個值:
content-boxcontent-box為標準的盒子模型。盒子的width跟height只包括盒子本身的width與height屬性。
計算法則:
width = width
height = height
border-boxborder-box為盒子模型可選的屬性之一。盒子的width跟height包括content、padding跟border。這也是當文檔處于 Quirks模式 時Internet Explorer使用的盒模型。
計算法則:
width = width + border + padding
height = height + border + padding
padding-boxpadding-box為非標準屬性,曾經在Firefox中實現過,但是在Firefox 50中被刪除。padding-box的width和height 屬性包括內容和內邊距,但是不包括邊框和外邊距。
圖示:
這里吐槽一下,不知道為何沒有margin-box,雖然并沒有太大意義,當真實現了效果估計也很詭異,但是作為一個強迫癥患者晚期,少了一個屬性總感覺好不舒服。
視覺格式化模型(visual formatting model)CSS的視覺格式化模型(visual formatting model) 是根據 基礎盒模型(CSS basic box model) 將 文檔(doucment) 中的元素轉換一個個盒子的實際算法。官方說法就是:它規定了用戶端在媒介中如何處理文檔樹( document tree )。
每個盒子的布局由以下因素決定:
盒子的尺寸
盒子的類型:行內盒子 (inline)、行內級盒子 (inline-level)、原子行內級盒子 (atomic inline-level)、塊盒子 (block)
定位:普通流、浮動、絕對定位
文檔樹中當前盒子的子元素 或 兄弟元素
視口(viewport) 的尺寸 和位置
盒子內部圖片的尺寸
其他某些外部因素
視覺格式化模型(visual formatting model) 的計算,都取決于一個矩形的邊界,這個矩形,被稱作是 包含塊( containing block ) 。 一般來說,(元素)生成的框會扮演它子孫元素包含塊的角色;我們稱之為:一個(元素的)框為它的子孫節點建造了包含塊。包含塊是一個相對的概念。
例子如下:
hi
以上代碼為例,div 和 table 都是包含塊。div 是 table 的包含塊,同時 table 又是 td 的包含塊,不是絕對的。
圖示:(圖片來自w3help):
盒子的生成盒子的生成是 CSS視覺格式化模型 的一部分,用于從文檔元素生成盒子。盒子的類型取決于CSS display 屬性。
塊級元素
當元素的display 為 block、list-item 或 table 時,它就是塊級元素。
塊級盒子
塊級盒子用于描述它與父、兄弟元素之間的關系。
每個塊級盒子都會參與塊格式化上下文(block formatting context)的創建。
每個塊級元素都會至少生成一個塊級盒子,即主塊級盒子(principal block-level box)
主塊級盒子包含由后代元素生成的盒子以及內容,同時它也會參與定位方案。
一個同時是塊容器盒子的塊級盒子稱為塊盒子(block box)。
匿名盒子
某些情況下需要進行視覺格式化時,需要添加一些增補性的盒子,這些盒子不能被CSS 選擇器選中,也就是所有可繼承的 CSS 屬性值都為 inherit ,而所有不可繼承的 CSS 屬性值都為 initial。因此稱為匿名盒子(anonymous boxes)。
行內元素
當元素的display 為 inline、inline-block 或 inline-table 時,它就是行內級元素。
顯示時可以與其他行內級內容一起顯示為多行。
行內盒子
行內級元素會生成行內級盒子,該盒子同時會參與行內格式化上下文(inline formatting context)的創建。
匿名行內盒子
類似于塊盒子,CSS引擎有時候也會自動創建一些行內盒子。這些行內盒子無法被選擇符選中,因此是匿名的,它們從父元素那里繼承那些可繼承的屬性,其他屬性保持默認值 initial。
行盒子
行盒子由行內格式化上下文創建,用來顯示一行文本。在塊盒子內部,行盒子總是從塊盒子的一邊延伸到另一邊(譯注:即占據整個塊盒子的寬度)。當有浮動元素時,行盒子會從向左浮動的元素的右邊緣延伸到向右浮動的元素的左邊緣。
run-in 盒子(在CSS 2.1的標準中移除了)
run-in盒子可以通過display: run-in來設置,它既可以是塊盒子,又可以是行內盒子,這取決于它后面的盒子的類型。
定位規則一旦形成了盒子,CSS引擎就需要定位它們來完成布局。
定位所使用的規則如下:
普通流
在普通流中,盒子會依次放置。
在塊格式化上下文(block formatting context)中,盒子在垂直方向依次排列。
在行內格式化上下文(inline formatting context) 中,盒子則水平擺列。
浮動:當一個盒子的float不為none,并且position為static或relative時,該盒子為浮動定位。
float: left:盒子會定位到當前行盒子的開始位置(左側)。
float: right:盒子會定位到當前行盒子的尾部位置(右側)。
絕對定位:如果元素的position 為 absolute 或 fixed,該元素為絕對定位。
在絕對定位中,盒子會完全從當前流中移除,并且不會再與其有任何聯系。
參考資料:W3C 中國
New CSS Logical Properties!
w3help
視覺格式化模型(Visual formatting model)
MDN 視覺格式化模型
包含塊( Containing block )
結語本篇文章主要介紹了CSS的新舊邏輯屬性的狀態以及盒子模型的具體情況。文章內還有部分內容沒有進行太多的介紹,例如塊格式化上下文(block formatting context) 跟 行內格式化上下文(inline formatting context)以及其他一些具體的名稱,這些后續的文章都將會進行介紹,到時候將會進行具體的講解,希望大家可以多多關注魚頭我的【Hello CSS】系列。
開頭時,魚頭我有問到大家一個問題,就是:
為什么Flex box跟Grid box的是以start、end為排列規則,而不是常規的top 、right 、bottom 跟left?
這個問題,通過本篇文章的分享,大家有答案了嗎?
魚頭我將會在下一篇開頭時分享答案,希望大家多多留意本系列文章。
【Hello CSS】系列【Hello CSS】是以CSS基礎概念為主題的系列文章,旨在幫助大家更深刻地了解并且提高CSS在各位開發者心目中的地位。由于魚頭我水平有限,文筆有限,如果各位在文章中發現有任何不合理,不正確的地方,還煩不吝指出,我會非常感謝的;如果通過文章有任何想法或疑問,也希望各位能積極留言,我們互相探討;如果通過本系列文章有所收獲,這就讓魚頭我喜不自勝了!
如果你也喜歡CSS,喜歡探討技術,或者對本文,本系列有任何的意見或建議,魚頭非常希望你能加入一個有趣的微信群 — “進擊的CSS”。你可以掃描下方二維碼,添加魚頭微信,添加時注明 “加群”,如果你覺得我的文章有趣,歡迎關注微信公眾號“魚頭的Web海洋”。衷心希望可以遇見你。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/114588.html
摘要:作者陳大魚頭正常流什么是正常流其實就是我們日常所說的文檔流。在官方文檔里對應的是。然后,包含形成一條線的框的矩形區域稱為線盒。基線線盒的高度由的計算結果決定。級層疊上下文被自動視為父級層疊上下文的一個獨立單元。自由分配,由具體情況決定。 作者:陳大魚頭 github: KRISACHAN 正常流 什么是正常流?其實就是我們日常所說的文檔流。在W3C官方文檔里對應的是normal ...
摘要:作者陳大魚頭正常流什么是正常流其實就是我們日常所說的文檔流。在官方文檔里對應的是。然后,包含形成一條線的框的矩形區域稱為線盒。基線線盒的高度由的計算結果決定。級層疊上下文被自動視為父級層疊上下文的一個獨立單元。自由分配,由具體情況決定。 作者:陳大魚頭 github: KRISACHAN 正常流 什么是正常流?其實就是我們日常所說的文檔流。在W3C官方文檔里對應的是normal ...
摘要:本篇則會介紹瀏覽器的視圖與坐標。返回值為視覺視口的縮放比例視覺視口寬度,返回值為像素值。那么接下來我們來了解一下瀏覽器中的坐標系系統。在數學里,笛卡爾坐標系英語,也稱直角坐標系,是一種正交坐標系。 作者:陳大魚頭 github: KRISACHAN 在上一篇【Hello CSS】的第二章第二章-CSS的邏輯屬性與盒子模型中提了個問題: 為什么Flex box跟Grid box的是...
摘要:前兩個元素之間的是,因為較小的頂部與較大的底部相結合。這是由于兩個重疊造成的。同樣,這種行為也有一定的邏輯。這意味著在使用百分比時,元素周圍的大小都是相同的。 為了保證的可讀性,本文采用意譯而非直譯。 當我們學習CSS時,我們大多數人學到的第一件事是CSS中盒子的各個部分的細節,這部分通過叫做 CSS盒、模型。盒模型中的元素之一是margin,即盒子周圍的透明區域,它會將其他元素從盒子...
摘要:前兩個元素之間的是,因為較小的頂部與較大的底部相結合。這是由于兩個重疊造成的。同樣,這種行為也有一定的邏輯。這意味著在使用百分比時,元素周圍的大小都是相同的。 為了保證的可讀性,本文采用意譯而非直譯。 當我們學習CSS時,我們大多數人學到的第一件事是CSS中盒子的各個部分的細節,這部分通過叫做 CSS盒、模型。盒模型中的元素之一是margin,即盒子周圍的透明區域,它會將其他元素從盒子...
閱讀 2936·2021-10-14 09:43
閱讀 2878·2021-10-14 09:42
閱讀 4661·2021-09-22 15:56
閱讀 2368·2019-08-30 10:49
閱讀 1593·2019-08-26 13:34
閱讀 2380·2019-08-26 10:35
閱讀 602·2019-08-23 17:57
閱讀 2027·2019-08-23 17:15