line-height,vertical-align及圖片居中對齊問題根源解析

關於圖片居中對齊的問題,進入前端行業雖然有一段時間了,覺得本身懂了,但是實際上仍是隻知其一;不知其二,找了一些博客來看了一下,可是感受講的有點碎,看完仍是隻知其一;不知其二css

查閱了一下《css權威指南》,結合遇到的問題,這才瞭解到前先後後的問題根源。html

 

主要的問題以下:前端

1.line-height是個什麼東西,範圍在哪裏,具體應用於什麼元素?瀏覽器

2.vertiacal-alignline-height有什麼關係,元素對齊究竟是一個什麼樣的過程。wordpress

3.圖片對齊和文本對齊有什麼區別?佈局

4.浮動元素爲何對齊會出現問題?測試

-------》解答這些問題,牽涉的碎片化知識:字體

基線,底端,行內框,行框,行距,替換元素及非替換元素,對齊ui

下面圍繞着上面的三個問題,以及相應的碎片化知識點來進行解析問題。spa

通常來講,之因此不瞭解vertical-align,是由於不清楚對齊後面的這些碎片化知識,而這些也是不少博客在解析的時候經常忽略的地方。

 

先說結論:

1.line-height是行高,主要做用是在文本上下行間距,基於文本產生影響文本元素位置的做用,對於行內元素的位置影響顯著,可是對於塊元素的影響甚微。

 

2.vertical-alignline-height的關係是:line-height是vertical-align的對齊依據。vertical-align主要是影響行內元素的對齊,不影響塊元素佈局

而決定行內元素對齊的有兩個因素,1.元素自己的height(相似於圖片和按鈕等替換元素)2.還有其餘spanem非替換元素的line-height。行框經過計算heightline-height,來將各個行內元素與行內的基線進行對齊。

可是當產生浮動的時候,浮動會對行內元素的佈局產生特殊影響,所以不會按照原先的方式來進行對齊,此時設置了vertical-align每每沒有效果

 

3.圖片的對齊是將本身的底端,也就是圖片的最下端與行框的默認基線進行對齊,對齊依據是底端影響圖片對齊的依據是圖片的heightpaddingborder大小。

而文本元素,例如<span>文本內容</span>,則是將自身的行內框基線與行框基線進行對齊,對齊依據是基線。影響行內文本元素的依據是line-height,以及元素自身的font屬性。

 

4.元素浮動以後其實是從正常的文檔流中除去了(所以會出現高度塌陷,父容器收縮的問題),可是同時又對文檔產生着影響(最經典的就是環繞效果)。元素浮動相似於一個被除名的黑戶,雖然不在土地登記簿上,可是的的確確佔用一塊地方,所以別的元素也不能所以佔據浮動元素的空間,可是由於是黑戶,因此別的元素會環繞它,好像它不存在同樣。

元素浮動以後,會盡力往容器的左右兩側移動,儘量地「漂」到容器的最高處。

 

所以此時行內元素浮動以後,浮動的規則會覆蓋vertical-align的規則,這個時候設置vertical-align每每會出現問題,最典型的就是對一個段落中的圖片進行浮動,而後設置vertical-align,可是發現每每不起做用。

 

可是文本元素浮動以後每每不會受到影響,由於line-height實際上仍是做用於文本元素的,雖然文本元素的容器位置「漂」到其餘位置,可是裏面的文本由於line-height,仍然有行高,能夠影響到行內元素的佈局。

 -------------------------------------------------------------------------------------------------------------------------------------------------

 ------------------------------------------------我是分割線---------------------------------------------------------------------------------------

 -------------------------------------------------------------------------------------------------------------------------------------------------

結論如何推導出來

看完這些結論,想必不少人也是一時之間有些不明白因此然,由於不一樣的人掌握的背景知識是不一樣的,而這些結論的關鍵偏偏是這些關鍵性的碎片化知識,它們起到了穿針引線的做用。下面來梳理一下,究竟是怎麼得出結論的。

 

  -------------------------------------------------------------------------------------------------------------------------------------------------

 ------------------------------------------------我是分割線--------------------------------------------------------------------------------------- 

---------------------------------------------------------------------------------------------------------------------------------------------------

 

1.核心問題:關於對齊

對齊涉及到兩個對象,要對齊元素及對齊對象,一個對象是不可能對齊。好比日常在戰隊,從高往低對齊,每一個人都要有一個參考系,對着參考系進行對齊。

而行內元素的對齊,除了行內元素自己,還有一個參考系,這個參考系就是行框的基線,而行框的基線依據於行內框元素的基線位置。

 

1.1對齊延伸問題:什麼是基線?

每個文本元素自身都會有四條線,頂線,中線,基線,底線。而基線通常是指文本元素中以x字母爲準,x字母的下邊緣爲該文本元素的基線。

而行高則是兩個文本行基線之間的距離,每每使段落產生間距。

可是也能夠這樣理解,行高 = 字體大小 + 上半行距 + 下半行距(其中上下半行距相等,這個等式能夠從圖中推導出來)

 

每個文本元素和文本行元素,都會有一條基線,基線的位置受到文本的字體格式以及line-height的影響。

 

 

1.2對齊延伸問題:什麼是行框和行內框?

 

