IE6/IE7用html和+html选择器过滤,Firefox用@-moz-document或#id[id="id"],Chrome/Safari用@media screen and (-webkit-min-device-pixel-ratio:0),IE8+用:root伪类配合\9或\0。

IE6/IE7 用 *html 和 *+html 选择器过滤
这两个选择器利用了 IE6 和 IE7 解析 HTML 根节点时的 bug:*html 只被 IE6 识别(因为 IE6 把 * 当作通配符,误认为 html 是其子元素);*+html 则依赖 IE7 对相邻兄弟选择符的错误解析,IE6 和 IE8+ 都不认。注意它们必须写在标准规则之后,靠 CSS 优先级覆盖。
常见错误是把它们当通用前缀乱加,比如 *html .btn 写成 *html.btn(漏空格),结果整个规则失效。另外,现代构建工具(如 PostCSS 插件)默认会删掉这类非法选择器,需手动禁用清理逻辑。
-
*html .header { margin-top: 10px; }→ 仅 IE6 生效 -
*+html .header { margin-top: 15px; }→ 仅 IE7 生效 - 不能用于内联样式或
style属性,只在外部或内部 CSS 中有效
Firefox 用 @-moz-document 或 #id[id="id"]
@-moz-document url-prefix() 是 Firefox 专属的 at-rule,能精准命中所有版本的 Firefox(包括 ESR),但不被任何其他浏览器解析。另一种更轻量的方式是利用 Gecko 内核对属性选择器的特殊处理:#demo[id="demo"] 这种写法在 Firefox 中计算为真,在 Chrome/Safari/Edge 中因严格匹配失败而被忽略。
注意 @-moz-document 在 Firefox 91+ 仍可用,但若页面启用了 document.domain 修改,可能触发安全限制导致规则不加载。而 #id[id="id"] 方式虽兼容性更好,但要求目标元素必须有对应 id 属性,且不能用在伪类链中(如 #x[id="x"]:hover 在部分旧版 FF 中失效)。
立即学习“前端免费学习笔记(深入)”;
@-moz-document url-prefix() { .nav { padding: 2px; } }-
#main[id="main"] { background: #eee; }→ 仅 Firefox 渲染 - 避免嵌套过深,例如
@-moz-document里再写@media可能被某些 FF 版本忽略
Chrome/Safari 用 @media screen and (-webkit-min-device-pixel-ratio:0)
这个媒体查询基于 WebKit 内核对 -webkit-min-device-pixel-ratio 的支持,Chrome 1+、Safari 3.1+ 都识别,但 Edge 12+(Chromium 版之前)和 Firefox 完全无视。它比 body:nth-of-type(1) 更可靠,后者在某些 Safari 版本中存在偶发失效问题。
容易踩的坑是把它当成“仅限 Chrome”,实际上所有 WebKit 内核浏览器(包括老版 Opera 15 前)都会进这个分支。如果你只想针对 Chrome,得叠加 UA 检测 JS 逻辑;如果只改样式,建议配合 :not(.no-webkit-hack) 类做降级兜底。
@media screen and (-webkit-min-device-pixel-ratio:0) { input[type="date"] { padding: 4px; } }- 不要在其中写
!important,WebKit 对媒体查询内优先级的处理偶尔有偏差 - 该查询在 Windows 上高 DPI 屏幕下可能意外触发,测试时需切换缩放比例验证
IE8+ 用 :root 伪类配合 \9 或 \0
:root 是 CSS3 标准伪类,IE9+、Firefox、Chrome、Safari 都支持,但 IE8 不支持——所以 :root .box 天然排除 IE8。若要单独命中 IE8,得用属性 hack:color:red\0; 被 IE8 和 Opera 12.1- 识别,color:red\9\0; 则仅 IE9 支持。两者组合可实现分层控制。
关键点在于转义符顺序:\9 必须紧贴属性值末尾(如 margin:0\9;),中间不能有空格;\0 同理。而且 IE8 对 \0 的解析不稳定——某些补丁版本会忽略带单位的值(如 width:100px\0; 失效,但 width:100\0; 可用)。
-
:root .wrap { font-size: 16px; }→ IE8 不执行 -
.wrap { padding: 10px\0; }→ IE8 + Opera 12.1- 生效 -
.wrap { color:#000\9\0; }→ 仅 IE9 解析(IE10+ 已废弃此 hack)
真正麻烦的不是写法本身,而是当多个 hack 叠加时的优先级冲突——比如 *+html .x 和 :root .x 同时存在,IE7 会执行前者并忽略后者,但开发者常误以为后者能“兜底”覆盖。实际调试时,得用浏览器自带的开发者工具逐条禁用规则来验证生效路径。


















