CSS Conf -《新時代CSS佈局》學習總結
《新時代CSS佈局》的分享者是新加坡的國際知名CSS專家 陳慧晶 。陳慧晶老師的個人部落格地址是:www.chenhuijing.com/。
陳慧晶老師的分享主題介紹如下:
CSS佈局經常是令前端開發者頭痛的一塊工作。但是近幾年來,瀏覽器不斷髮展,開始支援彈性盒子、網格佈局、盒模型對齊等佈局功能。這些CSS標準純粹是為了應付網路佈局而編寫的。我們將深入瞭解這些新屬性的特徵,新時代的佈局技巧、例子及最佳實踐。希望聽眾會有所啟發,利用這些新的CSS屬性創造更符合瀏覽器本質的設計。
本次分享的線上Slide: www.chenhuijing.com/slides/53-c…
為什麼縱向比橫向難排?
在分享的開始,慧晶老師便丟擲了上述的問題。
其實答案也很簡單,就是因為在最初的時候, HTML 跟 CSS 只是為了歐美國家而服務,而歐美國家文字排版又是橫向的,所以最開始的設計也是也橫向的文件流為主,到後面網際網路不斷髮展,連線至全世界的時候,才有了縱向排版的需求,所以結論就是設計者一開始並沒有考慮縱向排版,所以後續有需求的時候才會出現 縱向比橫向難排 的問題,關於縱橫佈局的比較可以查閱魚頭的 Hello CSS 系列的 CSS的邏輯屬性與盒子模型 。
然後慧晶老師便分享了網際網路的發展史。關於這部分內容,有興趣的也可以查閱魚頭的 Hello CSS 系列的序章-起源。
在這裡,慧晶老師分享了一個很有趣的連結,就是可以檢視最初的網頁長什麼樣,連結在此: worldwideweb.cern.ch/browser/ 。
Web佈局系統
在這一小節中,慧晶老師主要分享了 Flexbox 、 Grid 跟 Box Alignment 這CSS新時代佈局的三大棟樑。
CSS佈局部隊

CSS佈局部隊是由以下以及其他的553個屬性組成。因為CSS是個團隊專案。只有各屬性相互協調配合,才能把CSS的威力完全發揮出來。

瀏覽器的渲染過程
慧晶老師又介紹了瀏覽器的渲染過程,以下是原文摘抄。
如果要揭開CSS佈局的神祕面紗,那就必須先熟悉瀏覽器的渲染過程。渲染引擎會把伺服器傳送過來的Source文件解析成瀏覽器能夠明白的物件。而在渲染網頁之前,瀏覽器會生成一個渲染樹。這個渲染樹是個中介性的結構(intermediary structure),是文件格式結構(formatting structure)的表示法。

CSS在解析的過程,會計算出每個元素和文字節點的每個CSS屬性值。瀏覽器就會靠其中的取值來判斷要生成哪一類的盒子。
CSS顯示模組(CSS Display Module Level 3)
慧晶老師又介紹了 CSS顯示模組(CSS Display Module Level 3) ,以下是原文摘抄。
CSS顯示模組在這二十多年來,經過不少演變。從一開始的基本、到現在最新規範中一共有十七種屬性值。此規範提出了兩種顯示型別,內部及外部。內部顯示型別定義了元素內子元素的佈局方式,外部顯示型別則定義了元素怎樣參與流式佈局的處理。
CSS在解析的過程,會計算出每個元素和文字節點的每個CSS屬性值。瀏覽器就會靠其中的取值來判斷要生成哪一類的盒子。
CSS顯示模組規範提出了兩種顯示型別,內部及外部。內部顯示型別定義了元素內子元素的佈局方式,外部顯示型別則定義了元素怎樣參與流式佈局的處理。

Flex
在這部分慧晶老師主要介紹了 Flex 的語法以及使用技巧(關於語法部分,在此不再累述,有興趣的可以翻閱MDN)。慧晶老師在介紹完 Flex 之後便開始了第一個栗子: 自動margin是你的好友