在每個段落行內,不一樣的行內元素除了包裹自身內容的內容框以外,還會自動生成一個行內框,其中沒有標籤包裹的文本會生成匿名行內框,不一樣的行內框會根據各自不一樣的line-height產生行間距,而行框則會恰好包括最高的頂端和最低的底端,從而來生成行框。

 

 

行內框的基線很好計算,可是行框的基線如何計算呢?

行框的基線是立足於行內框中基線最低的元素,也就是line-height最大的文本元素

 

 下面的例子,能夠測試出來,當設置其中一個行內文本元素的line-height超過其餘行內元素的line-height的時候,整個容器會自動擴展,位置也會往下移動。

<!DOCTYPE html>

<html lang="zh-cn">

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<title>測試行框基線</title>

<style>

p{border:1px solid red;line-height:20px;}

span{line-height:40px;} /*能夠在瀏覽器中取消一下,觀察一下位置變更*/

</style>

</head>

<body>

<p>

<span>文本內容1</span>   匿名文本內容    <em>文本內容2</em>   <img src="" alt="">

</p>

</body>

</html>

  

 

 

1.3對齊延伸問題:什麼是替換元素。

替換元素是指元素的內容自己並不是文檔直接表現的,換句話說,就是不一樣的頁面中,瀏覽器不能肯定其具體內容的元素,好比圖片,按鈕,由於圖片的內容取決於圖片引用的src屬性源,按鈕的類型則依據於其input類型,所以瀏覽器是不能肯定今天img元素裏面是一張美女圖片,那麼明天加載的頁面裏面img是否是一張美女圖片。

 

除了替換元素,其餘的元素就是非替換元素。非替換元素和替換元素在行框中的影響,主要是其高度計算方式,替換元素在行框中的位置是由其heightpaddingborder來決定,而非替換元素在行框中的位置則是其line-height和字體樣式。

 

 

1.4對齊延伸問題:圖片等替換元素在行框中有什麼影響。

若是隻有文本元素的話,那麼行框是很好計算基線位置的,可是若是有圖片按鈕等替換元素的話,那麼計算方式就會變的稍微複雜一些。

css中,有兩種高度方式,一種是height,一種是line-height,這兩種會決定元素的高度和位置,對於圖片等行內替換元素來講,height是行框計算的依據,line-height對圖片、按鈕不會產生影響。

所以,若是有圖片在行內的話,那麼圖片的底端會對齊文本的基線。

 

那麼,若是圖片的高度高於其餘行內框的總體高度,這個時候會發生什麼呢?

 

圖片會在對齊原來的行框文本基線的基礎上,撐開高度,使行框最高點恰好包括圖片的頂端。

所以,當p段落裏面的line-height都是40px的時候,加入圖片以後,行框的高度就會比沒有加入圖片以前多50px - 40px=10px高度,所以基線就會下移10px的高度。

<p style=」line-height:40px;」>

<span>文本內容1</span> <em>文本內容2</em> <img src="img/img2.png" height="50px" width="50px" alt="高度圖片">

</p>

 

 

1.5對齊延伸問題:浮動對行內元素產生了什麼樣的影響。

設置一個元素的浮動以後,元素會從正常的文檔流中去除,可是同時也會對原來的文檔流產生一些影響。

 

能夠設想一下,在長方形區域的水面上,有不少人都想要有一個固定位置的水牀(瀏覽器盒模型佈局),可是固定水牀須要登記(告訴瀏覽器的如何佈局計算)。忽然有一天,有一我的想要在長方形區域的最左側建一個水牀(設置元素左浮動),它悄悄地從水底移動到最左側,把原先的水牀擠走(浮動元素會盡量移動在到容器最高處,及最左處或最右處),在最左側那裏建了一所水牀,沒有登記(沒有告知父容器高度,所以產生高度塌陷)。其餘的人不知道,在去最左端的固定水牀的時候,發現已經有人固定了,所以只能固定在它旁邊(浮動會產生環繞效果,而這一點就是由於浮動元素從正常文檔流中去除掉的緣由)。

 

圖片是屬於替換元素,在行框中的計算中,是依據於圖片的高度,若是圖片進行浮動的話,對於行框來講,圖片不存在了,所以,行框仍是依據原來的文本行基線來計算基線,進行對齊。

 

所以,效果以下

<p style=」line-height:40px;」>

<span>文本內容1</span> <em>文本內容2</em> <img src="img/img2.png" height="100px" width="100px" alt="高度圖片">

</p>

  

圖片沒有浮動:

 

圖片左浮動:

 

 

沒有圖片:

 

 

2.對齊的過程

 

行內元素是默認設置的vertical-alignbaseline,也就是基線對齊。當一個文本行開始渲染的時候,

1.首先瀏覽器會找出每個元素的類型,是替換元素仍是非替換元素

2.而後根據它們的height或者line-height以及字體大小來生成每一個元素行內框

3.肯定行內框基線位置,肯定行框基線位置

4.根據每一個元素是否設置vertical-align來進行對齊。

 

3.關於居中對齊

vertical-alignmiddle是將元素行內框的中點與父元素基線上方0.5ex處的一個點對齊,這裏的1ex相對於元素的font-size來計算x字母的高度,1ex等於該字體下x的字母高度。

多數瀏覽器會將1ex處理爲0.5em,也就是0.5倍字體大小font-size

 

 

 參考文檔:

《css權威指南》

張鑫旭文章:《css行高line-height的一些深刻理解及應用

 

原創文章,轉載請註明地址!!!

相關文章
相關標籤/搜索