css自定义属性通过作用域和继承实现值的动态传递,而非解决嵌套结构;变量需在最近非display:none祖先上声明,配合data属性、fallback和语义化命名才能真正解耦。

CSS自定义属性(--x)本身不“解决”嵌套结构,而是把样式中可变的部分从嵌套选择器里抽出来——嵌套负责层级关系,变量负责值的动态性。90% 的失效不是语法错,是作用域没理清。
var(--color) 在子组件里变成黑色?检查继承链是否断裂
变量靠 CSS 继承传递,不是全局查找。父元素没声明 --color,子元素 color: var(--color) 就 fallback 到 initial(通常是黑色)。
- 用浏览器 DevTools 的「Computed」面板展开
color属性,看「Custom Properties」里有没有你定义的变量值 - 确认变量是否在最近的、非
display: none的祖先上声明 ——display: none会切断继承链,display: contents不会 - 别只往
:root塞变量;.modal内部按钮的 hover 色,应该由.modal声明--btn-hover-color,而不是指望全局变量
React + CSS Modules 场景下,如何让 :hover 等伪类可定制?
CSS Modules 的哈希类名会阻断外部选择器穿透,直接传 className 无法影响 .button:hover 这类内部规则。变量是唯一能穿透封装边界的通信方式。
- 在组件 SCSS 文件里,把所有可变样式写成
var(--x):比如.button:hover { background: var(--hover-bg, #007bff); } - 通过
styleprop 或主题 class 注入变量:<button style="{{"></button> - 避免在
:root定义带具体用途的变量(如--button-hover-bg),改用语义化局部变量(如--interactive-bg-hover),由组件自身决定含义
多级菜单每层颜色不同,但不想写死 .menu .submenu .submenu__item?
用 data- 属性配合局部变量覆盖,比深层后代选择器更健壮、更易维护。
- HTML 中标注层级:
<div class="menu__item" data-level="2"> <li>CSS 中按属性设变量:<code>[data-level="1"] { --menu-fg: #1e40af; } [data-level="2"] { --menu-fg: #3b82f6; } - 统一消费:
.menu__item { color: var(--menu-fg); } - 别用
:is(.menu__item--level-1, .menu__item--level-2)—— IE 不支持,且语义模糊;data-level可读、可查、可 JS 控制 -
--gap必须带单位:--gap: 12px,不能写--gap: 12 - 给
var()加 fallback:margin: calc(var(--gap, 12px) + 10px) - 复杂计算拆成两步:
--inner-width: calc(100% - 40px); width: calc(var(--inner-width) / 3); - PostCSS 插件(如
postcss-custom-properties)默认不处理calc()里的var(),降级时需手动展开或换方案
calc(var(--gap) + 10px) 在 Safari 15.4 前静默失效?加单位 + fallback 是底线
旧版 Safari 和 Android WebView 对 calc() 内的 var() 支持极差,整条规则会被丢弃,DevTools 显示 Invalid property value,但控制台无提示。
最难的从来不是怎么写 var(--x),而是想清楚这个 --x 该在哪一层定义、被谁读取、被谁覆盖。一个 --spacing-unit 在 .card 里设为 12px,在 .card__header 里设为 6px,所有 padding 都用它,才叫真正解耦——否则只是把嵌套从选择器搬进了变量名里。











