CSS选择器有五大关键规则:①ID选择器数字开头必须Unicode转义(如#\37)或避免纯数字ID;②伪类顺序必须LVHA(:link/:visited/:hover/:active);③权重按等级逐位比较,ID(0,1,0,0)恒大于多类名;④内联样式权重1,0,0,0几乎不可覆盖;⑤>仅匹配直接子元素,后代选择器更容错。

ID选择器以数字开头必须转义
直接写 #7 或 #123 会导致整条CSS规则被浏览器忽略,样式完全不生效——这不是兼容性问题,而是CSS语法非法。HTML允许 id="7",但CSS选择器规范禁止数字开头的标识符未转义。
正确做法是使用Unicode转义:#\37(\37 是字符 7 的十六进制码点),注意末尾需加空格或紧跟非十六进制字符才能终止转义;更稳妥的方案是彻底避免纯数字ID,改用语义化类名如 .item-7。
常见错误现象:#7 { flex-shrink: 4; } 在开发者工具Styles面板中整行灰掉、无权重显示、无任何报错提示,极易误判为“没加载”或“写错了属性”。
伪类顺序错乱会直接导致规则失效
CSS解析器对 :link、:visited、:hover、:active 这组交互伪类有硬性顺序要求(LVHA),顺序错一个,整条规则可能被跳过。
立即学习“前端免费学习笔记(深入)”;
例如:a:active:hover 是非法写法,浏览器会标记为 Invalid selector 并静默丢弃;必须写成 a:hover:active。
现代伪类如 :focus-within 或 :has() 不受LVHA约束,但混用时建议拆开定义:单独写 button:hover 和 button:focus-within,比强行拼成 button:hover:focus-within 更可控、更易调试。
调试技巧:在DevTools中右键元素 → “Force element state”,手动触发状态,若能强制生效但自然交互无效,大概率是顺序问题。
选择器权重不是“越长越强”,而是分等级计算
权重比较是逐位进行的:0,1,0,0(ID)永远大于 0,0,99,99(99个类+99个标签),低级权重再多个也压不过高级权重的一个。
典型踩坑点:
-
#nav .menu-item.active(权重0,1,2,0)会被.nav-list li(权重0,0,2,0)轻松覆盖——因为前者含ID,后者没有,根本不在同一量级比较 - 内联样式
style="color:red"权重为1,0,0,0,几乎无法被外部CSS覆盖,除非加!important - 同权重下后写的规则才生效,但很多人把重置样式表放在最后,结果自定义样式全被清掉了
查权重最直接的方式:打开DevTools → 选中元素 → Styles面板里看被划掉的声明旁是否有权重数值(Chrome/Edge支持悬停查看)。
后代与子代选择器混淆导致匹配失败
.card p 和 .card > p 看似只差一个符号,但匹配逻辑完全不同:> 只认直接子元素,中间多一层包裹就失配。
比如HTML是 <div class="card"><section><p>text</p></section></div>,那么:
-
.card p能匹配(p是.card的后代) -
.card > p匹配不到(p不是.card的直接子元素)
这类问题在组件库嵌套或动态渲染DOM时高频出现,不能只靠“看起来结构一样”判断,务必在Elements面板里确认真实DOM层级。如果不确定结构是否稳定,优先用更宽松的后代选择器,或给目标元素加明确类名。


















