web前端入門到實戰(zhàn):CSS的邏輯屬性與盒子模型

首先開篇之前先提個問題:

為什么Flex boxGrid box的是以startend為排列規(guī)則楷掉,而不是常規(guī)的top 厢蒜、rightbottomleft烹植?

先不要急著往下翻斑鸦,大家先思考一下。

這個問題的答案刊橘,魚頭會在文章中給出鄙才,歡迎大家?guī)е@個問題往下翻閱,如果已經(jīng)知道答案促绵,也可以看看跟大家所知道的答案是否一致攒庵。

CSS的邏輯屬性

2017年5月18日,W3C的 CSS工作組(CSS Working Group) 發(fā)布了 CSS邏輯屬性和值(CSS Logical Properties and Values Level 1) 的首份工作草案(First Public Working Draft)败晴。不同的書寫模式(writing mode)中浓冒,可以抽取出共性的抽象概念(如開始位置,或行)尖坤,這些邏輯抽象概念需要在不同書寫模式下映射到左或右稳懒、上或下等物理的概念上。一些CSS布局可能依賴這些共性的邏輯概念慢味。該 CSS 模塊給出了用于通過邏輯方式(而不是基于物理坐標场梆、書寫方向和維映射等)控制布局的邏輯屬性和取值(logical properties and values)。這個模塊來源于CSS21中關(guān)于邏輯屬性和值的特性纯路。

對于前端來說或油,我們一直習慣于使用topright 驰唬、 bottom顶岸、 left來定義我們的HTML元素腔彰,這跟我們物理上的概念是一致的。但是對于CSS這個原本是為了服務(wù)于圖文展示才誕生的語言來說辖佣,其實是不匹配的霹抛,為什么這么說?

writing-mode

writing-mode:定義了文本水平或垂直排布以及在塊級元素中文本的行進方向卷谈。

writing-mode一共有以下5個改變HTML文本書寫規(guī)則的值(還有幾個是用在SVG上的杯拐,本文不予討論):

writing-mode: horizontal-tb;

writing-mode: horizontal-tb 定義了內(nèi)容從左到右水平流動,從上到下垂直流動雏搂。下一條水平線位于上一條線下方藕施。

writing-mode: vertical-rl;

writing-mode: vertical-rl 定義了內(nèi)容從上到下垂直流動寇损,從右到左水平流動凸郑。下一條垂直線位于上一行的左側(cè)。

writing-mode: vertical-lr;

writing-mode: vertical-lr定義了內(nèi)容從上到下垂直流動矛市,從左到右水平流動芙沥。下一條垂直線位于上一行的右側(cè)。

writing-mode: sideways-rl; (僅Firefox41+實現(xiàn))

writing-mode: sideways-rl定義了內(nèi)容從上到下垂直流動浊吏,所有字形而昨,甚至是垂直腳本中的字形,都設(shè)置在右側(cè)找田。

writing-mode: sideways-lr;(僅Firefox41+實現(xiàn))

writing-mode: sideways-lr內(nèi)容從上到下垂直流動歌憨,所有字形,甚至是垂直腳本中的字形墩衙,都設(shè)置在左側(cè)务嫡。

源碼如下:

.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;
}

<div class="text-content wm-htb">writing-mode: horizontal-tb;</div>
<div class="text-content wm-vrl">writing-mode: vertical-rl;</div>
<div class="text-content wm-vlr">writing-mode: vertical-lr;</div>
<div class="text-content wm-srl">writing-mode: sideways-rl;</div>
<div class="text-content wm-slr">writing-mode: sideways-lr;</div>
web前端開發(fā)學習Q-q-u-n: 731771211,分享學習的方法和需要注意的小細節(jié)漆改,不停更新最新的教程和學習方法(詳細的前端項目實戰(zhàn)教學視頻心铃,PDF)

圖示如下:

從上圖可以發(fā)現(xiàn),當我們設(shè)置了padding-right: 100px;的時候挫剑,不同的書寫規(guī)則去扣,展示效果是不一樣的。

