前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
首页程序员面试题库行内元素 margin-top height 无效
CSS盒模型与排版

给 span 设置 height 和 margin-top,为什么页面上看不出变化?

span 是行内非替换元素,width 和 height 对它不生效,margin-top 和 margin-bottom 虽然算了但不会推开上下的内容。一行有多高只看 line-height,想让它认高度就改成 display: inline-block。

前端进阶之旅 · 一题精讲更新于 2026.09.29
CSS#盒模型与排版
先看核心答案读代码示例
理解线索

行内盒在两个方向上的待遇不同

  1. 水平方向margin、padding、border 都会推开左右的文字
  2. 垂直方向height 无效,上下 margin 不占位,padding 只画不占位
  3. line-height行框高度由行内盒的 line-height 算出来,是唯一能撑开行的属性

<img>、<input> 这类替换元素虽然也是 inline,却能设宽高,上下 margin 也会撑开行框。题目说的只是 span、a、em 这类非替换元素。

核心回答

先记住这个答案

span 属于行内非替换元素,它的内容区高度由字体决定,CSS 规范明确规定 width 和 height 对它不生效。上下 margin 在计算上存在,但不参与行框的高度,所以看不出任何位移。上下 padding 和 border 会画出来,同样不撑开行,常常盖到上一行的文字上。一行有多高,只由这一行里各个行内盒的 line-height 决定。想让它认宽高,就改成 display: inline-block 或 block。

  • 行内非替换元素不认 width 和 height
  • 行内元素垂直外边距不撑行高
  • 垂直内边距和边框可绘制越界
  • 改成 inline-block 就能设宽高和上下外边距

同一个 span,两种 display 的对比

先看一段最直接的对照。同样的样式,一个是默认的 inline,一个改成了 inline-block。

把代码贴进浏览器看效果HTML
<p>第一行文字<br>
  <span style="height: 60px; margin-top: 30px; padding: 10px; background: #fcd34d;">inline</span>
  后面的文字
</p>
<p>第一行文字<br>
  <span style="display: inline-block; height: 60px; margin-top: 30px; padding: 10px; background: #fcd34d;">inline-block</span>
  后面的文字
</p>
<!-- 第一段:黄色背景比文字高一截,盖到了上一行,但第二行没有下移 -->
<!-- 第二段:黄块高 80px(60 + 上下 padding),第二行被整体推低 -->

第一段里,height: 60px 完全被忽略,margin-top: 30px 没有把它往下推,上下各 10px 的 padding 让背景变高了,但这一行的高度没变,背景就溢到上一行上。第二段改成 inline-block 后,它在外部仍然像文字一样排在行里,内部却按块级盒计算尺寸,宽高、上下 margin 都参与了行框高度的计算,整行被撑高。

为什么行内元素不认高度

行内元素的设计初衷是「嵌在一段文字里的一小段文字」。比如一句话里有个 <a> 链接,它可能从第一行的末尾折到第二行开头,被拆成两段。这种盒子本来就没法有一个固定的宽高,所以规范干脆不让 width 和 height 作用在它身上。

那一行的高度怎么定呢?浏览器会给每一行生成一个行框,可以理解成一条横向的轨道。轨道里每个行内盒都按自己的 line-height 算出一个高度,再按 vertical-align 对齐,最高点到最低点的距离就是这一行的高度。这个计算过程只用 line-height,不看 margin、padding 和 border。所以想让 span 所在的行更高,给它设大一点的 line-height 是有效的。

水平方向就不一样了。左右的 margin、padding、border 会实实在在地占位,把前后的文字推开。所以才会出现「margin-left 有效、margin-top 无效」这种看起来不对称的现象。

哪些情况下 span 会变得能设高度
除了手动写 display: inline-block,有几种情况会让 span 自动变成块级盒,宽高随之生效:设置了 float,设置了 position: absolute 或 fixed,或者它的父元素是 flex、grid 容器,这时它成了 flex 或 grid 项目。面试时能说出这几种「自动变块」的情况,说明你真的理解 display 的计算值会被改写。
回答前,多想一步

容易答错的地方

说行内元素的所有 margin 都无效
只有上下方向无效,左右 margin 是正常的。设置 margin: 0 20px 能把左右文字推开 20px。
说垂直 padding 也无效
垂直 padding 是生效的,背景色会跟着变大,只是它不占位,不会把上下行推开。所以给行内的链接加上下 padding 扩大点击区域是可行的,但要注意背景会压到上一行。
把 img 也归进来
<img> 默认也是 inline,但它是替换元素,内容来自外部资源,本身有固有尺寸,所以能设 width、height,上下 margin 也会撑开行框。题目里的规律只适用于非替换元素。
试着用自己的话回答

面试官还会怎么问?

那怎么让一个 span 垂直方向留出间距?

最常见的是改成 display: inline-block,然后直接设 margin-top 或 height。如果只是想让整行更高、文字更松,给它或它的父元素加大 line-height 就够了,不需要改 display。

inline-block 元素之间为什么有一条缝?

因为 inline-block 仍然参与行内排版,HTML 里两个标签之间的换行和空格会被当成一个空格字符渲染出来。常见修法是父元素 font-size: 0,或者干脆改用 flex 布局。

inline-block 的元素底部为什么会多出几像素空白?

inline-block 和图片默认按基线 vertical-align: baseline 对齐,基线下面要给字母 g、y 的下伸部分留位置,于是底部空出一截。把 vertical-align 改成 top 或 middle,或者改成 display: block 就没了。

从一道题,走向一组知识

把知识连起来

盒模型与排版

width 200px 再加 padding 20px 和 border 5px,元素实际有多宽?

改成 inline-block 之后宽高就生效了,这时总宽度怎么算要看 box-sizing。

盒模型与排版

clear both 到底做了什么,它是怎么避开左右两边浮动的?

给 span 加 float 会让它变成块级盒,宽高随之生效,浮动之后才轮到 clear 处理后面的元素。

参考资料

  • CSS:盒模型与排版参考资料

示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。

本题目录
  1. 先记住这个答案
  2. 同一个 span,两种 display 的对比
  3. 为什么行内元素不认高度
  4. 容易答错的地方
  5. 面试官还会怎么问
  6. 把知识连起来
读懂,再试着讲出来

先看核心答案,再读代码。最后展开追问,检查自己有没有遗漏边界。

试着回答追问
浏览全部面试题理解原理,也关注真实的使用场景。回到顶部 ↑