前言
一直聽說line-height是指兩行文本的基線間的距離,然后又說行高等于行距,最近還聽說有個叫行間距的家伙,@張鑫旭還說line-height和vertical-align基情四射,貴圈真亂啊。。。。。。于是通過本篇來一探究竟:)
line-height到底有多height?
行距、行間距傻傻分不清
首先看看“有道詞典”的解析!
Leading = Line Space + Font Size(即是 行距 = 行間距 + 字體大小)
Leading: 指相鄰文本行間上一個文本行基線和下一文本行基線間的距離。
Line Space: 指相鄰文本行間上一個文本行下行線(ascent)和下一文本行上行線(descent)間的距離。
而在一些面向普通消費者的軟件中,Leading往往是指Line Space。Leading
在CSS當中,Leading就是指Line Space。而CSS屬性line-height則是用于設置真實的Leading。參考
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的一個重要特性——垂直居中性。
line-height的垂直居中性
通過L = 'line-height' - AD
我們知道line-height=行間距+字形大小,字形大小我們可以通過font-size來設置,而line-height就更不用說了,而家問題是行間距所占的空間是怎樣分配的呢?
方案1:不是說行間距就是上一行的descent到下一行的ascent間的距離嗎?那直接分配到A位置就好了。
方案2:如果方案1的分配方案合理,那么分配到B位置就也是OK的。
方案3:一邊倒的分配方案太不美觀了吧!不如將行間距對半開,然后分別分配到上下兩端不就OK了嗎!
CSS采用的就是方案3。這是引用了Half-leading的概念,Half-leading = Leading/2.
Half the leading is called the half-leading. User agents center glyphs vertically in an inline box, which adds half-leading on the top and bottom. For example, if a piece of text is "12pt" high and the line-height value is "14pt", 2pt of extra space should be added: 1pt above and 1pt below the text (this applies to empty boxes as well, as if the empty box contained zero-height text).參考
在深入垂直居中性之前,我們先看一個容易引起誤解的示例。(其實是我自己誤解而已:()
<div id="container" style="border:solid 1px red;"><span style="background:blue;color:#fff;font-size:20px;line-height:60px;">center glyphs vertically in an inline box.</span></div>
不是說好了會垂直居中嗎?你看字母x明明就在div#container
中線的下方呢!
我們用空格符代替文字就可以看清楚了。
<div style="border:solid 1px red;"><span style="background:blue;color:#fff;font-size:20px;line-height:60px;">                     </span></div>
“垂直居中”是指字形所在的盒子的垂直中線與line-height所占據的盒子的垂直中線重合,不是指字形的mean line和line-height所占據的盒子的垂直中線重合。
從L = "line-height" - AD
可以知道行間距可能會負數,那么垂直居中性還有效嗎?
答案是肯定的,L為負數時,Half-leading自然也是負數,只是上下兩端從增加空間變為減少等量空間而已。不信你看
<body style="margin:0 10px;padding:0;">
<div style="position:relative;top:100px;font-size:90px;line-height:10px;background:yellow;"><span style="border:solid 1px red;line-height:10px;">x</span></div>
</body>
line-height屬性
'line-height'
Value: normal | <number> | <length> | <percentage> | inherit
Initial: normal
Applies to: all elements
Inherited: yes
Percentages: refer to the font size of the element itself
Media: visual
Computed value: forand 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其實就是一個
Chrome43的結果 Firefox44.0.2 IE9 通過小數據統計得出normal值的規律: <length> 設置固定值,單位可以是px、pt。好處是簡單——設置是什么,line-height的實際高度就是什么。壞處是子元素默認情況下會繼承父容器的line-height屬性,若子元素的font-size大于父容器的font-size屬性值,那么子元素的文本行會十分密集,降低可閱讀性。所以我們一般采用相對font-size實際大小來設置line-height值的方式,如默認normal方式。 <percentage> 既然采用
<number>
下面我們稍微將line-height垂直居中特性中Leading為負數的示例代碼修改一下,將 不是說垂直居中嗎?這里就涉及到一個相對復雜的CSS垂直對齊規則——vertical-align。 'vertical-align'
<lenght>:設置相對于baseline的距離,正數表示位于baseline的上方,負數表示位于baseline的下方; 注意:vertical-align僅對inline-level和table-cell元素有效,下面示例無效是正常不過的。 1.默認對齊方式——baseline 2.top——把元素line box上邊框對齊父元素的line box上邊框 其實除了在div上設置 由于我工作中沒有適配IE8等歷史瀏覽器的需求,因此詳細內容請參考@張鑫旭的CSS vertical-align的深入理解(二)之text-top篇 到這里理論部分已經介紹完了,是時候通過示例來驗證自己了! 尊重原創,轉載請注明來自:http://www.cnblogs.com/fsjohnhuang/p/5307706.html^_^肥子John 深入了解css的行高Line Height屬性<body style="font-family: Arial, Tahoma, Sans-serif;">
<div style="background:blue;color:#FFF;font-size:10px;">line-height-x-L</div>
<div style="background:blue;color:#FFF;font-size:40px;">line-height-x-L</div>
<div style="background:blue;color:#FFF;font-size:80px;">line-height-x-L</div>
<script type="text/javascript">
var els = document.getElementsByTagName('div')
for (var i = 0, len = els.length; i < len; ++i){
console.log(els[i].offsetHeight)
}
</script>
</body>
14/10 = 1.4
45/40 = 1.125
92/80 = 1.15
average: 1.225 約為1.2
13/10 = 1.3
46/40 = 1.15
92/80 = 1.15
average: 1.2
11/10 = 1.1
46/40 = 1.15
92/80 = 1.15
average: 1.13333 約為1.1
The specified length is used in the calculation of the line box height. Negative values are illegal.
The computed value of the property is this percentage multiplied by the element's computed font size. Negative values are illegal.
font-size:20px;line-height:200%;
,那么子元素繼承來的line-height值為40px,而不是200%。因此又回到
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.
其實line-height:1.2em;
和line-height:1.2;
是等價的。若想將參考系改為根元素的font-size,則需要采用CSS3新增的line-height:1.2rem
單位了。
根據WCAG2.0(萬維網內容可存取性指南)規定“段落中的行距至少要1.5倍”,那么是否在body那設置一個<style type="text/css">
body{
font-size: 16px;
line-height: 1.5;
}
h1 {font-size:32px;}
p {font-size:16px;}
#footer {font-size:12px;}
</style>
<h1>CSS魔法堂:深入理解line-height和vertical-align</h1>
<p>In my dual profession as an educator and health care provider, I have worked with numerous children infected with the virus that causes AIDS. The relationships that I have had with these special kids have been gifts in my life. They have taught me so many things, but I have especially learned that great courage can be found in the smallest of packages. Let me tell you about Tyler. </p>
<div id="footer">bed and whispered, “I might die soon. I’m not scared. When I die, please dress me in red. Mom promised she’s coming to heaven, too. I’ll be playing when she gets there, and I want to make sure she can find me.”</div>
看對于h1標題欄而言,行距太多了。于是得出如下配置:body{line-height:1.5;}
h1,h2,h3,h4,h5,h6{line-height:1.2;}
vertical-align到底如何對齊呢?
font-size:90px;line-height:10px;
遷移到子元素中.<div style="position:relative;top:100px;background:yellow;"><span style="border:solid 1px red;font-size:90px;line-height:10px;">x</span></div>
注意:前方高能,需要IFC、line box作為前提知識。(可參考CSS魔法堂:重新認識Box Model、IFC、BFC和Collapsing margins)vertical-algin屬性
Value: baseline | sub | super | top | text-top | middle | bottom | text-bottom | <percentage> | <length> | inherit
Initial: baseline
Applies to: inline-level and 'table-cell' elements
Inherited: no
Percentages: refer to the 'line-height' of the element itself
Media: visual
Computed value: for
<percentage>:設置以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僅對inline-level和table-cell元素有效
<div>
<div style="float:left;font-size:20px;vertical-align:middle;">I'm former</div>
<div style="float:left;font-size:50px;vertical-align:middle;">I'm latter</div>
</div>
IE9+下的vertical-align屬性值詳解(以下內容均在Chrome43中測試)
<div style="font-size:14px;">
<span id="obj" style="font-size:40px;">line-height x vertical-align</span>
x for reference frame
</div>
這里x for reference frame作為參考系,而它的baseline就是span#obj
所要對齊的baseline了。
那么在baseline的基礎上的設置<length>和<percentage><div style="font-size:14px;">
<span id="obj" style="font-size:40px;vertical-align:10px;">line-height x vertical-align</span>
x for reference frame
</div>
<div style="font-size:14px;">
<span id="obj" style="font-size:40px;vertical-align:-10px;">line-height x vertical-align</span>
x for reference frame
</div>
<div style="font-size:14px;line-height:1;">
<span id="obj" style="font-size:40px;vertical-align:50%;">line-height x vertical-align</span>
x for reference frame
</div>
<div style="font-size:14px;line-height:1;">
<span id="obj" style="font-size:40px;vertical-align:-50%;">line-height x vertical-align</span>
x for reference frame
</div>
我們將上面的示例稍微改一下<span style="font-size:14px;">
<span id="obj" style="font-size:40px;vertical-align:top;">line-height x vertical-align</span>
x for reference frame
</span>
確實不同了,但這無法證明是元素的line box上邊框對齊父元素的line box上邊框哦。那么我們改改代碼看看 <body style="margin:0 10px;padding:0;">
<div style="border:solid 1px blue;font-size:14px;line-height:1;">
<span id="parent" style="background:red;line-height:1;">
<span id="obj" style="background:yellow;font-size:40px;vertical-align:top;line-height:1;">line-height x vertical-align</span>
x for reference frame
</span>
</div>
</body>
通過line-height:1
使line box與content box/area的高度一致,雖然span#parent
和span#obj
的上邊框對齊,但還不能說明什么。 <body style="margin:0 10px;padding:0;">
<div style="position:relative;top:100px;;border:solid 1px blue;font-size:14px;line-height:1;">
<span id="parent" style="background:red;line-height:1;">
<span id="obj" style="background:yellow;font-size:40px;vertical-align:top;line-height:1;margin-top:100px;padding-top:100px;background-clip:content-box;">line-height x vertical-align</span>
x for reference frame
</span>
</div>
</body>
沒有任何變化。那改變line-height又如何呢? <body style="margin:0 10px;padding:0;">
<div style="border:solid 1px blue;font-size:14px;line-height:1;">
<span id="parent" style="background:red;line-height:2;">
<span style="display:inline-block;vertical-align:top;background:green;">
<span id="obj" style="background:yellow;font-size:40px;line-height:2;">line-height x vertical-align</span>
</span>
x for reference frame
</span>
</div>
</body>
為了讓span#obj
的Half-leading清晰可見,特意添加一個display:inline-block
的inline box包裹著span#obj
。而span#parent
也增大了Half-leading的高度。現在可以我們清晰看到確實是span#obj
的line box的上邊框對齊父元素的line box上邊框。(同理證明了vertical-align:bottom
是把元素line box下邊框對齊父元素的line box下邊框;)
注意:chrome下若外層div不添加font-size:14px;line-height:1;
屬性,將導致span#parent上有條空白間隙
原因十分簡單,那是因為span#parent
的對齊方式是baseline,參考系是div的baseline,而div的line-height為normal,有空白間隙就是當然的事了。通過JS就可以看清楚了。var div = document.getElementsByTagName('div')[0]
console.log(div.childNodes[0].nodeType) // 顯示3,就是TextNode
line-height:1
之外,我們還可以在span#parent
上設置vertical-align:top
來解決。 <body style="margin:0 10px;padding:0;">
<div style="border:solid 1px blue;font-size:14px;">
<span id="parent" style="background:red;line-height:1;vertical-align:top;">
<span id="obj" style="background:yellow;font-size:40px;vertical-align:top;line-height:1;">line-height x vertical-align</span>
x for reference frame
</span>
</div>
</body>
3.text-top——把元素的line box上邊框對齊父元素的ascent(即content top edge) <body style="margin:0 10px;padding:0;">
<div style="position:relative;top:100px;border:solid 1px blue;font-size:14px;line-height:1;"> <span id="parent" style="background:red;line-height:2;">
<span id="obj" style="background:yellow;vertical-align:text-top;font-size:2px;line-height:1;">*</span>
x for reference frame
</span>
</div>
</body>
<body style="margin:0 10px;padding:0;">
<div style="position:relative;top:100px;border:solid 1px blue;font-size:14px;line-height:1;"> <span id="parent" style="background:red;line-height:2;">
<span style="display:inline-block;vertical-align:text-top;border-top:solid 2px green;">
<span id="obj" style="background:yellow;font-size:2px;line-height:2;">*******</span>
</span>
x for reference frame
</span>
</div>
</body>
4.middle——把元素line box中垂點與父元素基線 + x-height/2的高度對齊 <body style="margin:0 10px;padding:0;">
<div style="border:solid 1px blue;font-size:40px;line-height:1;">
<span id="parent" style="background:red;line-height:1;">
<span id="obj" style="padding-top:10px;display:inline-block;background:yellow;font-size:15px;line-height:1;vertical-align:middle;">*******</span>x for reference frame
</span>
</div>
</body>
注意
當元素的display:inline-block/inline-table
等對應的是atomic inline-level box時,其line box高度為margin box的高度。若元素對應的是inline box,則其最小高度為line-height,最大則由子盒子決定。IE5.5~8下vertical-align屬性值詳解
簡單來說IE5.5~IE8下vertical-align:text-top
是把元素的ascent對齊父元素的ascent(即content top edge)真的掌握vertical-align了嗎?
單行文字的垂直居中對齊
<style type="text/css">
.slma1{
border:solid 3px #888;
font-size: 14px;
line-height: 100px;
}
</style>
<p class="slma1">
字體大小14px
</p>
<style type="text/css">
.slma2{
border:solid 3px #888;
font-size: 14px;
line-height: 100px;
}
.slma2 i{font-style:normal;font-weight:bolder;vertical-align:middle;}
.slma2 span{font-size:30px;vertical-align:middle;}
</style>
<p class="slma2">
<i>* </i>字體大小為14px<span>字體大小為30px</span>
</p>
行數不固定的多行文字的垂直居中對齊
<style type="text/css">
.mlma1{
border:solid 3px #888;
font-size: 14px;
line-height: 100px;
}
.mlma1 span{
line-height: 1.5;
display: inline-block;
vertical-align: middle;
}
</style>
<p class="mlma1">
<span> 第一行文本<br/>the second one.</span>
</p>
大小不固定的圖片的垂直居中對齊
<style type="text/css">
.a{width: 100px; height: 100px;}
.b{width: 80px; height: 80px;}
.c{width: 60px; height: 60px;}
.container{
background: #ccc;
line-height: 200px;
}
img{padding:5px;border:solid 1px blue;vertical-align:middle;}
</style>
<div class="container">
<img class="a" src="./john.png"/>
<img class="b" src="./john.png"/>
<img class="c" src="./john.png"/>
<img class="b" src="./john.png"/>
</div>
總結
感謝
我對CSS vertical-align的一些理解與認識(一)
CSS vertical-align的深入理解(二)之text-top篇
CSS深入理解vertical-align和line-height的基友關系
css行高line-height的一些深入理解及應用
大小不固定的圖片、多行文字的水平垂直居中
深入理解 CSS 中的行高與基線
文章列表