天天看點

vertical-align屬性一、為什麼要寫這篇文章二、vertical-align幹什麼的?三、baseline四、vertical-align基于baseline的不同取值五、vertical-align基于line box的不同取值六、inline元素下方可能會有一點空隙七、vertical-align:middle讓元素下移而不居中的問題分析八、其他應用

一、為什麼要寫這篇文章

今天看到一個問題:

兩個div 都設定 display:inline-block,正常顯示;但是在第二個div中加一個塊級元素或者内聯元素,顯示就變了個樣,為什麼?

vertical-align屬性一、為什麼要寫這篇文章二、vertical-align幹什麼的?三、baseline四、vertical-align基于baseline的不同取值五、vertical-align基于line box的不同取值六、inline元素下方可能會有一點空隙七、vertical-align:middle讓元素下移而不居中的問題分析八、其他應用
<meta charset="utf-8"/>
<style>
div{
    width: 100px;
    height: 100px;
    border:1px solid red;
    display: inline-block;
}
.align{
/*    vertical-align: top;*/
}
</style>
<body>
    <div>
    </div>
    <div class="align">為什麼?</div>
</body>      
vertical-align屬性一、為什麼要寫這篇文章二、vertical-align幹什麼的?三、baseline四、vertical-align基于baseline的不同取值五、vertical-align基于line box的不同取值六、inline元素下方可能會有一點空隙七、vertical-align:middle讓元素下移而不居中的問題分析八、其他應用
vertical-align屬性一、為什麼要寫這篇文章二、vertical-align幹什麼的?三、baseline四、vertical-align基于baseline的不同取值五、vertical-align基于line box的不同取值六、inline元素下方可能會有一點空隙七、vertical-align:middle讓元素下移而不居中的問題分析八、其他應用

解決方案就是給第二個div加上:vertical-align:top。

關于vertical-align和基線我知道一點,但是這個問題我沒能答出,是以學習總結分享一下。

二、vertical-align幹什麼的?

w3c有一段相關資訊如下:

vertical-align屬性一、為什麼要寫這篇文章二、vertical-align幹什麼的?三、baseline四、vertical-align基于baseline的不同取值五、vertical-align基于line box的不同取值六、inline元素下方可能會有一點空隙七、vertical-align:middle讓元素下移而不居中的問題分析八、其他應用
'vertical-align'
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> and <length> the absolute length, otherwise as specified      
vertical-align屬性一、為什麼要寫這篇文章二、vertical-align幹什麼的?三、baseline四、vertical-align基于baseline的不同取值五、vertical-align基于line box的不同取值六、inline元素下方可能會有一點空隙七、vertical-align:middle讓元素下移而不居中的問題分析八、其他應用

可以看到vertical-align影響inline-level元素和table-cell元素垂直方向上的布局。根據MDN描述,vertical-align對::first-letter和::first-line同樣适用。

适用于:

inline水準的元素

  • inline:<img>,<span>,<strong>,<em>,未知元素
  • inline-block:<input>(IE8+),<button><IE8+>....

'table-cell'元素

  • table-cell:<td>

是以預設情況下,圖檔,按鈕,文字和單元格都可以用vertical-align屬性。

取值:

vertical-align: baseline|length|percentage|sub|super|top|middle|bottom|text-top|text-bottom|initial|inherit;      

三、baseline

1、字母‘x’與baseline

 字母x的下邊緣(線)就是基線。不是字母

s

之類下面有尾巴的字母

vertical-align屬性一、為什麼要寫這篇文章二、vertical-align幹什麼的?三、baseline四、vertical-align基于baseline的不同取值五、vertical-align基于line box的不同取值六、inline元素下方可能會有一點空隙七、vertical-align:middle讓元素下移而不居中的問題分析八、其他應用

基線甚至衍生出了:

  1. “alphabetic” baseline: “字母”基線 – 英文
  2. “hanging” baseline: “懸挂”基線 – 印度文
  3. “ideographic” baseline: “表意”基線 – 中文
vertical-align屬性一、為什麼要寫這篇文章二、vertical-align幹什麼的?三、baseline四、vertical-align基于baseline的不同取值五、vertical-align基于line box的不同取值六、inline元素下方可能會有一點空隙七、vertical-align:middle讓元素下移而不居中的問題分析八、其他應用

2、baseline的确定規則

1、inline-table元素的baseline是它的table第一行的baseline。

2、父元素【line box】的baseline是最後一個inline box 的baseline。 

