您的位置:首页 > 其它

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

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

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

<!--css-->

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

<!--html-->

<div class='div1'>

    <div class='div2'>abc</div>

    <div class='div2'></div>

</div>

效果是这样的:



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



可以看到,没有内容的div与父div底边会有一定的间距。这是为什么呢?
其实,这是因为display:inline-block和vertical-align:baseline。
首先,当我们在一个大div中(以后简称大div),放置若干小div(以后简称小div),同时设置这些小div为display:inline-block的时候,浏览器会对每一个小div进行垂直方向的对齐,对齐方式取决于每个小div的vertical-align属性。而默认的vertical-align属性的值就是baseline。baseline是基线,这里我们认为它是水平贯穿div、竖直位置确定的一条横线就行。浏览器会将小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的基线是不是重合,我们放大看一下:



果然,右边div的底边和左边的字母a的底边同在一条水平线上。而字母a的底边正是这段文字baseline的位置,也就是左边div的baseline。
————————————————分割线——————————
但是,有一种情况下,即使小div内有文字内容,也不会将内部文字的baseline作为自己的baseline,而是仍然把底边作为baseline。我们看下面这个例子:

例子2:

<div>
<div style="background-color: red;">
   <div style="display: inline-block;background: blue">aaa</div>
<div style="display: inline-block;background-color: gray;">
       <div style="float: left">aaa</div>
</div>
</div>
</div>

效果:



灰色的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 style="background-color: red;font-size: 60px;font-family: fantasy;line-height: 80px;">
<div style="display: inline-block;background-color: blue;padding: 0;margin: 0;width: 30px;height: 30px;"></div>

</div>

将上面代码中外部的div字体、字号、行高改变,会改变内部div的竖直位置。
——————————————————————分割线-----------------------------------------------------------------------
最后,我们再研究一下vertical-align属性,以解决文章开始提出的问题。已经说过,vertical-align默认的是baseline,也就是把小div的baseline都对齐到大div的baseline上。根据下图:



我们可以看到,与baseline会比文字底部高一点不同,文字的顶端就是top这条线,当小div内没有文字时,小div的top就是小div的顶部,而大div的顶端就是文字的顶端,因此我们设置vertical-align:top可以让小div顶端对齐到大div顶端。而大小div的字体行高都相同,因此高度相同,上下边能够重叠。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: