CSS盒模型在IE6/7/8下的兼容性回顾_历史遗留问题

2次阅读

ie6/7 完全不支持 box-sizing 属性,ie8 仅在标准模式下支持;怪异模式下 width 包含 paddingborder,需用结构模拟 border-box 效果。

CSS盒模型在IE6/7/8下的兼容性回顾_历史遗留问题

IE6/7 的 box-sizing 根本不支持

直接说结论:IE6 和 IE7 完全没有 box-sizing 这个 css 属性,写上去等于没写。IE8 虽然开始支持,但只在 IE8 标准模式()下生效;如果页面触发了 IE8 的怪异模式(quirks mode),它会退化成 IE7 行为,照样忽略 <code>box-sizing

常见错误现象是:你在 chrome 里调好的 width: 200px; padding: 10px; box-sizing: border-box;,一到老 IE 就撑开成 220px,布局错位。

  • 别指望用 @supports (box-sizing: border-box) 在老 IE 里做降级——它本身就不识别 @supports
  • 如果必须兼容,得靠重写盒模型结构:用外层容器控宽,内层元素控 padding,把 border/padding 搬到父级去
  • jquery 1.x 的 .width() / .innerWidth() 在 IE6/7 下返回值混乱,不是因为 js 错,而是底层 dom 获取的尺寸本就受怪异盒模型影响

IE6/7/8 怪异模式下的 width 计算逻辑

这是最常踩坑的地方:只要没写标准 DOCTYPE,IE6–8 全部进入怪异模式,此时 width 指的是「内容 + padding + border」的总和,也就是所谓的“IE 盒模型”。这和现代浏览器的「content-box」语义完全相反。

典型使用场景:接手一个没有 DOCTYPE 的老后台系统,CSS 里写了 width: 100%; padding: 5px;,结果在 IE6 下内容区被压缩到只剩 90% 宽。

立即学习前端免费学习笔记(深入)”;

  • 检查是否触发怪异模式:打开开发者工具(F12),看右上角文档模式是不是 “Quirks” 或 “IE7 Standards” —— 前者一定出问题,后者也不保险
  • widthheightmax-width 在怪异模式下全部按 IE 盒模型解析,但 min-width 不生效(IE6/7 完全不支持)
  • 不要试图用 *width_width hack 强行覆盖怪异模式行为——hack 只能改值,改不了计算逻辑

border-box 模拟在 IE6–8 中的可行方案

真要让老 IE 表现接近 box-sizing: border-box,只能用结构换样式。核心思路是:把 padding 和 border 搬离目标元素,由父容器承担视觉占位。

比如你原本想写的:

.input-wrap { width: 200px; padding: 4px; border: 1px solid #ccc; box-sizing: border-box; }

在 IE6–8 里必须拆成两层:

<div class="input-outer">   <input type="text" class="input-inner"> </div>

然后这样写 CSS:

.input-outer { width: 200px; padding: 4px; border: 1px solid #ccc; } .input-inner { width: 100%; border: none; margin: 0; }
  • 这个模式在 IE6–8 所有文档模式下都稳定,且不影响 JavaScript 获取 offsetWidth
  • 注意 input 默认有 vertical-align: baseline,可能造成父容器底部多出几像素间隙,需要加 vertical-align: top 或设 font-size: 0 清除
  • 如果涉及浮动或 inline-block 布局,外层容器记得清除浮动或设置 font-size: 0 防止空白符占位

margin 合并与 hasLayout 在 IE6/7 中的连锁反应

IE6/7 的 hasLayout 状态不仅影响边距塌陷,还会间接改变盒模型的尺寸解析边界。一个没触发 hasLayout 的块级元素,在计算 margin 时可能把父容器的 padding 也算进去,导致实际宽度溢出。

典型错误现象:两个相邻 <div>,各自设了 <code>margin-bottom: 10px,在 IE6 下只显示 10px 间距(正常合并),但父容器却莫名变高——其实是子元素没 hasLayout,导致 margin 渗透到了父容器外部。

  • 触发 hasLayout 的常用方式:zoom: 1(最安全)、height: 1%overflow: hidden(慎用,可能裁剪内容)
  • 一旦用了 zoom: 1,该元素的 width 就按当前文档模式重新解释:标准模式下是 content-box,怪异模式下是 IE 盒模型
  • 不要给所有元素无差别加 zoom: 1——它会强制重排,对性能敏感的老机器(比如 XP + IE6)可能明显卡顿

事情说清了就结束。真正麻烦的从来不是“怎么模拟 border-box”,而是当多个老系统嵌套 iframe、混用不同 DOCTYPE、又叠加了 jQuery 1.4.2 和 prototype 1.6 时,哪一层的盒模型被谁改了——这种时候,光看 CSS 是看不出问题的。

text=ZqhQzanResources