3、inline-block元素的baseline确定規則

  • 規則1:inline-block元素,如果内部有line box,則inline-block元素的baseline就是最後一個作為内容存在的元素[inline box]的baseline,而這個元素的baseline的确定就要根據它自身來定了。
  • 規則2:inline-block元素,如果其内部沒有line box或它的overflow屬性不是visible,那麼baseline将是這個inline-block元素的底margin邊界。

3、例子:inline-block例子

vertical-align屬性一、為什麼要寫這篇文章二、vertical-align幹什麼的?三、baseline四、vertical-align基于baseline的不同取值五、vertical-align基于line box的不同取值六、inline元素下方可能會有一點空隙七、vertical-align:middle讓元素下移而不居中的問題分析八、其他應用

上圖描述:

上圖中從左到右都是line-block元素,紅線代表margin-box的邊界,藍線代表baseline;黃色為border,綠色為padding,藍色為content。

左邊元素包含着沒有脫離正常流的内容c,中間元素除了沒有脫離正常流的内容c外還增加了overflow:hidden,右邊元素沒有内容,但是内容區有寬高。

分析圖中各種情況inline-block元素的baseline:

上圖左圖,inline-block元素有處于正常流的内容,根據規則1,是以inline-block的baseline就是最後一個作為内容存在的元素的baseline,也就是内容c的baseline,而c的baseline根據自身定,就是圖中藍色。

上圖中圖,inline-block元素overflow:hidden不為visible,根據規則2,該inline-block元素baseline就是inline-block元素的margin-box的下邊界了,即圖中藍線。

上圖右圖,inline-block元素沒有内容,根據規則2,是以其baseline為margin-box的下邊界,即藍線。

4、例子:baseline确定規則例子 

舉例:

vertical-align屬性一、為什麼要寫這篇文章二、vertical-align幹什麼的?三、baseline四、vertical-align基于baseline的不同取值五、vertical-align基于line box的不同取值六、inline元素下方可能會有一點空隙七、vertical-align:middle讓元素下移而不居中的問題分析八、其他應用

 View Code

vertical-align屬性一、為什麼要寫這篇文章二、vertical-align幹什麼的?三、baseline四、vertical-align基于baseline的不同取值五、vertical-align基于line box的不同取值六、inline元素下方可能會有一點空隙七、vertical-align:middle讓元素下移而不居中的問題分析八、其他應用

分析:

父元素.ctn-block的base-line是Gg的baseline,

inline-block元素因為沒有内部line box,也沒有設定overflow:visible,是以其baseline是底margin邊界。

四、vertical-align基于baseline的不同取值

1、baseline

将子元素盒子的baseline與父盒子的baseline對齊。

vertical-align屬性一、為什麼要寫這篇文章二、vertical-align幹什麼的?三、baseline四、vertical-align基于baseline的不同取值五、vertical-align基于line box的不同取值六、inline元素下方可能會有一點空隙七、vertical-align:middle讓元素下移而不居中的問題分析八、其他應用

2、middle

将元素盒子的垂直中點與父盒子的baseline加上父盒子的x-height的一半位置對齊

這裡元素盒子的垂直中點容易确定,父盒子的baseline也好确定,但是x-height要進行計算得到,這個x-height就是字母x的高度。

vertical-align屬性一、為什麼要寫這篇文章二、vertical-align幹什麼的?三、baseline四、vertical-align基于baseline的不同取值五、vertical-align基于line box的不同取值六、inline元素下方可能會有一點空隙七、vertical-align:middle讓元素下移而不居中的問題分析八、其他應用

3、text-top

将盒子的頂端(margin-top邊界)與父盒子的文本區域頂端對齊

審查盒子看到margin-top的頂端。

vertical-align屬性一、為什麼要寫這篇文章二、vertical-align幹什麼的?三、baseline四、vertical-align基于baseline的不同取值五、vertical-align基于line box的不同取值六、inline元素下方可能會有一點空隙七、vertical-align:middle讓元素下移而不居中的問題分析八、其他應用

審查文本,看到藍色區域的上邊界就是文本區域頂端。

vertical-align屬性一、為什麼要寫這篇文章二、vertical-align幹什麼的?三、baseline四、vertical-align基于baseline的不同取值五、vertical-align基于line box的不同取值六、inline元素下方可能會有一點空隙七、vertical-align:middle讓元素下移而不居中的問題分析八、其他應用

最終效果就是盒子的頂端與父盒子文本區域頂端對齊。

4、text-bottom

将盒子的底端(margin-bottom邊界) 與父盒子的文本區域底端對齊

和text-top類似,不過将子元素的margin-bottom和文本區域的下邊界對齊。

