inline-block元素与父div底边之间的间距问题(inline-block与vertical-align:baseline)

在一些情况下,inline-block的元素距离父div底边会有距离,让我们看一下例子:

例子1,两个inline-block元素,设定了固定的宽高,第一个有文字,第二个没有文字:

 

.div1{
   background-color: red;
   color: white;
}
.div2{
   background-color: blue;
   display: inline-block;
   width: 30px;
   height: 20px;
}

 


   
abc

   

效果是这样的:

而且,即使我们去掉左边的小div,空div的底边与父div的底边还是有距离,如图


可以看到,没有内容的div与父div底边会有一定的间距。这是为什么呢?

其实,这是因为display:inline-block和vertical-align:baseline。

首先,当我们在一个大div中(以后简称大div),放置若干小div(以后简称小div),同时设置这些小div为display:inline-block(或inline)的时候,浏览器会对每一个小div进行垂直方向的对齐,对齐方式取决于每个小div的vertical-align属性。vertical-align属性是指行内元素在垂直上的对齐方式,其常用的值有top、bottom、middle、baseline等等,如果选择top,则表示将该元素的顶端与line-box的顶端对齐(至于line-box,是指同在一行内的内联元素共同构成的区域。在一行内,各个元素站的参差不齐,有的高,有的低,最高的那个的头顶就是line-box的顶端,最低的那个的脚就是line-box的底端)。vertical-align:bottom同理,即底端于line-box底端对齐,baseline则是将该元素baseline与父元素baseline对齐。而默认的vertical-align属性的值就是baseline。baseline是基线,这里先认为它是水平贯穿元素、竖直位置确定的一条横线就行。浏览器会将小div的baseline和大div的baseline对齐(重叠到一起),使得若干小div对齐。换句话说,就是大div有自己的baseline这么一条线,每个小div也都有,然后依次把每个小div的baseline和大div的baseline对齐,这样就对齐了这些小div。

问题就来了,即使小div宽高都一致,但是如果不同的小div的baseline位置不同,比如小div1的baseline在顶部,而小div2的baseline在底部,那两个小div不就对不齐了吗?正是如此。这就是文章一开始说的问题。

 

我们先来了解一下baseline这个东西,什么是baseline呢?baseline是用来确定文字垂直位置的一条线。见下图:

 

 

注意:字母的底部并不都是贴着baseline上面的,有些字母,比如图中的p,会向下超出一点,类似的,字母j,g等也会超出一点。

注意:baseline这个东西,有的文章上说只有内联元素(也叫行内元素、inline-box)有,块级元素(也加line-box)没有;实际上这个说法不准确。baseline是用来对齐文字的,块级元素实际上也有baseline,只是baseline对内联元素和块级元素的影响不同:浏览器默认的vertical-align属性的值是baseline。对于内联元素来说,vertical-align属性有用,baseline会影响到元素在竖直方向的位置;而对块级元素来说,vertical-align属性没用,因此对位置没有影响。

我们可以先看一下什么是内联元素,什么是块级元素:

详情可以点这里:http://www.cnblogs.com/xiepeixing/p/4334501.html。简单地说,内联元素就是display:inline或display:inline-block的元素(这里说的可能不全,display还有很多其他属性,但此处我们只要知道display:inline-block是内联元素即可) ,内联元素可以和其他元素排列在一行。而块级元素是display:block的元素,独占一行(除非设置了float)。比如默认情况下div就是块级元素(浏览器默认div的display属性是block),span、a都是内联元素(浏览器默认span、a的display属性是inline)。因此如果不给一个div设置任何样式,那div默认的display就是block,是一个块级元素。因此,baseline在哪里,对于display:block的div的位置没有影响。

——————————————————分割线——————————————————————

好了,了解了baseline,我们继续往下说,小div的baseline位置不同会导致小div对不齐。当小div内有文字时,小div的baseline就是这段文字的baseline,而文字的baseline取决于文字的font-family、font-size、line-height三个属性。而当小div没有文字时,小div的baseline就是该div的底边。(注意,小div是inline-block元素)。

 

对于块级div,没有文字时,baseline也不是底边。当块级div内部含有内联元素时,不论块级div内部有没有文字,该块级div会根据font-size、font-family、line-height来确定baseline位置(就像小div有文字时那样)。而且上文说了,baseline不是文字的最底部,而是文字底部向上一些的位置,而大div底部就是文字的底部,因此大div的baseline会比div的底边靠上。

 

 

因此,当小div的baseline在各自div的位置不同时,就会出现如文章一开始给出的例子:

右边的小div没有内容,因此把底边作为小div的baseline,左边的有内容,因此把左边div的baseline就是文字的baseline,这两个baseline都要和大div的baseline对齐。因此虽然两个小div宽高一样,但是左边的靠下一点,右边的靠上一点。为了验证一下两个小div的基线是不是重合,我们放大看一下:

inline-block元素与父div底边之间的间距问题(inline-block与vertical-align:baseline)_第1张图片

果然,右边div的底边和左边的字母a的底边同在一条水平线上。而字母a的底边正是这段文字baseline的位置,也就是左边div的baseline。

————————————————分割线——————————

但是,有一种情况下,即使小div内有文字内容,也不会将内部文字的baseline作为自己的baseline,而是仍然把底边作为baseline。我们看下面这个例子:

例子2:



   
aaa


       
aaa



效果:

灰色的div和蓝色的div都是inline-block的元素,不同的是蓝色div内直接是文字,而在灰色div内有一个向左浮动的div,在浮动div里有一段文字。由于灰色div内部的div是向左浮动的,而灰色div不浮动,因此浮动的div脱离了文档流,相当于浏览器在绘制灰色div时,灰色div内部是没有内容的,它的baseline仍然是自己的底边。但是灰色div的高度仍然被浮动div撑开了,而不是0.

 

————————————————————分割线——————————————————

刚才我们说到,当块级div内部含有内联元素时,不论块级div内部有没有文字,该块级div会根据font-size、font-family、line-height来确定baseline位置。可以尝试一下:



将上面代码中外部的div字体、字号、行高改变,会改变内部div的竖直位置。

——————————————————————分割线-----------------------------------------------------------------------

最后,我们再研究一下vertical-align属性,以解决文章开始提出的问题。已经说过,vertical-align默认的是baseline,也就是把小div的baseline都对齐到大div的baseline上。根据下图:

我们可以看到,与baseline会比文字底部高一点不同,文字的顶端就是top这条线,当小div内没有文字时,小div的top就是小div的顶部,而大div的顶端就是文字的顶端,因此我们设置vertical-align:top可以让小div顶端对齐到大div顶端。而大小div的字体行高都相同,因此高度相同,上下边能够重叠。

 

你可能感兴趣的:(css,html,web前端)