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