行块级元素的那些事儿

在写项目的时候,我们难免会把一个元素声明为display: inline-block,inline-block 元素既具有 block 元素可以定义宽高的特性,同时又具有 inline 元素默认不换行的特性。它也可以设置 vertical-align(这个属性只对设置了inline-block的元素有效)属性,如果这时候加上overflow: hidden,这可能会引发一个对齐问题,这正是本文要探讨的主要问题。

注意:HTML 中的换行符、空格符、制表符等合并为空白符,字体大小不为 0 的情况下,空白符占据一定的宽度,这时 inline-block 元素之间会产生空隙。

发现问题

其实之前做项目就发现多个内联元素同行显示时就有间隙的问题,不同浏览器间距大小还不同,不过这有很多方法解决,这里就不一一赘述了。

今天在修改按钮样式时就发现一个异常问题,一时间不知道是什么原因引起的,情况如下:按钮是用 a 标签写的,由于要写css hover效果,给 a 加了overflow: hidden后发现 a 的父容器下方被撑开了若干像素。

17_9_3_01.png

按钮样式为:

1
2
3
4
5
6
7
8
9
10
11
12
13
a{
display: inline-block;
padding: 0 20px;
color: #fff;
border: 2px solid #555;
color: #555;
font-size: 14px;
background: #fff;
border-radius: 2px;
line-height: 2;
overflow: hidden;
vertical-align: bottom;
}

解决问题

常用的解决方法有两种:

  1. 给父容器加font-size: 0
  2. 给上述 inline-block 元素加vertical-align: bottom (相对于父标签的底部对齐);

17_9_3_02.png

WHY?

W3C的规范对此行为有明确规定:

1
2
3
The baseline of an 'inline-block' is the baseline of its last line box in the normal flow, 
unless it has either no in-flow line boxes or if its 'overflow' property has a computed value other than 'visible',
in which case the baseline is the bottom margin edge.

我们从规范中可以知道当一个 inline-block 元素被设置 overflow 非 visible 属性值后,其 baseline 将被强制修改为元素下外边沿。

我们知道默认情况下,baseline为字符的底线位置且 vertical-align 属性值为 baseline。

为什么W3C要做如此奇怪的规定呢?

这是因为 overflow 被设置为非 visible 值,将使得该 inline-block 元素中的 last line box 的渲染处于不确定状态(浏览器可能渲染也可能不渲染),这让保持默认规则的 baseline 也处于不确定状态,那么索性就规定以确定的下外边沿来作为 baseline。

1
2
3
"baseline" -
Align the baseline of the box with the baseline of the parent box.
If the box does not have a baseline, align the bottom margin edge with the parent's baseline.

参考vertical-align的更多用法:这里