[翻譯]關於Vertical-Align你須要知道的事情

寫在前面的話

開始學習前端以來,在CSS相關知識當中困擾我最多的就是Vertical-Align這個屬性。在stackoverflow上查找相關問題的時候看到了這篇文章,因而將它翻譯出來,做爲本身的一次學習筆記吧。css

正文

在遇到將元素在垂直方向上對齊的需求時,CSS提供了多種方法,有時候我用float解決,有時候我使用position:absolute解決,還有時候採用的方法是手動調整marginpadding
其實我並不喜歡這些解決方法,float會讓元素的頂端對齊並且須要手動清楚浮動。絕對定位讓元素脫離了正常流,這樣這些元素就不會再影響到周圍的元素。在元素的paddingmargin固定的狀況下,一點小的改變也頗有可能對佈局形成影響。
接下來登場的就是本文的主角了:Vertical-align。一般來講使用這個屬性進行佈局是一種hack行爲,由於它原本並非被用於這個目的。它用在文本和與文本相鄰元素的垂直方向上的對齊問題。然而,你也可使用Vertical-align在不一樣的上下文中對元素進行靈活的,細粒度的排布。元素的尺寸無需知曉,元素任然處於正常流當中,所以元素的變化會影響到周圍的元素,這使得Vertical-align是很是有價值的排布方案的選擇。html

Vertical-align的奇特之處

Vertical-align有時候會變的面目猙獰。它彷佛有一些謎同樣的規則。舉例來講,有時候你改變了Vertical-align的值,可是該元素垂直方向上沒有發生改變反而別的元素改變了位置。
一些資料在談到Vertical-align這個問題的時候深刻程度不夠,特別是當人們想使用這個屬性佈局的時候。這些資料更多的將精力集中在了一個誤區上,就是嘗試將元素內的一切都垂直對齊。他們給出了一下在簡單狀況下的例子來解釋Vertical-align這個屬性而忽略了一些複雜奇怪的方面。前端

使用Vertical-align的要求

Vertical-align被用於垂直對齊inline元素,也就是display值爲inlineinline-block的元素。inline-table的元素不在本文的討論範圍內。
inline元素基本上值得就是文本
inline-block元素就像它的名字同樣,同時具有inline元素和block元素的特色,這樣的元素有padding,margin,border,width,height。其中高度有多是由元素的內容決定的。
inline元素一個挨着一個的擺放在行內,當行內元素太多的狀況下,一個新行會被建立出來,這些行也叫作line--box。它將行內的全部內容都包裹了起來。根據行內內容的不一樣,line-box的尺寸也會不一樣,在接下來的圖裏面,紅線表明了line-box的上下邊界圖片描述
在這些line-box內,Vertical-align屬性負責對齊一些獨立的元素。那麼,這些元素是要和誰對齊呢?ide

關於邊界和baseline

對於垂直對齊這個知識點來講最重要的就是涉及元素的baseline。有時候元素的盒模型的上下邊界也會變的很重要。下面上圖
圖片描述
如圖所示有三行文字。行高的上下邊界是紅線。文字的上下邊界是綠色的線,藍色的線就是baseline了,左邊文字的高度與行高是一致的,所以綠線和紅線重合了,中間的行高是文字大小的兩倍,而在右邊,行高是文字大小的二分之一。
行內元素的外邊緣在行高的上邊緣和下邊緣這個範圍內對齊,若是行高小於文字的高度也無所謂。關於baseline的定義仍是直接給出標準的連接佈局

inline-block元素

圖片描述
從左到右的三幅圖片都是inline-block元素,不一樣的是,左面包含着沒有脫離正常流的內容c,中間的除了沒有脫離正常流的內容之外還加了overflow:hidden,右面的沒有內容可是內容區還有高度。紅線表明了margin-box的邊界。黃色表明的是border,綠色的是padding,藍色的是content,藍色的線表明的仍是baseline。
inline-block元素的外邊緣就是margin-box的邊緣。
inline-block元素的baseline的位置要看該元素有沒有處於正常流以內的內容。
(1)在有處於正常流內容的狀況下,inline-block元素的baseline就是最後一個做爲內容存在的元素的baseline,這個元素的baseline的肯定就要根據他自身來肯定了。
(2)在overflow屬性不爲visible的狀況下,baseline就是margin-box的下邊界了。
(3)第三種狀況下baseline仍是margin-box的下邊界。學習

