天天看點

CSS魔法堂:深入了解line-height和vertical-align

一直聽說line-height是指兩行文本的基線間的距離,然後又說行高等于行距,最近還聽說有個叫行間距的家夥,@張鑫旭還說line-height和vertical-align基情四射,貴圈真亂啊。。。。。。于是通過本篇來一探究竟:)

 首先看看“有道詞典”的解析!

Leading = Line Space + Font Size(即是 行距 = 行間距 + 字型大小) Leading: 指相鄰文本行間上一個文本行基線和下一文本行基線間的距離。 Line Space: 指相鄰文本行間上一個文本行下行線(ascent)和下一文本行上行線(descent)間的距離。
Still for each glyph, determine the leading L to add, where L = 'line-height' - AD

AD是指字形ascent和descent間的距離,即是font-size。

這裡為更清晰地叙說,我将以廣義Leading指代行間距,而狹義Leading則指代行距。

從W3C Rec中看出,line-height就是狹義Leading,而line-height的字面意思即為“行高”,推導結果CSS中行高即是行距。

這裡我們了解到行高,行距和行間距的差別了。那接下來要介紹line-height的一個重要特性——垂直居中性。

 通過<code>L = 'line-height' - AD</code>我們知道line-height=行間距+字形大小,字形大小我們可以通過font-size來設定,而line-height就更不用說了,而家問題是行間距所占的空間是怎樣配置設定的呢?

方案1:不是說行間距就是上一行的descent到下一行的ascent間的距離嗎?那直接配置設定到A位置就好了。

CSS魔法堂:深入了解line-height和vertical-align

方案2:如果方案1的配置設定方案合理,那麼配置設定到B位置就也是OK的。

CSS魔法堂:深入了解line-height和vertical-align

方案3:一邊倒的配置設定方案太不美觀了吧!不如将行間距對半開,然後分别配置設定到上下兩端不就OK了嗎!

CSS魔法堂:深入了解line-height和vertical-align

CSS采用的就是方案3。這是引用了Half-leading的概念,Half-leading = Leading/2.

