为何行内元素span的上半部分会遮挡文本而下半部分不会?
复现问题代码
CSS 样式
span { margin: 20px; padding: 20px; width: 80px; height: 50px; background-color: lightblue; border: 2px solid blue; } p { width: 300px; }
HTML 结构
<p> I am a paragraph and this is a <span>span</span> inside that paragraph. A span is an inline element and so does not respect width and height. </p>
现象说明
运行上述代码可以观察到:span 元素的上半部分会遮挡上方的文本,下半部分不会遮挡下方的文本,具体表现为单词paragraph被 span 的背景遮挡,而 span 下方的span is an文本没有被遮挡。
原因解释
span是行内非替换元素,设置的width、height属性不会生效,上下方向的margin也不会参与行高计算,既不会改变当前行的高度,也不会撑开父元素p的高度。但上下的padding和border会实际渲染,会超出当前行的行盒范围。- 父元素
p设置了固定宽度 300px,而行内元素的左右margin、padding、border都会参与水平布局计算,本次设置的 span 水平占位宽度过大,不足以放在第一行剩余空间中,因此 span 会自动换行到第二行开头。 - 浏览器绘制页面遵循 DOM 顺序从上到下依次绘制 的规则,先渲染的元素会被后渲染的元素覆盖:
- 第一行包含
paragraph的文本先渲染,位于第二行的 span 后渲染,span 向上溢出的上 padding 区域就会覆盖在第一行的文字上方 - 第三行的文本渲染时间晚于 span,所以 span 向下溢出的下 padding 区域会被后渲染的第三行文本覆盖,不会出现遮挡下方文字的情况
- 第一行包含
解决方案
如果要避免遮挡问题,可任选一种方案:
- 给 span 添加
display: inline-block属性,此时上下padding、margin都会参与行高计算,行盒会被撑开,不会出现溢出现象 - 给父元素
p设置足够大的line-height,让行高可以容纳 span 加上上下padding、border的总高度,避免溢出覆盖
内容的提问来源于stack exchange,提问作者Smallnine
相关产品推荐
相关产品推荐