vertical-align屬性一、為什麼要寫這篇文章二、vertical-align幹什麼的?三、baseline四、vertical-align基于baseline的不同取值五、vertical-align基于line box的不同取值六、inline元素下方可能會有一點空隙七、vertical-align:middle讓元素下移而不居中的問題分析八、其他應用

5、sub

将子元素盒子的baseline降低,到适當的父盒子的下标位置

子元素的baseline已經确定了,就是margin-bottom下邊界,但是父盒子的下标位置太不好了解。。。首先需要了解下标這個概念,我們可以通過<sub>标簽為文字添加下标,将<span>中的内容修改為Gg<sub>Gg</sub>,就會有如下效果。

vertical-align屬性一、為什麼要寫這篇文章二、vertical-align幹什麼的?三、baseline四、vertical-align基于baseline的不同取值五、vertical-align基于line box的不同取值六、inline元素下方可能會有一點空隙七、vertical-align:middle讓元素下移而不居中的問題分析八、其他應用
vertical-align屬性一、為什麼要寫這篇文章二、vertical-align幹什麼的?三、baseline四、vertical-align基于baseline的不同取值五、vertical-align基于line box的不同取值六、inline元素下方可能會有一點空隙七、vertical-align:middle讓元素下移而不居中的問題分析八、其他應用

這裡就是将元素的margin-bottom下邊界和下标的baseline對齊。

6、super

将元素盒子的baseline升高,到适當的父盒子的上标位置。

與sub對應,super提升到上标内容的baseline處,首先通過<sup>标簽建立上标。

vertical-align屬性一、為什麼要寫這篇文章二、vertical-align幹什麼的?三、baseline四、vertical-align基于baseline的不同取值五、vertical-align基于line box的不同取值六、inline元素下方可能會有一點空隙七、vertical-align:middle讓元素下移而不居中的問題分析八、其他應用
vertical-align屬性一、為什麼要寫這篇文章二、vertical-align幹什麼的?三、baseline四、vertical-align基于baseline的不同取值五、vertical-align基于line box的不同取值六、inline元素下方可能會有一點空隙七、vertical-align:middle讓元素下移而不居中的問題分析八、其他應用

7、percentage

百分比:升高(正值)或降低(負值)子元素盒子,具體的升高/降低數值由父盒子的line-height的值乘以百分比計算得出。如果百分比為0%,就和vertical-align:baseline一樣。

這個是相當好了解的,就相當于子元素盒子的baseline升高或降低,具體數值為百分比乘以父盒子的line-height。

本例中,父盒子的line-height為200px,是以設定25%,元素應該上移50px。

vertical-align屬性一、為什麼要寫這篇文章二、vertical-align幹什麼的?三、baseline四、vertical-align基于baseline的不同取值五、vertical-align基于line box的不同取值六、inline元素下方可能會有一點空隙七、vertical-align:middle讓元素下移而不居中的問題分析八、其他應用

并不是很直覺,給它加上一個transform: translate(0, 50px);【相對下移50px】,它又移到那個熟悉的位置了。

vertical-align屬性一、為什麼要寫這篇文章二、vertical-align幹什麼的?三、baseline四、vertical-align基于baseline的不同取值五、vertical-align基于line box的不同取值六、inline元素下方可能會有一點空隙七、vertical-align:middle讓元素下移而不居中的問題分析八、其他應用

8、length

升高(正值)或降低(負值)子元素盒子。值為升高/降低的距離,如果為0,和vertical-align:baseline一樣。

以我們最常用的px作為機關,設定vertical-align:50px,效果就和上面百分比為25%(200px*25%=50px)一樣了,不做例子了。

五、vertical-align基于line box的不同取值

當vertical-align設定為top和bottom時,其就不是按照baseline進行定位了,而是根據line box進行定位。子元素盒子的頂部和底部也就是其上下margin外邊界。

1、top

将子元素盒子的頂部和其所在的line box頂部對齊

由于vertical-align:top将會讓子元素盒子頂部與line box頂部對齊,而如果line box高度小于子元素高度,line box将會被撐開。我們先用一個高度較高的元素撐開line box,然後看看效果:

vertical-align屬性一、為什麼要寫這篇文章二、vertical-align幹什麼的?三、baseline四、vertical-align基于baseline的不同取值五、vertical-align基于line box的不同取值六、inline元素下方可能會有一點空隙七、vertical-align:middle讓元素下移而不居中的問題分析八、其他應用

可以看到,big子元素撐開了line box,而child1的margin-top外邊界緊貼在line box的頂端。

2、bottom

将子元素盒子的底部和其所在的line box底部對齊

