结论:总高度 = height + 上下padding + 上下border + 上下margin(仅content-box下严格成立);border-box下height已含padding和border,仅margin需额外加,且margin始终不参与box-sizing计算。

直接说结论:总高度 = height + 上下padding + 上下border + 上下margin,但这个公式只在box-sizing: content-box(默认)下严格成立;一旦用了box-sizing: border-box,height就已包含上下padding和border,只剩margin要额外加。
content-box 模式下 height 到底管哪一段
它只管内容区(content)的垂直空间。哪怕你写height: 100px,只要加了padding-top: 12px、padding-bottom: 8px、border-top: 1px solid #000、border-bottom: 1px solid #000,内容区确实是100px高,但元素实际从上边框顶到下边框底就是100 + 12 + 8 + 1 + 1 = 122px。
常见错误现象:
- 用
flex: 1撑满父容器时,子元素莫名溢出——其实是padding和border偷偷加高了 - JS读取
offsetHeight发现比CSS写的height大一截,却找不到原因 - 栅格列里设了
height: 100%,但文字被padding挤出可视区
border-box 模式下 height 的真实含义
height变成“最外沿到最外沿”的距离(不含margin)。上下padding和border不再往外撑,而是往里压缩内容区。比如同样height: 100px、padding: 12px 8px、border: 1px solid,内容区实际只有100 - 12 - 8 - 1 - 1 = 78px高,但整个元素从上边框顶到下边框底铁定是100px。
立即学习“前端免费学习笔记(深入)”;
适用场景:
- 需要多个卡片并排且高度严格一致(如产品列表)
- 表单控件统一尺寸,避免
input和textarea因padding不同而错位 - 用
vh做全屏布局时,防止padding导致滚动条意外出现
margin 为什么永远不参与 box-sizing 计算
无论content-box还是border-box,margin都游离在盒子之外。它不影响offsetHeight或getBoundingClientRect().height的返回值,但会决定该元素在文档流中“占多少地方”。
比如一个div设了height: 100px、box-sizing: border-box、margin: 20px 0,它的offsetHeight是100,但兄弟元素和它之间的净距离是40px(20 + 20),而且父容器若高度固定为100px,就会被撑开。
容易踩的坑:
- 以为
box-sizing: border-box能“吞掉”margin——它完全不管margin - 用
height: 100vh+margin-bottom: 40px,结果页面出现垂直滚动条(因为总占位=100vh + 40px) - Flex容器设
align-items: stretch,子项margin会拉伸整个行高,但height本身没变
line-height 和 overflow 对实际高度的干扰
上面所有计算都假设内容没撑破设定高度。但line-height会影响内联内容的实际行高,overflow: visible会让内容溢出却不改变offsetHeight,而overflow: hidden可能裁剪但不压缩高度。
例如:height: 40px、line-height: 24px、font-size: 14px、padding: 8px,单行文本理论上刚好填满(24 + 8 + 8 = 40),但如果字体渲染有微小偏差,或遇到vertical-align: baseline,实际高度可能多出1–2px。
关键点:
-
min-height和max-height会覆盖height,但叠加规则不变 - 空元素(无内容、无
line-height触发)在content-box下height: 0仍会显示padding和border - 表格单元格(
td)、button等原生控件对box-sizing支持不一,Safari旧版select甚至会忽略border-box


