line-box

圖片描述
關於line-box的圖上面已經給過了,此次我將文字部分高亮顯示。line-box的上邊界與最高元素的上邊界對齊,下邊界與最低元素的下邊界對齊。
W3C標準中並無定義line-box的baseline的位置。這一點很讓人困惑,baseline的位置須要知足vertical-align屬性的值以及讓line-box的高度最小等條件,是一個很靈活的參數。
line-box的baseline是不可見的,可是能夠很輕鬆的將它可視化出來,在行的開頭添加一個字母,好比'x',這個字母的下邊界默認就是baseline的位置。圍繞着baseline在line-box中造成了文字盒。文字盒能夠被認爲是沒有和任何元素對齊的line-box中的inline元素,它的告訴與它的父元素的font-size的值相同。所以,文字盒僅僅包含非格式化的line-box的文本,文字盒的邊界由綠線來表示。由於文字盒是緊挨着baseline的,因此baseline的位置發生變化的話,文字盒的位置也會跟着改變(這裏所說的文字盒在標準中被叫作strut)。
總結起來的話有如下兩點:spa

  • 有一個區域叫作line-box,垂直方向上的對齊都是發生在這個區域裏面,它有baseline,有文字盒,有上下邊界。
  • inline元素也有baseline和上下邊界,inline元素是須要對齊的對象。

Vertical-align屬性的值

圖片描述
有關Vertical-align各個取值的說明讀者仍是上MDN看吧。也能夠看看天鑲大神的博客上的文章.net

Vertical這個屬性究竟是怎麼起做用的呢?

對齊一個Icon

我想將一個icon與文字對齊僅僅使icon的vertical-align屬性的值設置爲middle彷佛不能產生使人滿意的結果,例子以下圖
圖片描述翻譯

<!-- left mark-up -->
<span class="icon middle"></span>
Centered?

<!-- right mark-up -->
<span class="icon middle"></span>
<span class="middle">Centered!</span>

<style type="text/css">
  .icon   { display: inline-block;
            /* size, color, etc. */ }

  .middle { vertical-align: middle; }
</style>

下面給出上圖的輔助線版本
圖片描述
緣由就是左面的文字根本就沒有發生對齊行爲,它仍是對齊於line-box的baseline。而vertical-align對齊的點是baseline加上半個x的距離(half of the x-height)。所以文字的最高點超過了icon的高度。
而右面的例子,文字與icon都對齊於一箇中點,文字的baseline稍微下移,位於line-box的baseline的下方。結果是很好的達到了icon與文字對齊的效果。3d

line-box的baseline的移動問題

這是一個Vertical-align的坑,line-box中的全部元素都會影響到baseline的位置。假設,一個元素按某種方式垂直對齊了,可是這種對齊方式會引發baseline的移動,又由於大部分的垂直對齊方式(除了top和bottom)和baseline有關,所以這個元素的垂直方向對齊的行爲會引發該line-box內其餘元素位置的調整。
下面仍是一些例子

  • 一個很高的元素,其高度佔滿了整個line-box,那麼vertical-align對其實沒有影響的,在它的top和bottom以外沒有空間讓其移動。可是爲了知足它的vertical-align的值,line-box的baseline會發生移動,左面的高元素的取值爲text-bottom,矮元素的取值爲baseline。右面的高元素的取值爲text-top,你會看到baseline跳上去了
    圖片描述
<!-- left mark-up -->
<span class="tall-box text-bottom"></span>
<span class="short-box"></span>

<!-- right mark-up -->
<span class="tall-box text-top"></span>
<span class="short-box"></span>