和top類似,由于big用于撐開line box,可以不必修改其vertical-align的值,僅修改child1為vertical-align:bottom,效果:

vertical-align屬性一、為什麼要寫這篇文章二、vertical-align幹什麼的?三、baseline四、vertical-align基于baseline的不同取值五、vertical-align基于line box的不同取值六、inline元素下方可能會有一點空隙七、vertical-align:middle讓元素下移而不居中的問題分析八、其他應用

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

例子:嘗試将li元素在垂直方向上進行對齊的話,這個現象非常常見

vertical-align屬性一、為什麼要寫這篇文章二、vertical-align幹什麼的?三、baseline四、vertical-align基于baseline的不同取值五、vertical-align基于line box的不同取值六、inline元素下方可能會有一點空隙七、vertical-align:middle讓元素下移而不居中的問題分析八、其他應用
<!doctype html>
<html >
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style type="text/css">
        ul{
            background-color: bisque;
        }
        .box { display: inline-block;
            width: 100px;
            height: 100px;
            background-color: aliceblue;
            /*     vertical-align: middle;*/
        }
    </style>

</head>
<body>

<ul>
    <li class="box"></li>
    <li class="box"></li>
    <li class="box"></li>
</ul>
</body>
</html>      
vertical-align屬性一、為什麼要寫這篇文章二、vertical-align幹什麼的?三、baseline四、vertical-align基于baseline的不同取值五、vertical-align基于line box的不同取值六、inline元素下方可能會有一點空隙七、vertical-align:middle讓元素下移而不居中的問題分析八、其他應用

1、垂直空隙

vertical-align屬性一、為什麼要寫這篇文章二、vertical-align幹什麼的?三、baseline四、vertical-align基于baseline的不同取值五、vertical-align基于line box的不同取值六、inline元素下方可能會有一點空隙七、vertical-align:middle讓元素下移而不居中的問題分析八、其他應用

因為li元素預設vertical-align:baseline,而baseline的下方會給字母的一部分留出空間,是以會産生一個空隙,要産生理想的效果,解決方案就是改變line box的baseline位置,比如将這些li設定為vertical-align:middle。【tip:加一個x效果更明顯】

vertical-align屬性一、為什麼要寫這篇文章二、vertical-align幹什麼的?三、baseline四、vertical-align基于baseline的不同取值五、vertical-align基于line box的不同取值六、inline元素下方可能會有一點空隙七、vertical-align:middle讓元素下移而不居中的問題分析八、其他應用

2、水準空隙

li元素的水準空隙是因為換行引起的,這個換行會變成一個空白,這個空白會被解析為DOM中的文本節點。比如像下面醬紫的代碼。

<ul>
  <li class="box"></li><li class="box"></li>
  <li class="box"></li>
</ul>      

效果如下:因為前2個li之間沒有空白,而2和3個li之間有空白。

vertical-align屬性一、為什麼要寫這篇文章二、vertical-align幹什麼的?三、baseline四、vertical-align基于baseline的不同取值五、vertical-align基于line box的不同取值六、inline元素下方可能會有一點空隙七、vertical-align:middle讓元素下移而不居中的問題分析八、其他應用

但是上面的代碼可讀性太差,也不美觀,一般這樣寫

<ul>
        <li class="box"></li><!-- 注釋去空格
     --><li class="box"></li>
        <li class="box"></li>
    </ul>      

我們用一個注釋節點代替空白(文本節點),而注釋節點渲染的時候是不渲染的。了解更多DOM中的節點類型,可看我的另一篇文章《DOM》。

七、vertical-align:middle讓元素下移而不居中的問題分析

1、問題

現在有三個inline-box塊,高度分别為100px,200px,300px,想讓高度為100px的塊垂直居中,于是寫出了如下代碼:

vertical-align屬性一、為什麼要寫這篇文章二、vertical-align幹什麼的?三、baseline四、vertical-align基于baseline的不同取值五、vertical-align基于line box的不同取值六、inline元素下方可能會有一點空隙七、vertical-align:middle讓元素下移而不居中的問題分析八、其他應用

 View Code

vertical-align屬性一、為什麼要寫這篇文章二、vertical-align幹什麼的?三、baseline四、vertical-align基于baseline的不同取值五、vertical-align基于line box的不同取值六、inline元素下方可能會有一點空隙七、vertical-align:middle讓元素下移而不居中的問題分析八、其他應用
vertical-align屬性一、為什麼要寫這篇文章二、vertical-align幹什麼的?三、baseline四、vertical-align基于baseline的不同取值五、vertical-align基于line box的不同取值六、inline元素下方可能會有一點空隙七、vertical-align:middle讓元素下移而不居中的問題分析八、其他應用