在最開始的時候樊破,HTMLCSS只服務(wù)于英語國家愉棱,但是隨著互聯(lián)網(wǎng)的發(fā)展,逐漸各個不同書寫規(guī)則的國家也開始流行了起來哲戚。

我們原來的CSS邏輯屬性是按照物理邏輯奔滑,從上(top)、右(right)惫恼、下(bottom)档押、左(left)劃分的。

那么按著這個規(guī)則去修改文本屬性時,就會出現(xiàn)上述這種不符合語法規(guī)則的狀態(tài)令宿。

大概也是基于這個原因叼耙,所以W3C發(fā)布了新的邏輯屬性與值。

新舊邏輯屬性對比

CSS新舊邏輯屬性是完全不同的兩種模型粒没。

我們首先來看看新舊有的邏輯屬性的對比圖示:

左舊右新

通過上圖可以得知新舊邏輯屬性對應(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軸方向的屬性都改為了blockX軸方向的屬性都改為了inline癞松。

對于不同語系的國家爽撒,書寫順序會可能有很大的差異,意思就是blockinline的方向不同响蓉。例如:

  • 在英語國家 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*/
}
web前端開發(fā)學習Q-q-u-n: 731771211枫甲,分享學習的方法和需要注意的小細節(jié)源武,不停更新最新的教程和學習方法(詳細的前端項目實戰(zhàn)教學視頻,PDF)

CSS浮動

浮動float的屬性也改了想幻。

舊的邏輯屬性 新的邏輯屬性
float: left float: inline-start
float: right float: inline-end

text-align

文本text-align的屬性也改了粱栖。

舊的邏輯屬性 新的邏輯屬性
text-align: left text-align: start
text-align: right text-align: end

direction

除了writing-mode,還有一個排版屬性就是direction脏毯,跟writing-mode類似闹究,不一樣的是writing-mode是控住網(wǎng)頁布局方向的,而direction是控制文本對齊方向的食店。屬性如下:

direction: ltr;

默認值渣淤,讓文本和其他元素從左到右顯示。

direction: rtl;

讓文本和其他元素從右到左顯示叛买。

吐槽一下砂代,看到這里的切圖仔們,抓緊 跑路 重構(gòu)吧率挣,等哪天此屬性正式被啟用刻伊,就真的GG了。不過我想應(yīng)該會立個屬性來選擇性開啟物理屬性還是邏輯屬性椒功,不然這對前端來說將會是一場災(zāi)難捶箱!

CSS的盒子模型

基礎(chǔ)盒模型(CSS basic box model)

當瀏覽器對一個render tree進行渲染時,瀏覽器的渲染引擎就會根據(jù)基礎(chǔ)盒模型(CSS basic box model)动漾,將所有元素劃分為一個個矩形的盒子丁屎,這些盒子的外觀,屬性由CSS來決定旱眯。

我們在瀏覽器控制臺輸入如下代碼就可以看到頁面的每一個元素都是由一個矩形來包裹的晨川,這些就是盒子

$$('*').forEach(e => {
  e.style.border = '1px solid';
})

圖示如下:

每個盒子都由四個部分組成:

內(nèi)容(content)

盒子(box) 的內(nèi)容证九,顯示標簽內(nèi)一切的文本,圖案或者別的內(nèi)容共虑。

內(nèi)邊距(padding)

盒子(box) 內(nèi)的填充物愧怜,樣式為透明,主要負責擴展盒子內(nèi)區(qū)域大小妈拌。

外邊距(margin)

盒子(box) 外部的區(qū)域拥坛,樣式為透明,負責隔離相鄰的元素尘分。

邊框(border)

盒子(box) 的邊界猜惋,負責隔離外邊距以及內(nèi)邊距。

盒子模型的值

盒子模型一共有三個值:

content-box

content-box為標準的盒子模型培愁。盒子的widthheight只包括盒子本身的widthheight屬性著摔。

計算法則:

width = width

height = height

border-box

