伪类名必须用单冒号,双冒号专用于伪元素;:hover等状态伪类用:,::before等伪元素用::,::hover无效;:not()仅支持简单选择器;:focus-visible提升可访问性;lvha顺序不可错。

伪类名必须用单个冒号还是双冒号?
现代 CSS 中,:hover、:focus、:nth-child() 这类表示元素状态或位置的伪类,统一用单冒号 :。双冒号 :: 是专留给伪元素的,比如 ::before 和 ::after——这是 W3C 明确区分的语义边界。
常见错误是把 :first-child 写成 ::first-child,浏览器会直接忽略它,且控制台不报错,只默默失效。
- 老式写法(IE8 及更早)只认单冒号,但所有现代浏览器都支持单冒号伪类
-
::selection是个例外:它本是伪元素,但早期实现用单冒号,现在两种都认,建议统一用::selection - 如果用了
::hover,CSS 就无效;别靠“看着像”去猜,查 MDN 看分类
:not() 里能嵌套其他伪类吗?
可以,但有严格限制::not() 的参数只能是「简单选择器」,不能是复合选择器或带伪类链的表达式。
比如 a:not(:visited) 合法,但 div:not(.foo:hover) 非法——.foo:hover 是两个选择器组合,超出了 :not() 的能力范围。
立即学习“前端免费学习笔记(深入)”;
- 合法:
p:not([class*="warn"])、button:not(:disabled) - 非法:
span:not(a:hover)、li:not(:first-child > a) - 想实现复杂排除逻辑?得换思路:用更具体的选择器正向匹配,或加 class 控制
:focus-visible 和 :focus 怎么选?
:focus 在任何获得焦点时都触发(鼠标点、Tab 键、JS .focus()),而 :focus-visible 只在「用户明显需要键盘导航」时激活,比如按 Tab 或方向键,但鼠标点击后不会触发。
这是为可访问性设计的:避免鼠标用户看到突兀的焦点框,又不牺牲键盘用户的操作反馈。
- 默认样式中
:focus常导致鼠标点击按钮后残留蓝框,体验割裂 - 推荐组合写法:
button:focus:not(:focus-visible) { outline: none; },再单独定义button:focus-visible样式 - 注意兼容性:
:focus-visible在 Safari 15.4+ 才稳定支持,旧版本需降级到:focus
伪类顺序写错会导致样式不生效?
会,尤其是 :link、:visited、:hover、:active 这组链接伪类,必须按 LVHA 顺序(Link → Visited → Hover → Active),否则 :hover 可能被 :link 覆盖。
这不是语法错误,而是层叠优先级问题:它们权重相同,后出现的规则覆盖前面的。浏览器不会警告,但鼠标悬停时没反应,你得回头一行行核对顺序。
- 安全写法:
a:link { color: blue; } a:visited { color: purple; } a:hover { color: red; } a:active { color: orange; } -
:focus和:focus-within不在此序列中,可自由安排,但建议放在:hover后便于视觉一致性 - 用预处理器时尤其小心:@extend 或嵌套可能无意打乱顺序,最终生成的 CSS 必须人工检查
伪类不是语法糖,是 CSS 层叠引擎里真实参与计算的条件分支。写错一个冒号、调换两行顺序、在 :not() 里多套一层,都可能让样式彻底消失——而且没有错误提示,只有眼睛盯着页面反复试。