<style type="text/css">
  .tall-box,
  .short-box   { display: inline-block;
                /* size, color, etc. */ }

  .text-bottom { vertical-align: text-bottom; }
  .text-top    { vertical-align: text-top; }
</style>

若是把高元素的vertical-align設置爲其餘值,也能看到相似的行爲
甚至將vertical-align設置爲bottom或者是top也會讓baseline發生移動。這很奇怪,由於這時候應該就沒baseline什麼事兒了。
圖片描述

<!-- left mark-up -->
<span class="tall-box bottom"></span>
<span class="short-box"></span>

<!-- right mark-up -->
<span class="tall-box top"></span>
<span class="short-box"></span>

<style type="text/css">
  .tall-box,
  .short-box { display: inline-block;
               /* size, color, etc. */ }

  .bottom    { vertical-align: bottom; }
  .top       { vertical-align: top; }
</style>

將兩個更大的元素放在一個line裏面,而且設置vertical-align的值讓line-box的baseline移動。在知足vertical-align數值對齊的條件下,line-box的高度會自我調整,如左面的圖。再增長第三個元素,第三個元素若是由於其vertical-align的設置不會超過line-box的邊緣的話,它是不會影響到line-box的高度和baseline的位置的,若是它會超過line-box的邊緣,那麼line-box的高度和baseline的位置也會進行調整。在第二種狀況下,另外兩個元素的位置發生了下移。
圖片描述

<!-- left mark-up -->
<span class="tall-box text-bottom"></span>
<span class="tall-box text-top"></span>

<!-- mark-up in the middle -->
<span class="tall-box text-bottom"></span>
<span class="tall-box text-top"></span>
<span class="tall-box middle"></span>

<!-- right mark-up -->
<span class="tall-box text-bottom"></span>
<span class="tall-box text-top"></span>
<span class="tall-box text-100up"></span>

<style type="text/css">
  .tall-box    { display: inline-block;
                 /* size, color, etc. */ }

  .middle      { vertical-align: middle; }
  .text-top    { vertical-align: text-top; }
  .text-bottom { vertical-align: text-bottom; }
  .text-100up  { vertical-align: 100%; }
</style>

inline元素下方可能會有一點空隙

下面給出一個例子,若是嘗試將li元素在垂直方向上進行對齊的話在,這個現象很是常見。
圖片描述



<ul> <li class="box"></li> <li class="box"></li> <li class="box"></li> </ul> <style type="text/css"> .box { display: inline-block; /* size, color, etc. */ } </style>

正如你所見,li元素是對齊baseline的,baseline的下方會給字母的一部分留出空間,所以會產生一個空隙。解決方案就是改變line-box的baseline的位置,好比將這些li這是爲vertical-align:middle



<ul> <li class="box middle"></li> <li class="box middle"></li> <li class="box middle"></li> </ul> <style type="text/css"> .box { display: inline-block; /* size, color, etc. */ } .middle { vertical-align: middle; } </style>

inline元素之間的空隙形成佈局效果與理想狀態發生誤差
這主要是由於inline元素自己的緣由,可是由於若是要讓vertical-align的值產生做用的話,inline元素是必備要求,所以瞭解一點也不錯嘛
這個空隙來源於inline元素之間的空格,全部的inline元素之間的空白都會變成一個空格。若是你想讓inline元素在水平上緊挨着,設置它們的寬度是不行的。由於之間存在空隙,因此行的寬度不夠放下兩個inline元素。一行會被破壞爲兩行。解決方案以下圖的右側
圖片描述

<!-- left mark-up -->


<div class="half">50% wide</div>




<div class="half">50% wide... and in next line</div>


<!-- right mark-up -->


<div class="half">50% wide</div>

<!--
-->

<div class="half">50% wide</div>


<style type="text/css">
  .half { display: inline-block;
          width: 50%; }
</style>

注意

兩個建議,若是vertical-align屬性不起做用,那麼問問本身:

  • line-box的上下邊緣以及baseline的位置在哪裏?
  • inline元素的上下邊緣以及baseline的位置在哪裏?
相關文章
相關標籤/搜索