行块级元素的那些事儿
在写项目的时候,我们难免会把一个元素声明为display: inline-block
,inline-block 元素既具有 block 元素可以定义宽高的特性,同时又具有 inline 元素默认不换行的特性。它也可以设置 vertical-align(这个属性只对设置了inline-block的元素有效)属性,如果这时候加上overflow: hidden
,这可能会引发一个对齐问题,这正是本文要探讨的主要问题。
注意:HTML 中的换行符、空格符、制表符等合并为空白符,字体大小不为 0 的情况下,空白符占据一定的宽度,这时 inline-block 元素之间会产生空隙。
发现问题
其实之前做项目就发现多个内联元素同行显示时就有间隙的问题,不同浏览器间距大小还不同,不过这有很多方法解决,这里就不一一赘述了。
今天在修改按钮样式时就发现一个异常问题,一时间不知道是什么原因引起的,情况如下:按钮是用 a 标签写的,由于要写css hover效果,给 a 加了overflow: hidden
后发现 a 的父容器下方被撑开了若干像素。
按钮样式为:
1 | a{ |
解决问题
常用的解决方法有两种:
- 给父容器加
font-size: 0
; - 给上述 inline-block 元素加
vertical-align: bottom
(相对于父标签的底部对齐);
WHY?
W3C的规范对此行为有明确规定:
1 | The baseline of an 'inline-block' is the baseline of its last line box in the normal flow, |
我们从规范中可以知道当一个 inline-block 元素被设置 overflow 非 visible 属性值后,其 baseline 将被强制修改为元素下外边沿。
我们知道默认情况下,baseline为字符的底线位置且 vertical-align 属性值为 baseline。
为什么W3C要做如此奇怪的规定呢?
这是因为 overflow 被设置为非 visible 值,将使得该 inline-block 元素中的 last line box 的渲染处于不确定状态(浏览器可能渲染也可能不渲染),这让保持默认规则的 baseline 也处于不确定状态,那么索性就规定以确定的下外边沿来作为 baseline。
1 | "baseline" - |
参考vertical-align的更多用法:这里