border-box為盒子模型可選的屬性之一。盒子的widthheight包括content竭钝、paddingborder梨撞。這也是當文檔處于 Quirks模式 時Internet Explorer使用的盒模型雹洗。

計算法則:

width = width + border + padding

height = height + border + padding

padding-box

padding-box為非標準屬性香罐,曾經(jīng)在Firefox中實現(xiàn)過,但是在Firefox 50中被刪除时肿。padding-boxwidthheight 屬性包括內(nèi)容和內(nèi)邊距庇茫,但是不包括邊框和外邊距。

圖示:

這里吐槽一下螃成,不知道為何沒有margin-box旦签,雖然并沒有太大意義,當真實現(xiàn)了效果估計也很詭異寸宏,但是作為一個強迫癥患者晚期宁炫,少了一個屬性總感覺好不舒服。

視覺格式化模型(visual formatting model)

CSS視覺格式化模型(visual formatting model) 是根據(jù) 基礎(chǔ)盒模型(CSS basic box model)文檔(doucment) 中的元素轉(zhuǎn)換一個個盒子的實際算法氮凝。

官方說法就是:它規(guī)定了用戶端在媒介中如何處理文檔樹( document tree )羔巢。

每個盒子的布局由以下因素決定:

  • 盒子的尺寸
  • 盒子的類型:行內(nèi)盒子 (inline)行內(nèi)級盒子 (inline-level)罩阵、原子行內(nèi)級盒子 (atomic inline-level)竿秆、塊盒子 (block)
  • 定位:普通流浮動稿壁、絕對定位
  • 文檔樹中當前盒子的子元素兄弟元素
  • 視口(viewport)尺寸位置
  • 盒子內(nèi)部圖片的尺寸
  • 其他某些外部因素

視覺格式化模型(visual formatting model) 的計算幽钢,都取決于一個矩形的邊界,這個矩形傅是,被稱作是 包含塊( containing block ) 匪燕。 一般來說蕾羊,(元素)生成的框會扮演它子孫元素包含塊的角色;我們稱之為:一個(元素的)框為它的子孫節(jié)點建造了包含塊帽驯。包含塊是一個相對的概念肚豺。

例子如下:

<div>
    <table>
        <tr>
            <td>hi</td>
        </tr>
    </table>
</div>
web前端開發(fā)學習Q-q-u-n: 731771211,分享學習的方法和需要注意的小細節(jié)界拦,不停更新最新的教程和學習方法(詳細的前端項目實戰(zhàn)教學視頻吸申,PDF)

以上代碼為例,divtable 都是包含塊享甸。divtable 的包含塊截碴,同時 table 又是 td 的包含塊,不是絕對的蛉威。

盒子的生成

