前端一面:CSS 优先级、选择器与样式冲突排查
很多候选人在项目里写了大量 CSS,但在一面里被问到“这段样式为什么没生效?”就会有点慌。这一篇从 CSS 优先级规则、常见选择器用法和排查思路几个角度整理一下。
CSS 优先级的基本规则
可以用一个常见的抽象来记忆选择器优先级(从高到低):
!important(在正常层叠规则之上,慎用);- 行内样式(例如
style="color: red"); - 选择器的“权重”:
- ID 选择器:
#id; - 类、属性、伪类选择器:
.class、[type="text"]、:hover等; - 元素、伪元素选择器:
div、p::before等;
- ID 选择器:
- 源码顺序(后出现的覆盖前面的)。
常见的权重记忆方法(不必死背具体数字,但可以用来解释):
- 每个选择器可以表示成一个“权重元组”,例如
(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)。
理解这些内容,有助于你在排查“为什么我这条样式没生效”时少走弯路。
样式冲突排查的常用思路
在实际项目里,当你发现“写了样式但没有生效”,可以按这个顺序排查:
确认选择器是否匹配到元素
- 用浏览器 DevTools 查看元素的匹配规则;
- 检查 class 名是否拼写正确、有没有写错层级。
比较优先级
- DevTools 里看是被谁覆盖了;
- 注意是否有
!important或 ID 选择器;
检查是否有更高层的样式覆盖
- 比如组件库的样式、全局样式等;
- 有时需要通过增加一个更具体的选择器或调整样式层级来解决。
考虑样式作用域机制
- 在 Vue/React CSS Modules 等场景下,class 可能被编译成哈希名,手写选择器不起作用;
- 需要用对应的 scoped 机制或正确引入样式。
在一面回答“如何排查样式冲突”时,沿着这个思路讲一遍,能让人感觉你日常真的踩过坑。
常见面试题与参考答案
题 1:下面哪条规则生效?为什么?
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,仍然会被更高权重的选择器压过。
题 2:如何强制某条样式覆盖其它规则?!important 有什么问题?
参考答案要点:
- 可以通过提高选择器优先级(例如增加一个父级限定)来覆盖其它规则;
- 也可以在少数必要场景下使用
!important,但要谨慎:- 它会跳出正常的层叠规则,使后续样式很难再覆盖;
!important越多,样式越难维护,冲突越难排查。
建议表明态度:
“我会优先通过调整选择器和结构来解决,
!important只在特殊情况(例如第三方库样式无法改动时)使用。”
题 3:如何排查一段样式“似乎没生效”的问题?
参考答案思路:
- 打开 DevTools,选中目标元素,查看“Rules/样式”面板:
- 看看目标选择器有没有匹配到元素;
- 看看有没有其它规则(尤其是组件库/全局样式)覆盖了它;
- 如果被覆盖:
- 分析对方的优先级和源码顺序;
- 根据情况调整自己的选择器(如加一层父级限定),或者调整样式引入顺序;
- 如果完全没匹配:
- 检查 class 名拼写、样式作用域(scoped/CSS Modules)等问题。
这类问法本质上是想看你是不是习惯用 DevTools + 优先级规则来系统排查,而不是盲目地加 !important。