在深入垂直居中性之前,我們先看一個容易引起誤解的示例。(其實是我自己誤解而已:()

不是說好了會垂直居中嗎?你看字母x明明就在<code>div#container</code>中線的下方呢!

我們用空格符代替文字就可以看清楚了。

CSS魔法堂:深入了解line-height和vertical-align

“垂直居中”是指字形所在的盒子的垂直中線與line-height所占據的盒子的垂直中線重合,不是指字形的mean line和line-height所占據的盒子的垂直中線重合。

從<code>L = "line-height" - AD</code>可以知道行間距可能會負數,那麼垂直居中性還有效嗎?

答案是肯定的,L為負數時,Half-leading自然也是負數,隻是上下兩端從增加空間變為減少等量空間而已。不信你看

CSS魔法堂:深入了解line-height和vertical-align
'line-height' Value: normal | &lt;number&gt; | &lt;length&gt; | &lt;percentage&gt; | inherit Initial: normal Applies to: all elements Inherited: yes Percentages: refer to the font size of the element itself Media: visual Computed value: for and the absolute value; otherwise as specified
normal Tells user agents to set the used value to a "reasonable" value based on the font of the element. The value has the same meaning as . We recommend a used value for 'normal' between 1.0 to 1.2. The computed value is 'normal'.

 normal其實就是一個值,不過實際值則由浏覽器決定,實際值一般在1.0~1.2之間(含兩端)浮動。但實際真的是這樣嗎?

Chrome43的結果

CSS魔法堂:深入了解line-height和vertical-align

Firefox44.0.2

CSS魔法堂:深入了解line-height和vertical-align

IE9

CSS魔法堂:深入了解line-height和vertical-align

通過小資料統計得出normal值的規律:

不同浏覽器的normal值不相同;

同一個浏覽器下,font-size值不同,normal值也會有變化;

同一浏覽器下,font-size值相同,font-family值不同,normal值也會有變化;

normal的平均值确實是在1.0~1.2之間(含兩端),但具體到特定浏覽器、font-family和font-size時,normal的實際值可能會大于1.2。

&lt;length&gt; The specified length is used in the calculation of the line box height. Negative values are illegal.

 設定固定值,機關可以是px、pt。好處是簡單——設定是什麼,line-height的實際高度就是什麼。壞處是子元素預設情況下會繼承父容器的line-height屬性,若子元素的font-size大于父容器的font-size屬性值,那麼子元素的文本行會十分密集,降低可閱讀性。是以我們一般采用相對font-size實際大小來設定line-height值的方式,如預設normal方式。

&lt;percentage&gt; The computed value of the property is this percentage multiplied by the element's computed font size. Negative values are illegal.

 既然采用副作用那麼大,那采用這個相對值就萬事大吉了吧!非也,首先我們要弄清楚這個的參考系是啥,另外還要明白子元素的line-height到底繼承的了哪個值,是值還是父容器實際的line-height值。

的參考系的确是font-size;

子元素繼承的是父容器實際的line-height值。也就是說父容器設定為<code>font-size:20px;line-height:200%;</code>,那麼子元素繼承來的line-height值為40px,而不是200%。是以又回到方式的問題上了。

&lt;number&gt; The used value of the property is this number multiplied by the element's font size. Negative values are illegal. The computed value is the same as the specified value.

 和方式一樣,以font-size作為參考系,以相對值的方式設定line-height。唯一的不同就是子元素繼承的是父容器的值,參考系自動變更為子元素的font-size。

其實<code>line-height:1.2em;</code>和<code>line-height:1.2;</code>是等價的。若想将參考系改為根元素的font-size,則需要采用CSS3新增的<code>line-height:1.2rem</code>機關了。

根據WCAG2.0(網際網路内容可存取性指南)規定“段落中的行距至少要1.5倍”,那麼是否在body那設定一個就一勞永逸呢?請看

CSS魔法堂:深入了解line-height和vertical-align

看對于h1标題欄而言,行距太多了。于是得出如下配置:

 下面我們稍微将line-height垂直居中特性中Leading為負數的示例代碼修改一下,将<code>font-size:90px;line-height:10px;</code>遷移到子元素中.

CSS魔法堂:深入了解line-height和vertical-align

不是說垂直居中嗎?這裡就涉及到一個相對複雜的CSS垂直對齊規則——vertical-align。

'vertical-align' Value: baseline | sub | super | top | text-top | middle | bottom | text-bottom | &lt;percentage&gt; | &lt;length&gt; | inherit Initial: baseline Applies to: inline-level and 'table-cell' elements Inherited: no Percentages: refer to the 'line-height' of the element itself Computed value: for and the absolute length, otherwise as specified

&lt;lenght&gt;:設定相對于baseline的距離,正數表示位于baseline的上方,負數表示位于baseline的下方;

&lt; percentage&gt;:設定以line-height為參考系,相對于baseline的距離,正數表示位于baseline的上方,負數表示位于baseline的下方;

baseline:預設值。元素的基線與父元素的基線對齊;

top:把元素line box上邊框對齊父元素的line box上邊框;

text-top:把元素line box上邊框對齊父元素的ascent(即content top edge);

super:升高元素的基線到父元素合适的上标位置;

middle:把元素line box中垂點與父元素基線 + x-height/2的高度對齊;

sub:降低元素的基線到父元素合适的下标位置;

text-bottom:把元素line box下邊框對齊父元素的descent(即content bottom edge);

bottom:把元素line box下邊框對齊父元素的line box下邊框;

inherit:繼承父元素的對齊方式。

怎麼這麼多規則要記啊?我記性不好難道到時還要挨個查嗎?其實歸納一下就OK了!

對齊操作必定涉及操作元素和參考系元素,而vertical-align的值全是指參考系元素的位置,而操作元素則以baseline或linebox上中下作對齊;

預設對齊方式為baseline,數量值均是相對于baseline而言。

注意:vertical-align僅對inline-level和table-cell元素有效,下面示例無效是正常不過的。

CSS魔法堂:深入了解line-height和vertical-align

1.預設對齊方式——baseline

CSS魔法堂:深入了解line-height和vertical-align

這裡x for reference frame作為參考系,而它的baseline就是<code>span#obj</code>所要對齊的baseline了。

那麼在baseline的基礎上的設定&lt;length&gt;和&lt;percentage&gt;

CSS魔法堂:深入了解line-height和vertical-align

2.top——把元素line box上邊框對齊父元素的line box上邊框

我們将上面的示例稍微改一下

CSS魔法堂:深入了解line-height和vertical-align

确實不同了,但這無法證明是元素的line box上邊框對齊父元素的line box上邊框哦。那麼我們改改代碼看看

CSS魔法堂:深入了解line-height和vertical-align

通過<code>line-height:1</code>使line box與content box/area的高度一緻,雖然<code>span#parent</code>和<code>span#obj</code>的上邊框對齊,但還不能說明什麼。

CSS魔法堂:深入了解line-height和vertical-align

沒有任何變化。那改變line-height又如何呢?

CSS魔法堂:深入了解line-height和vertical-align

為了讓<code>span#obj</code>的Half-leading清晰可見,特意添加一個<code>display:inline-block</code>的inline box包裹着<code>span#obj</code>。而<code>span#parent</code>也增大了Half-leading的高度。現在可以我們清晰看到确實是<code>span#obj</code>的line box的上邊框對齊父元素的line box上邊框。(同理證明了<code>vertical-align:bottom</code>是把元素line box下邊框對齊父元素的line box下邊框;)

注意:chrome下若外層div不添加<code>font-size:14px;line-height:1;</code>屬性,将導緻<code>span#parent上有條空白間隙</code>

CSS魔法堂:深入了解line-height和vertical-align

原因十分簡單,那是因為<code>span#parent</code>的對齊方式是baseline,參考系是div的baseline,而div的line-height為normal,有空白間隙就是當然的事了。通過JS就可以看清楚了。

其實除了在div上設定<code>line-height:1</code>之外,我們還可以在<code>span#parent</code>上設定<code>vertical-align:top</code>來解決。

CSS魔法堂:深入了解line-height和vertical-align

3.text-top——把元素的line box上邊框對齊父元素的ascent(即content top edge)

CSS魔法堂:深入了解line-height和vertical-align
CSS魔法堂:深入了解line-height和vertical-align

4.middle——把元素line box中垂點與父元素基線 + x-height/2的高度對齊

CSS魔法堂:深入了解line-height和vertical-align

注意

當元素的<code>display:inline-block/inline-table</code>等對應的是atomic inline-level box時,其line box高度為margin box的高度。若元素對應的是inline box,則其最小高度為line-height,最大則由子盒子決定。

簡單來說IE5.5~IE8下<code>vertical-align:text-top</code>是把元素的ascent對齊父元素的ascent(即content top edge)

 到這裡理論部分已經介紹完了,是時候通過示例來驗證自己了!

CSS魔法堂:深入了解line-height和vertical-align
CSS魔法堂:深入了解line-height和vertical-align
CSS魔法堂:深入了解line-height和vertical-align

<a href="http://www.cnblogs.com/fengzheng126/archive/2012/05/18/2507632.html">深入了解css的行高Line Height屬性</a>

<a href="http://www.zhangxinxu.com/wordpress/2010/05/%E6%88%91%E5%AF%B9css-vertical-align%E7%9A%84%E4%B8%80%E4%BA%9B%E7%90%86%E8%A7%A3%E4%B8%8E%E8%AE%A4%E8%AF%86%EF%BC%88%E4%B8%80%EF%BC%89/">我對CSS vertical-align的一些了解與認識(一)</a>

<a href="http://www.zhangxinxu.com/wordpress/2010/06/css-vertical-align%E7%9A%84%E6%B7%B1%E5%85%A5%E7%90%86%E8%A7%A3%EF%BC%88%E4%BA%8C%EF%BC%89%E4%B9%8Btext-top%E7%AF%87/">CSS vertical-align的深入了解(二)之text-top篇</a>

<a href="http://www.zhangxinxu.com/wordpress/2015/08/css-deep-understand-vertical-align-and-line-height/">CSS深入了解vertical-align和line-height的基友關系</a>

<a href="http://www.zhangxinxu.com/wordpress/2009/11/css%E8%A1%8C%E9%AB%98line-height%E7%9A%84%E4%B8%80%E4%BA%9B%E6%B7%B1%E5%85%A5%E7%90%86%E8%A7%A3%E5%8F%8A%E5%BA%94%E7%94%A8/">css行高line-height的一些深入了解及應用</a>

<a href="http://www.zhangxinxu.com/wordpress/2009/08/%E5%A4%A7%E5%B0%8F%E4%B8%8D%E5%9B%BA%E5%AE%9A%E7%9A%84%E5%9B%BE%E7%89%87%E3%80%81%E5%A4%9A%E8%A1%8C%E6%96%87%E5%AD%97%E7%9A%84%E6%B0%B4%E5%B9%B3%E5%9E%82%E7%9B%B4%E5%B1%85%E4%B8%AD/">大小不固定的圖檔、多行文字的水準垂直居中</a>

<a href="http://sojuker.blog.163.com/blog/static/1387908792012760243916/">深入了解 CSS 中的行高與基線</a>

如果您覺得本文的内容有趣就掃一下吧!捐贈互勉!

CSS魔法堂:深入了解line-height和vertical-align
CSS魔法堂:深入了解line-height和vertical-align
CSS魔法堂:深入了解line-height和vertical-align

<a href="http://home.cnblogs.com/u/fsjohnhuang/">^_^肥仔John</a>

<a href="http://home.cnblogs.com/u/fsjohnhuang/followees">關注 - 85</a>

<a href="http://home.cnblogs.com/u/fsjohnhuang/followers">粉絲 - 707</a>

<a>+加關注</a>

4

<a></a>

評論清單

支援支援。。好長。。

http://pic.cnblogs.com/face/u41249.jpg

<a href="http://www.ucancode.com/index.htm" target="_blank">【推薦】超50萬VC++源碼: 大型工控、組态\仿真、模組化CAD源碼2018!</a>

<a href="https://cloud.tencent.com/developer/support-plan?fromSource=gwzcw.710852.710852.710852" target="_blank">【推薦】加入騰訊雲自媒體扶持計劃,免費領取域名&amp;伺服器</a>

CSS魔法堂:深入了解line-height和vertical-align

<b>最新IT新聞</b>:

CSS魔法堂:深入了解line-height和vertical-align

<b>最新知識庫文章</b>:

<a href="https://github.com/fsjohnhuang" target="_blank">肥仔John@github</a>

作品:

<a href="https://github.com/fsjohnhuang/iScheme" target="_blank">iScheme—Scheme解釋器</a>

繼續閱讀