提綱:
- 前言
- 建立全局觀
- 實驗代碼與關鍵名詞解釋
- vertical-align 含義水到渠成
- 案例分析
- 結語
前言
最近我在自學 CSS (cascading style sheets), 發現這個話題還真是相當複雜。複雜的地方不在於它不斷增加的語法多樣性,而在於那些看似簡潔的語法背後、影響網頁元素最終呈現的大量互相交織、互相影響的隱性因素。這些隱性因素,單從 CSS 語法上是無法直接察覺的,得有明眼人指導,加上自己動手反覆嘗試才能逐步探查清楚。
Vertical-align, 一個看似普通的 CSS 屬性(property),用來調整一塊文本的頂部對齊、底部對齊或是居中對齊,其實裡頭大有名堂,這是隱性因素大行其道的地方。這兩天玩弄這個屬性的過程還發現了 Chrome 71 (2019.02) 在這個屬性上犯的 bug ,真是意外。剛開始沒意識到這是 bug,以為是我自己理解有誤,但對照了 Firefox 65 後,認為這應該就是 Chrome 的 bug,本文後頭將展示之([CASE 3.1])。因此,世界上有兩份完全不同的瀏覽器實現是多麼重要。
我學習 CSS 的參考書有兩本:
- [CSSID] Manning - CSS in Depth (2018),是塑造 CSS 全局觀的書,超棒,我給十分。不過此書偏偏沒講 vertical-align.
- [CSSDG] OReilly - CSS: The Definitive Guide, 4th Edition (2017),這本歷史其實很悠久了,從 2000 的第一版不斷擴寫而來,我只給七分,因為它缺乏全局觀,像流水帳,更適合當字典來查。
網上講 vertical-align 的文章重床疊架。但我相信我的這篇是獨特的,因為我相信我自己在寫這篇文章的過程中為自己塑造了 vertical-align 的全局觀。全局觀為什麼重要,因為它能使我們擺脫盲人摸象的處境,網上的很多文章可能就沒有擺脫這種處境。
當然,我不敢說我這裡講的內容完全正確,細節上可能有些許偏差,畢竟 CSS 的複雜性擺在那裡,我這篇文章更像是提供了一小塊實驗場,我們可以藉助其驗證陳述的對錯。
【澄清關於 vertical-align 的歧義】
如果你去看 vertical-align 的官方文檔,它的第一句話是:
The vertical-align
CSS property sets vertical alignment of an inline or table-cell box.
但我要告訴你,vertical-align 此處是有歧義的,更準確地說,它是一詞兩用,你體會到了嗎?打個比方,「龍頭」這個詞,其實它有獨立的兩個意思,「自來水龍頭」和「行業龍頭」。回到 vertical-align,其實是兩個獨立場景用了同一個屬性名。
- 場景一,不妨叫它 align-me-to-parent 。我們在一個 inline 性質的子元素上設定該屬性,讓這個子元素用一種特定的規則跟父元素進行對齊。
- 場景二,不妨叫它 align-my-children。我們在一個 table-cell 元素(作為父元素)上設定該屬性,讓它的子元素在單元格內浮頂、沉底或居中顯示。
這兩種場景是完全互相獨立的,按理說應該給它們起不同的屬性名,只不過,CSS 的規範制定者偷了個懶,用了相同的名字,好在這兩種場景是不會交叉的,意即,一個元素不可能既是 table-cell 又是個 inline (<span>, <img> 等),一詞兩用也就不會有衝突了。順便說一句,場景二的 vertical-align 有個孿生屬性,叫 text-align,其取值可以是 left, center, right, 用於指示它裡頭的子元素在
水平方向上靠左、居中、或靠右對齊。然而,場景一卻沒有類似的孿生屬性,是啊,一個
inline element 豈有水平方向上任意找人對齊的道理?本文討論的 vertical-align 完全是 align-me-to-parent 這種場景;至於 align-my-children 那個場景則簡單得多,本文就不費筆墨了。本文後頭提及的 vertical-align ,都是指場景一的。
接下來,文章比較長,需要一些耐心。
建立全局觀
這裡我必須先展示一個表格,叫它 VA-table 吧,該表格是獲得 vertical-align 全局觀的關鍵。後頭分析具體案例時,你需要回頭來查這張表格。