根本原因是table-layout: auto不支持百分比高度,各浏览器对行高、继承和包含块解析逻辑不同;safari忽略height:100%,chrome算出0px,firefox回退auto。

根本原因不是浏览器“算错”,而是 table-layout: auto(默认值)压根不承诺支持百分比高度或列宽计算——各浏览器对内容换行、行高继承、单元格包含块的解析逻辑天然不同,导致同一份 CSS 在 Chrome、Firefox、Safari 中得出完全不同的像素结果。
为什么 table-layout: auto 下 height: 100% 在 td 里基本无效
这不是写法问题,是规范层面的放弃:该模式只负责根据第一行内容推算列宽,对行高、单元格高度继承不做保证。各引擎自行决定怎么处理:
- Safari 倾向让
td高度由内容撑开,height: 100%被忽略 - Chrome 可能尝试继承
tr高度,但tr自身常为auto,子项算出 0px - Firefox 多数情况直接 fallback 到
auto,声明形同虚设
为什么 table-layout: fixed 的列宽在不同浏览器仍不一致
它不是“开关”,而是一组协同生效条件。漏掉任意一条,浏览器就悄悄回退到 auto 模式,差异照旧:
-
table元素必须有明确width(如width: 100%或width: 800px),否则无尺寸基准 - 列宽定义必须落在第一行的
<th>/</th> <td> 上,或更稳妥地用 <code><colgroup><col></colgroup>—— 后续行的width属性全被忽略 - 不能在单元格上混用
min-width或max-width,尤其 Firefox 中它们会覆盖百分比计算,优先级异常高 - 别调样式、别加
!important、别怀疑浏览器——它就是不支持 - 若需响应式内边距,改用固定像素值(如
padding: 16px)或包裹一层<div> 再设 <code>padding-top: 20%(此时基准变为该div的宽度) - 注意:该限制仅作用于
table-cell,table-row或table元素上设百分比 padding 也无效,但原因不同(缺少包含块定义) - 务必用开发者工具逐层点开 Computed 面板,检查每一级的
height是auto还是具体像素值,而不是只盯着table自身 - 特别留意
display: flow-root、overflow: hidden、transform等会创建新包含块的属性,它们会切断高度链路 - 动态插入内容后,
table-layout: fixed不会自动重读列宽——需手动触发重计算:table.style.width = table.offsetWidth + 'px'
为什么 padding-top: 20% 在 td 里完全没反应
这是 W3C 明确规定的例外行为:display: table-cell 类型下,所有 padding 百分比值被当作 0 处理,所有主流浏览器一致执行。这不是 bug,是规范。
调试时最常被忽略的断点位置
很多人卡在“明明写了 html, body { height: 100% }”,却没发现真正断链的是 table 的直接父容器——比如某个 .panel 被 position: absolute 或 display: inline-block 处理后,就不再是 table 的包含块,导致 height: 100% 回退到 html 计算。