給中間div加上vertical-align:middle,效果變為上圖二的樣子——child-1元素下移了,但是卻沒有居中。

2、原因

從上面可以指定,vertical-align:middle的定位方式是:将子元素盒子的垂直中點與父盒子的baseline加上父盒子的x-height的一半位置對齊。

子元素盒子的中點很好算,而父盒子的baseline加上父盒子的x-height一半位置又是什麼呢?

首先計算父盒子的baseline:三個子元素的baseline走在一條直線上,就是child-2和child-3的底部。

然後加上父盒子的x-height:由于chrome下預設font-size是16px,而font-family:sans-serif,是以x-height的一半大概是3-4px,綜上,按照如下方式對齊:

vertical-align屬性一、為什麼要寫這篇文章二、vertical-align幹什麼的?三、baseline四、vertical-align基于baseline的不同取值五、vertical-align基于line box的不同取值六、inline元素下方可能會有一點空隙七、vertical-align:middle讓元素下移而不居中的問題分析八、其他應用

3、 解決方案

 一種方式是将最高的元素設為vertical-align:middle。

然後将想要居中的也設定為vertical-align:middle,其他的根據需要設定vertical-align:top/bottom。

原理有點抽象:

首先明确一點:最高元素設定為vertical-align:middle後,這個元素對于line box來說,baseline就是其中線。

其他元素設定vertical-align:top/bottom後,它們不影響line box的baseline,是以再将需要設定垂直居中的元素也設定為vertical-align:middle,它們的baseline必然在最高元素的baseline之上,是以會會被強制下移,進行居中。

vertical-align屬性一、為什麼要寫這篇文章二、vertical-align幹什麼的?三、baseline四、vertical-align基于baseline的不同取值五、vertical-align基于line box的不同取值六、inline元素下方可能會有一點空隙七、vertical-align:middle讓元素下移而不居中的問題分析八、其他應用
.ctn-block .child-1 {
        height: 100px;
        vertical-align: middle;
    }
    .ctn-block .child-2 {
        height: 200px;
        vertical-align:top;
    }
    .ctn-block .child-3 {
        height: 300px;
        vertical-align: middle;
    }      
vertical-align屬性一、為什麼要寫這篇文章二、vertical-align幹什麼的?三、baseline四、vertical-align基于baseline的不同取值五、vertical-align基于line box的不同取值六、inline元素下方可能會有一點空隙七、vertical-align:middle讓元素下移而不居中的問題分析八、其他應用
vertical-align屬性一、為什麼要寫這篇文章二、vertical-align幹什麼的?三、baseline四、vertical-align基于baseline的不同取值五、vertical-align基于line box的不同取值六、inline元素下方可能會有一點空隙七、vertical-align:middle讓元素下移而不居中的問題分析八、其他應用

4、衍生的一種可行的垂直居中方案

為父元素設定一個僞元素::after,其高度為父元素的高度,display:inline-block,将其設定為vertical-align:middle即可撐開line box,同時line box的baseline為父元素高度一半的位置。然後設定子元素vertical-align:middle,即可實作居中。

考慮相容性的話,這裡需要使用一些hack,由于IE8不支援::after僞元素,是以需要一個span來替代。而display:inline-block亦需要hack。

我的《未知寬高圖檔垂直居中》一文中就用到這種方案。 

八、其他應用

ico和文字對齊 

vertical-align屬性一、為什麼要寫這篇文章二、vertical-align幹什麼的?三、baseline四、vertical-align基于baseline的不同取值五、vertical-align基于line box的不同取值六、inline元素下方可能會有一點空隙七、vertical-align:middle讓元素下移而不居中的問題分析八、其他應用

 View Code

vertical-align屬性一、為什麼要寫這篇文章二、vertical-align幹什麼的?三、baseline四、vertical-align基于baseline的不同取值五、vertical-align基于line box的不同取值六、inline元素下方可能會有一點空隙七、vertical-align:middle讓元素下移而不居中的問題分析八、其他應用

我想讓左邊ico和文字,按鈕都對齊。

.pop-viphead-nologin-icon,.pop-viphead-nologin-txt,.pop-viphead-nologin-btn{
        vertical-align: middle;
    }      
vertical-align屬性一、為什麼要寫這篇文章二、vertical-align幹什麼的?三、baseline四、vertical-align基于baseline的不同取值五、vertical-align基于line box的不同取值六、inline元素下方可能會有一點空隙七、vertical-align:middle讓元素下移而不居中的問題分析八、其他應用