.a.b是交集选择器,匹配同时拥有a和b类的单个元素;.a .b是后代选择器,匹配.a内部任意层级的.b元素。二者对象不同、层级不同、性能不同。

`.a.b` 和 `.a .b` 是两种完全不同的选择逻辑
加空格是后代选择器,不加空格是类名交集选择器——它们匹配的 DOM 节点根本不在同一个层级上,不是“效果不同”,而是“对象不同”。
比如 .card.title 只会匹配 <div class="card title"> 这种单个元素同时带两个类的情况;而 <code>.card .title 匹配的是任何在 .card 内部(哪怕嵌套 5 层)的 .title 元素,哪怕它自己 class 只有 title 一个。
常见错误现象:
- 写
.btn .primary想给按钮加高亮,结果把页面所有.primary文字都染色了 - 组件封装时用
.modal .header,用户一加个 wrapper div,.header就失效 - SCSS 中写
& .icon(带空格),编译出来变成后代选择器,而不是预期的.modal-icon
空格在 HTML class 属性里和 CSS 选择器里语义相反
HTML 的 class="a b" 中空格表示“并列多个类”,是“且”关系;但 CSS 选择器里 .a .b 的空格表示“祖先-后代”,是“包含”关系。这两个空格互不干扰、各管各的。
立即学习“前端免费学习笔记(深入)”;
所以:class="a b" → 元素拥有两个独立类 a 和 b.a.b → 要求元素同时有 a 和 b 类.a .b → 要求某个 .b 元素在某个 .a 元素内部
容易踩的坑:
- 误把
class="btn-primary"拆成.btn .primary写,实际应写.btn-primary - 复制别人代码时没注意缩进或换行,
.list>li被写成.list > li(多空格不影响),但.list >li(少空格)会解析失败 - 用 JS 动态拼接选择器时,字符串里不小心多塞了个空格,比如
"." + cls1 + " ." + cls2,本意是组合类,结果成了后代选择器
性能与维护性差异比你想象中更实在
浏览器对 .a .b 的匹配需要向上遍历祖先链,DOM 越深、节点越多,重排重绘开销越大;而 .a.b 是单节点属性匹配,快且稳定。
使用场景建议:
- 需要强约束、防误伤:优先用
.a.b或.a.b.c(如.input.error[disabled]) - 必须穿透嵌套结构(比如全局工具类
.text-center应用于任意深度内容):才用空格 - 组件内部样式:尽量用
>替代空格,避免因用户 DOM 变动导致样式断裂
调试时最该盯住的不是样式本身,而是开发者工具里的匹配路径
Chrome DevTools 里选中元素后,右侧 Styles 面板顶部显示的匹配选择器如果出现 .parent .child,就说明这个样式不是作用于当前元素,而是靠它“被包含”才生效的——此时你要立刻问:这个空格,是我真需要它跨层生效,还是只是手抖按出来的?
真正难的不是记住规则,是在每次敲下空格键前,心里已经清楚它将打开哪一层 DOM 树。


















