后代选择器 .card .title 会因 dom 层级耦合导致复用失败;:where() 以零权重安全归一化跨块样式;css 自定义属性需按结构/皮肤分类管理;data- 属性比 classlist 更稳定、语义化且性能优。

为什么直接写 .card .title 会导致复用失败
这种后代选择器把样式逻辑锁死在 DOM 层级里,一旦卡片被嵌入到已有 .card 的页面、或父容器 class 名从 .section-card 改成 .feature-card,.card .title 就会失效或误匹配。更隐蔽的问题是:两个不同模块都定义了 .button:hover,后加载的 CSS 会静默覆盖前者的交互效果,开发者却很难察觉。
:where() 怎么安全合并多个块的基础样式
它权重为 0,不会干扰后续修饰符覆盖,适合归一化跨块共性规则。比如 .header__logo 和 .footer__logo 都需要 max-width: 120px,可统一写:
:where(.header__logo, .footer__logo) {
max-width: 120px;
}
注意点:
- Safari 15.4+ 才完全支持,旧版需用 PostCSS 插件降级
- 别用
:is()做跨块归一化——它会提升权重,可能导致.btn--primary覆盖失败 -
:where()不适合写状态类(如[data-loading]),它只管基础结构对齐
CSS 自定义属性怎么真正解耦“结构”和“皮肤”
变量名必须用连字符(--space-md),下划线或驼峰在旧版 Safari 中可能不识别;关键不是定义多少变量,而是把重复出现的数值(颜色、间距、圆角)抽出来统一管理。
结构类该用变量的地方:
-
padding、margin、border-radius—— 它们影响布局稳定性 -
font-size、line-height—— 字号错乱会导致组件“站不住”
皮肤类该用变量的地方:
-
background-color、color、box-shadow—— 纯视觉表现,可随主题切换 -
transition动效参数 —— 保持动效节奏一致
错误做法:.btn--primary { font-size: var(--text-lg); } —— 字号属于结构,不该由皮肤类控制。
动态改 data- 属性比操作 classList 更稳的原因
用 data-loading 标记状态,配合 CSS 写成 [data-loading] { opacity: 0.6; pointer-events: none; },JS 只需 el.dataset.loading = 'true'。
优势明显:
- 避免手拼类名出错(比如
btn--disabled-loading这种组合类漏掉--或多加空格) - 不触发 classList 增删的重排重绘开销
- 无障碍工具能读取
data-属性语义,比纯 class 更友好 - 搭配
:has()实现父子联动(如.card:has([data-error])),不用给父元素额外加类
容易忽略的一点:自定义属性值为空字符串时,[data-loading=""] 不会匹配,得用布尔属性写法 [data-loading] 才可靠。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











