CSS世界Bug般的存在——字母x與“居中”

字母x ?

《css世界》中提到:“我們這裏的字母x就是26個英文字母中的x。由於自身形態的一些特殊性,這個小小的不起眼的字母擔當大任,在css世界中扮演了一個重要的角色。”


筆者在這兩天寫一個項目中遇到了“居中”的困惑:我發現代碼段

li{
	verticle-align: middle;
}

失效!

經過一番查證,發現:vertical-align屬性只對行內元素有效,對塊元素無效
但我很快想到:有時候爲什麼寫了line-height也會出錯、或者說反而會出錯呢?

有時使用display:inline-block會導致verticle-align:middle失效。爲何?因爲display:inline-block會導致line-height有偏差

這又是什麼原理?

fg

字母x與“基線”

在各種內聯相關模型中,凡是涉及垂直方向的排版或者對齊的,都離不開最基本的——基線。
例如,line-height行高的定義就是兩基線的間距,verticle-align的默認值就是基線;其它中線頂線一類的定義也離不開基線。
基線也延伸出了很多其它的概念:
比如字母基線懸掛基線表意基線
jx

而【基線】的定義就離不開本文的主角“X”。

字母x的下邊緣(所在直線)就是我們所說的基線

上面所說內容當然和開頭的“問題”沒有直接關係,但是它確實引出了下面的一系列概念:

fg

字母x與CSS中的x-height

要更深層次的瞭解字母x,或者說基線與居中有何關係,那就不得不說CSS中的一個概念——x-height
它指的是字母x的高度!

通俗的講,x-height就是指小寫字母x的高度,術語描述就是基線和等分線(也叫“中線”)之間的距離:
jxx

爲什麼要說這個?
CSS中有些屬性值的定義其實就和這個x-height有關,最典型的代表就是verticle-align: middle;。這裏的middle是中間的意思。注意:跟上面所說【中線】不是一個意思(圖中baseline上面那根就是median——中線)。
在CSS中,middle指的是基線往上1/2 x-height高度的位置。我們可以近似理解爲“字母x的交叉點所在位置”。

由此可見,verticle-align: middle 並不是絕對的垂直居中對齊 —— 我們平時看到的middle效果只是一種近似效果。原因很簡單:不同字體在行內盒子中的位置是不一樣的。

事實上,“微軟雅黑”是一個字符比較下沉的字體——所有字符的位置都比其它字體要偏下一點。

也就是說,“微軟雅黑”字體中的字母x的交叉點是在容器中分線的下面一點。而此時我們就不難理解爲什麼verticle-align不是相對容器的中分線對其的了。

讓我們回到開頭的一段代碼,我們此時可以很容易想到:先將其變爲行內

li{
	display: inline-block;
	verticle-align: middle;
}

發現沒啥用。。。
然後我們“恍然大悟”,想到:這是缺少“參照”的表現啊!

而對於li列表,適合用什麼佈局呢?——table:

li{
	display: table-cell;   /* 轉化爲單元格 */
	verticle-align: middle;
}

其實line-block失效的原因有很多:比如你再元素外層又包裹了div,對div設置display、本來就是line…這裏是恰好碰上li罷了

這樣就解決了。

fg

字母x與CSS中的ex

我們可能都聽過em、rem、px、rpx,但是這個ex是什麼鬼。。。
說起這個,他可能就會很自豪:畢竟是連IE6都支持的屬性單位。

ex是CSS中的一個相對單位,指的就是小寫字母x的高度。沒錯,就是指x-height。
而且——不受字體和自號影響的內聯元素的垂直居中對其效果!

我們都知道,內聯元素默認是基線對齊的,而基線就是x的底部,而1ex就是一個x的高度。設想一下,假如圖片(標)的高度就是1ex,將其作爲背景圖片顯示,這時如果(背景)圖片居中,那豈不是圖標和文字“天然”垂直居中對齊?而且不受字體和自號的影響。

<div class="mxc">
	yunxiaomeng<i class="icon-arrow"></i>
</div>
<style>
	.icon-arrow {
    	display: inline-block;
    	width: 20px;
    	height: 1ex;
    	background: url("/img/up.png") no-repeat center/20px 20px;
	}
</style>

xm
然後就對齊了 —— 完全沒有verticle-align的出場機會嘛!


當然,關於“居中偏差”的問題我們也可以用僞元素解決,比如這裏:

li:after{
	content: "";
	display: inline-block;
	height: 100%;
	vertical-align: middle;
}

【本文所有資料來源:《CSS世界》;感謝張鑫旭大大】

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章