【Hello CSS】第六章-文檔流與排版

正常流

什麼是「正常流」? 其實就是咱們平常所說的「文檔流」。 在W3C官方文檔裏對應的是「normal flow」。css

正常流的盒子屬於格式化上下文(FC),在CSS2.2中能夠是表格內聯。 在CSS3中引入了flexgrid,固然之後會引入得更多。html

塊級盒子(block-level boxes) 與建立 塊級格式化上下文(BFC) 有關;css3

行內級盒子(inline-level boxes) 與建立 行內級格式化上下文(IFC) 有關。git

BFC

魚頭注:在以前的文章中有介紹過如何生成一個BFC,本章便再也不累述。github

根據W3C上的解釋:

浮動、絕對定位元素、塊容器(例如inline-blocks、table-cells、and table-captions)都不是塊盒子。除了overflow之外的visible(除非該值已經傳播到了視口)爲其內容創建新的BFCweb

表現是什麼?

表現就是在包含塊內一個盒子一個盒子不重疊地垂直排列,兩個兄弟盒子直接的垂直距離由margin決定。浮動也是如此(雖然有可能兩個盒子的距離會由於floats而變小),除非該盒子再建立一個新的BFC瀏覽器

簡單來講,BFC就是一個獨立不干擾外界也不受外界干擾的盒子啊(/ω\)微信

IFC

魚頭注:Mmmmm,BFC仍是相對好理解,IFC比較複雜,W3C上所佔的篇幅也比BFC多得多的。ide

簡單來講,跟BFC表現不同的盒子就是IFC了(*❦ω❦)。wordpress

BFC不同,IFC內的盒子會從包含塊的頂部一個接着一個地水平排列。這些盒子會考慮水平marginborderpadding。垂直對齊的方式也略有複雜。而後,包含造成一條線的框的矩形區域稱爲線盒(line box)

線盒(line box)的寬度:由浮動狀況跟它所在的包含塊決定。

線盒(line box)的高度:由line-height的計算結果決定。

基線(baseline)

線盒(line box) 的高度由line-height的計算結果決定。

line-height的定義就是線盒(line box)內兩基線(baseline)(W3C原文)的間距。

vertical-align的默認值就是基線。

字母x

大家還記得讀書時用的英語做業本嗎?

image

如上圖所示,咱們看到小寫字母x的位置,它的上下邊緣就是咱們的基線(baseline),但下邊緣纔是咱們平常使用的屬性值。順便一提,CSS單位ex即是指的這個字母x的高度。

如何理解IFC

自從翻了CSS的發展史以後,瞭解了CSS的誕生背景以後,其實不少東西理解起來就輕鬆了。IFC之因此比BFC複雜,緣由就在於不少非規律的成分,在西文了,咱們能夠簡單粗暴的理解爲英語做業本的表現,可是在writing-mode不一樣,文字表現不一樣的各個國家,IFC的表現也會有差別。

固然以上都是個人我的理解,若是有更科學更標準的理解方式或者不一樣的想法,能夠加魚頭微信「krisChans95」來探討。

層疊上下文與層疊順序

咱們首先來看一張很著名的圖

image

上面即是在一樣的上下文中,元素的層疊規則(CSS3之後的除外,那規則會比較複雜)。元素的 z-index 值只在父級層疊上下文中有意義。級層疊上下文被自動視爲父級層疊上下文的一個獨立單元。

文檔中的層疊上下文由知足如下任意一個條件的元素造成:

  • 根元素 (HTML),
  • z-index 值不爲 auto 的 絕對/相對定位,
  • 一個 z-index 值不爲 auto 的 flex 項目 (flex item),即:父元素 display: flex|inline-flex
  • opacity 屬性值小於 1 的元素,
  • transform 屬性值不爲 none 的元素,
  • mix-blend-mode 屬性值不爲 "normal"的元素,
  • filter值不爲 none 的元素,
  • perspective值不爲 none 的元素,
  • isolation 屬性被設置爲 isolate 的元素,
  • position: fixed
  • will-change 中指定了任意 CSS 屬性,即使你沒有直接指定這些屬性的值
  • -webkit-overflow-scrolling 屬性被設置 touch 的元素

新時代的佈局

Flex

我想到現在,應該不多人會沒寫過或者沒了解過 Flex (不知道的能夠翻閱MDN)。

這個是 CSS 史上第一個以 start-end 來定義方向的屬性,這是一個可伸縮的佈局模型。

一個設有 display:flexdisplay:inline-flex 的元素是一個伸縮容器,伸縮容器的子元素被稱爲爲伸縮項目,這些子元素使用伸縮佈局模型來排版。

語法以下:

display: flex/inline-flex;
flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ];
複製代碼

flex 屬性能夠指定1個,2個或3個值。

單值語法: 值必須爲如下其中之一:

  • 一個無單位 數(<number>) : 它會被看成<flex-grow>的值
  • 一個有效的 寬度(width) 值: 它會被看成 <flex-basis>的值
  • 關鍵字 noneauto, 或 initial

雙值語法: 第一個值必須爲一個無單位數,而且它會被看成 <flex-grow> 的值。第二個值必須爲如下之一:

  • 一個無單位數:它會被看成 <flex-shrink> 的值。
  • 一個有效的寬度值: 它會被看成 <flex-basis> 的值。

三值語法:

  • 第一個值必須爲一個無單位數,而且它會被看成 <flex-grow> 的值。
  • 第二個值必須爲一個無單位數,而且它會被看成 <flex-shrink> 的值。
  • 第三個值必須爲一個有效的寬度值, 而且它會被看成 <flex-basis> 的值。