盒子的生成是 CSS視覺格式化模型 的一部分日丹,用于從文檔元素生成盒子。盒子的類型取決于CSS display 屬性蚯嫌。

  • 塊級元素

    • 當元素的displayblock哲虾、list-itemtable 時,它就是塊級元素择示。
  • 塊級盒子

    • 塊級盒子用于描述它與父束凑、兄弟元素之間的關(guān)系。
    • 每個塊級盒子都會參與塊格式化上下文(block formatting context)的創(chuàng)建栅盲。
    • 每個塊級元素都會至少生成一個塊級盒子汪诉,即主塊級盒子(principal block-level box)
    • 主塊級盒子包含由后代元素生成的盒子以及內(nèi)容,同時它也會參與定位方案谈秫。
    • 一個同時是塊容器盒子的塊級盒子稱為塊盒子(block box)扒寄。
  • 匿名盒子

    • 某些情況下需要進行視覺格式化時,需要添加一些增補性的盒子拟烫,這些盒子不能被CSS 選擇器選中该编,也就是所有可繼承的 CSS 屬性值都為 inherit ,而所有不可繼承的 CSS 屬性值都為 initial硕淑。因此稱為匿名盒子(anonymous boxes)课竣。
  • 行內(nèi)元素

    • 當元素的displayinlineinline-blockinline-table 時喜颁,它就是行內(nèi)級元素稠氮。
    • 顯示時可以與其他行內(nèi)級內(nèi)容一起顯示為多行。
  • 行內(nèi)盒子

    • 行內(nèi)級元素會生成行內(nèi)級盒子半开,該盒子同時會參與行內(nèi)格式化上下文(inline formatting context)的創(chuàng)建隔披。
  • 匿名行內(nèi)盒子

    • 類似于塊盒子,CSS引擎有時候也會自動創(chuàng)建一些行內(nèi)盒子寂拆。這些行內(nèi)盒子無法被選擇符選中奢米,因此是匿名的抓韩,它們從父元素那里繼承那些可繼承的屬性,其他屬性保持默認值 initial鬓长。
  • 行盒子

    • 行盒子由行內(nèi)格式化上下文創(chuàng)建谒拴,用來顯示一行文本。在塊盒子內(nèi)部涉波,行盒子總是從塊盒子的一邊延伸到另一邊(譯注:即占據(jù)整個塊盒子的寬度)英上。當有浮動元素時,行盒子會從向左浮動的元素的右邊緣延伸到向右浮動的元素的左邊緣啤覆。
  • run-in 盒子(在CSS 2.1的標準中移除了)

    • run-in盒子可以通過display: run-in來設(shè)置苍日,它既可以是塊盒子,又可以是行內(nèi)盒子窗声,這取決于它后面的盒子的類型相恃。

定位規(guī)則

一旦形成了盒子,CSS引擎就需要定位它們來完成布局笨觅。

定位所使用的規(guī)則如下:

  • 普通流

    • 在普通流中拦耐,盒子會依次放置。
    • 塊格式化上下文(block formatting context)中见剩,盒子在垂直方向依次排列杀糯。
    • 行內(nèi)格式化上下文(inline formatting context) 中,盒子則水平擺列炮温。
  • 浮動:當一個盒子的float不為none火脉,并且positionstaticrelative時,該盒子為浮動定位柒啤。

    • float: left:盒子會定位到當前行盒子的開始位置(左側(cè))。
    • float: right:盒子會定位到當前行盒子的尾部位置(右側(cè))畸颅。
  • 絕對定位:如果元素的positionabsolutefixed担巩,該元素為絕對定位。

    • 在絕對定位中没炒,盒子會完全從當前流中移除涛癌,并且不會再與其有任何聯(lián)系。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末送火,一起剝皮案震驚了整個濱河市拳话,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌种吸,老刑警劉巖弃衍,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異坚俗,居然都是意外死亡镜盯,警方通過查閱死者的電腦和手機岸裙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來速缆,“玉大人降允,你說我怎么就攤上這事∫彰樱” “怎么了剧董?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長破停。 經(jīng)常有香客問我送滞,道長,這世上最難降的妖魔是什么辱挥? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任犁嗅,我火速辦了婚禮,結(jié)果婚禮上晤碘,老公的妹妹穿的比我還像新娘褂微。我一直安慰自己,他們只是感情好园爷,可當我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布宠蚂。 她就那樣靜靜地躺著,像睡著了一般童社。 火紅的嫁衣襯著肌膚如雪求厕。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天扰楼,我揣著相機與錄音呀癣,去河邊找鬼。 笑死弦赖,一個胖子當著我的面吹牛项栏,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蹬竖,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼沼沈,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了币厕?” 一聲冷哼從身側(cè)響起列另,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎旦装,沒想到半個月后页衙,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡同辣,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年拷姿,在試婚紗的時候發(fā)現(xiàn)自己被綠了惭载。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡响巢,死狀恐怖描滔,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情踪古,我是刑警寧澤含长,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站伏穆,受9級特大地震影響拘泞,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜枕扫,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一陪腌、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧烟瞧,春花似錦诗鸭、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至砾赔,卻和暖如春蝌箍,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背暴心。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工妓盲, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人酷勺。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓本橙,卻偏偏與公主長得像,于是被迫代替她去往敵國和親脆诉。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內(nèi)容