前端一面:CSS 优先级、选择器与样式冲突排查

很多候选人在项目里写了大量 CSS,但在一面里被问到“这段样式为什么没生效?”就会有点慌。这一篇从 CSS 优先级规则、常见选择器用法和排查思路几个角度整理一下。

可以用一个常见的抽象来记忆选择器优先级(从高到低):

  1. !important(在正常层叠规则之上,慎用);
  2. 行内样式(例如 style="color: red");
  3. 选择器的“权重”:
    • ID 选择器:#id
    • 类、属性、伪类选择器:.class[type="text"]:hover 等;
    • 元素、伪元素选择器:divp::before 等;
  4. 源码顺序(后出现的覆盖前面的)。

常见的权重记忆方法(不必死背具体数字,但可以用来解释):

  • 每个选择器可以表示成一个“权重元组”,例如 (a, b, c, d)
    • a:是否为行内样式;
    • b:ID 选择器个数;
    • c:类/属性/伪类选择器个数;
    • d:元素/伪元素选择器个数。

比较两个规则时,先比 a,再比 b,依次往下。

一面里有时会给你一段 HTML 和几段 CSS,问你“最终应用的是哪条规则”,这里容易出错的包括:

  • 混用 ID 和类:
1#app .title { color: red; }
2.title { color: blue; }

即使 .title { color: blue; } 写在后面,由于 #app .title 的优先级更高,最终颜色仍然是红色。

  • 后代选择器与子选择器的区别:
1.container .item { ... }  /* 后代,任意嵌套层级 */
2.container > .item { ... } /* 子元素,必须是直接子节点 */
  • 属性选择器/伪类选择器也会增加权重:
1input[type="text"]:focus { ... }

在优先级上等价于一个类选择器(计入 c)。

理解这些内容,有助于你在排查“为什么我这条样式没生效”时少走弯路。

在实际项目里,当你发现“写了样式但没有生效”,可以按这个顺序排查:

  1. 确认选择器是否匹配到元素

    • 用浏览器 DevTools 查看元素的匹配规则;
    • 检查 class 名是否拼写正确、有没有写错层级。
  2. 比较优先级

    • DevTools 里看是被谁覆盖了;
    • 注意是否有 !important 或 ID 选择器;
  3. 检查是否有更高层的样式覆盖

    • 比如组件库的样式、全局样式等;
    • 有时需要通过增加一个更具体的选择器或调整样式层级来解决。
  4. 考虑样式作用域机制

    • 在 Vue/React CSS Modules 等场景下,class 可能被编译成哈希名,手写选择器不起作用;
    • 需要用对应的 scoped 机制或正确引入样式。

在一面回答“如何排查样式冲突”时,沿着这个思路讲一遍,能让人感觉你日常真的踩过坑。

1<div id="app">
2  <h1 class="title">Hello</h1>
3</div>
1h1 { color: black; }
2.title { color: blue; }
3#app .title { color: red; }

参考答案:

  • 最终颜色是红色,来自 #app .title
  • 三条规则的优先级从低到高分别是:
    • h1:元素选择器 → 权重较低;
    • .title:类选择器 → 比元素高;
    • #app .title:ID + 类选择器 → 最高;
  • 即便 .title 写在 #app .title 后面,如果不加 !important,仍然会被更高权重的选择器压过。

参考答案要点:

  • 可以通过提高选择器优先级(例如增加一个父级限定)来覆盖其它规则;
  • 也可以在少数必要场景下使用 !important,但要谨慎:
    • 它会跳出正常的层叠规则,使后续样式很难再覆盖;
    • !important 越多,样式越难维护,冲突越难排查。

建议表明态度:

“我会优先通过调整选择器和结构来解决,!important 只在特殊情况(例如第三方库样式无法改动时)使用。”

参考答案思路:

  • 打开 DevTools,选中目标元素,查看“Rules/样式”面板:
    • 看看目标选择器有没有匹配到元素;
    • 看看有没有其它规则(尤其是组件库/全局样式)覆盖了它;
  • 如果被覆盖:
    • 分析对方的优先级和源码顺序;
    • 根据情况调整自己的选择器(如加一层父级限定),或者调整样式引入顺序;
  • 如果完全没匹配:
    • 检查 class 名拼写、样式作用域(scoped/CSS Modules)等问题。

这类问法本质上是想看你是不是习惯用 DevTools + 优先级规则来系统排查,而不是盲目地加 !important