Grid

我印象中第一次接觸Grid佈局的時候,開個Chrome的實驗性功能也就只能能支持個repeat(4, 200px),但現在已經除了IE,其餘瀏覽器差很少也是Full support了(若是你還不瞭解這個佈局模型,能夠翻閱MDN)。

在這裏順便提一下,Flex是一維佈局,Grid是二維佈局。意思就是Flex只能同時在一個方向進行做用,而Grid卻能夠在縱橫兩個方向同時工做。

語法以下:

display: grid/inline-grid;
gird: <'grid-template'> | <'grid-template-rows'> / [ auto-flow && dense? ] <'grid-auto-columns'>? | [ auto-flow && dense? ] <'grid-auto-rows'>? / <'grid-template-columns'>
複製代碼

咱們來看看 grid 所支持的一些 「奇怪」 的特性:

命名空間

魚頭以爲 grid 佈局中最有趣的功能就是命名空間了,咱們能夠看看如下示例:

首先是第一種 網格線命名

<style> html, body, div { margin: 0; padding: 0; } .grid { display: grid; width: 420px; background: #e4d6ba; margin: 1em auto; } .g-namespace { height: 400px; grid-template-columns: [col1] 100px [col2] auto [col3] 100px; grid-template-rows: [rows1] 25% [rows2] 100px [rows3] auto [rows4] 60px } .grid > div { outline: 1px dotted; } </style>
<body>
    <div class="grid g-namespace">
        <div></div>
        <div></div>
        <div></div>
        <div></div>
        <div></div>
        <div></div>
        <div></div>
        <div></div>
        <div></div>
        <div></div>
        <div></div>
        <div></div>
    </div>
</body>
複製代碼

效果以下:

image

第二種 真命名空間佈局

<style> html, body, div { margin: 0; padding: 0; } .grid { display: grid; width: 400px; height: 400px; margin: 1em auto; } .g-namespace { grid-template-columns: 1fr 1fr 1fr; grid-template-rows: 1fr 1fr 1fr; grid-template-areas: "頭部 頭部 頭部" "左邊 中間 右邊" "底部 底部 底部"; } .頭部 { grid-area: 頭部 / 頭部 / 頭部 / 頭部; background: #32CD32; } .底部 { grid-area: 底部 / 底部 / 底部 / 底部; background: #FFD700; } .左邊 { grid-area: 左邊 / 左邊 / 左邊 / 左邊; background: #EE82EE; } .右邊 { grid-area: 右邊 / 右邊 / 右邊 / 右邊; background: #FF7F50; } </style>
<body>
    <div class="grid g-namespace">
        <div class="頭部"></div>
        <div class="左邊"></div>
        <div class="右邊"></div>
        <div class="底部"></div>
    </div>
</body>
複製代碼

效果以下:

image

經過上面兩個示例,咱們能夠發現Grid佈局的二維性能夠知足咱們平常不少的佈局要求,固然,第一眼看語法難免有點懵,可是熟悉以後,基本平常需求中的二維佈局咱們都能依賴它來完成。

一些經常使用的靈活尺寸

屬性 定義
fr 可伸縮長度單位,網格容器中可用空間的一等份。
auto 自由分配,由具體狀況決定。
minmax() 定義了一個長寬範圍的閉區間。
fit-content() 同等於min(maximum size, max(minimum size, argument))

以上屬性對比結果以下:

image

源碼在我codepen中,你們能夠自行去對比: codepen.io/krischan77/…

後記

本章的內容要深究起來是很是龐大的,魚頭我在準備內容的時候有想過是否是要另外再開個佈局的系列去分享,可是我想把本文當成是一個關鍵字集合來供本身以及有須要的人來作目錄也是極好的。我認爲CSS中最難的部分就是佈局了,雖然W3C自己提供了不少的屬性以及規範來處理這些佈局問題的,可是涉及到了現實的項目,更多時候是錯綜複雜的,可是隨着CSS邏輯屬性的變化,以及各種新佈局系統的出現,相信之後的佈局會簡單得多。

本章內容就這麼草草結束了,關於上面提到的,或者沒有提到的與之相關的,之後有機會魚頭會新開個系列來分享。固然若是看到這裏的你有任何佈局上的看法或問題也歡迎來找魚頭探討。

參考資料:

聊聊CSS中的層疊相關概念

CSS Conf -《新時代CSS佈局》學習總結

新時代CSS佈局

CSS世界

CSS Display Module Level 3

CSS Flexible Box Layout Module Level 1

CSS Grid Layout Module Level 1

CSS Box Alignment Module Level 3

寫給本身看的display: grid佈局教程

寫給本身看的display: flex佈局教程

CSS深刻理解流體特性和BFC特性下多欄自適應佈局

塊格式化上下文

Normal flow

css中的IFC

【Hello CSS】系列

【Hello CSS】是以CSS基礎概念爲主題的系列文章,旨在幫助你們更深入地瞭解而且提升CSS在各位開發者心目中的地位。因爲魚頭我水平有限,文筆有限,若是各位在文章中發現有任何不合理,不正確的地方,還煩不吝指出,我會很是感謝的;若是經過文章有任何想法或疑問,也但願各位能積極留言,咱們互相探討;若是經過本系列文章有所收穫,這就讓魚頭我喜不自勝了!



若是你也喜歡 CSS,喜歡探討技術,或者對本文,本系列有任何的意見或建議,你能夠掃描下方二維碼,關注微信公衆號「 魚頭的Web海洋」,隨時與魚頭互動。歡迎!衷心但願能夠碰見你。

相關文章
相關標籤/搜索