在上面這個簡單的例子,容器內只有一個子元素。我們可以運用margin來操縱它。如果不設定任何方向,盒子就會在容器的正中間。一行搞定水平垂直居中的問題。
然後慧晶老師提問到:“ 為什麼塊格式自動margin不垂直居中元素? ”
原因是如果元素的高度設為auto,那瀏覽器在計算它的高度時,只會考慮元素內容及子元素,縱向沒有已確定的空間來調整位置。即使元素設了固定的高度,別忘記它跟子元素是互不相關的。這很有可能是瀏覽器最初執行的抉擇遺留下來的行為。瀏覽器沒辦法計算上下方的margin取值,所以就把auto取值解析成0。
容器–專案的「父子」關係
這是慧晶老師之前提到的轉折點。因為flex或grid容器跟子元素的關係,在佈局時是被瀏覽器承認的。因此,瀏覽器才有辦法計算出四面的自動margin取值。

CSS盒式對齊模組
在這一節,慧晶老師對CSS盒式對齊模組(CSS Box Alignment Level 3)進行了介紹。
在這裡,慧晶老師解釋道:
當然,光靠自動margin是不夠的。要更精確的調整子元素的位置,我們可以運用盒式對齊模組(box alignment)提供的屬性值。
Flexbox的首個公開工作草案是在2009釋出的,而Grid的則是2011釋出。當時兩個規範設定了兩組不同的對齊屬性。經過討論,工作組決定把盒子對齊寫成獨立的規範,讓過去、現在和未來的formatting contexts都統一使用相同的屬性。
Box alignment的屬性一共有六個。在使用flex時,用得上其中四個,使用grid的話,六個屬性全部都能用。
魚頭注:這裡具體的屬性也不累述了,有興趣的可以自行查閱[W3C][ www.w3.org/TR/css-alig… ]或者W3C PLUS
Grid或者Flexbox?
“所以應該是用 Gird 還是 Flex ?”
關於這個問題的答案,慧晶老師回答道:
這不是個二選一的狀況,應該是二合一才對。
Flexbox比較適合單維方向的佈局。因為運用Flexbox來實現的行列,即使對齊了,也只是個假象。Flexbox的行跟列是互不相關的。但是在單維佈局,它擁有最強的彈性功能。
Grid則適合做二維網格佈局,因為Grid中的行列才是真實的,才是是有關係的。你可以像在棋盤上排棋子似的,把Grid專案排成理想的佈局。

要實現類似上面佈局的設計,用新時代佈局方式是做得到的。要如何實現這種內容不對齊,環繞每個Grid單元厚厚的border?如果單靠Grid,用Box alignment屬性,可以嗎?

很可惜,做不到。之前有提過,Grid專案對齊的預設值是stretch。一旦用上任何以外的取值時,專案就會馬上縮到內容的尺寸。可是如果我們在Grid專案上設一個display:flex,把它變成Flex容器。那表示Grid專案裡面的內容,成為了Flex專案。現在利用Box alignment的各屬性調整內容的位置就不會影響到Grid專案的尺寸,border也可以保持在Grid線上了。
百分比的侷限(一致性的伸縮率)
慧晶老師原話:“現在已經相當普遍的響應式網頁設計,主要是依靠百分比來設定元素的尺寸。運用百分比的侷限就是每個元素伸縮率是一致的。有時,這會導致開發者為了應付各種viewport尺寸範圍,被逼要寫數不清的media query。

在深入研究這些新的佈局模式時,我發現到最有趣的東西是靈活性尺寸。根據所設定的屬性值,元素伸縮的變化率是有差別的。有些屬性值會「堅持自己的立場」,在viewport變化的狀況下,儘量保持範圍內的寬度。這樣講有點難了解,還是看看一些用例吧。”

接下來慧晶老師主要是對以下三組屬性進行了對比:
(魚頭注:關於上述屬性對比,有興趣的童鞋可以點選連結檢視)
相容處理
慧晶老師說:“Grid正式釋出到現在,已經有大概兩年的時間,瀏覽器的支援程度如今也高達88%,可以算是被廣泛支援了。但是其它12%的使用者該怎麼辦呢?”
上述問題其實CSS可以通過feature query做功能檢測。它的語法類似media query,只是用的關鍵字是 @supports
(魚頭注:關於 @supports
的使用,有興趣的可以檢視魚頭的文章 【Hello CSS】第一章-CSS的語法與工作流 )
如果你也喜歡`CSS`,喜歡探討技術,或者對本文,本系列有任何的意見或建議,魚頭非常希望你能加入一個有趣的微信群 — “ 進擊的CSS ”。你可以掃描下方二維碼,新增魚頭微信,新增時註明 “ 加群 ”,如果你覺得我的文章有趣,歡迎關注微信公眾號“ 魚頭的Web海洋 ”。衷心希望可以遇見你。
