使用vanilla-extract定义嵌套元素样式遇TS报错,求正确用法
问题原因与解决方案
核心原因
vanilla-extract 默认不允许在style()函数内直接编写后代选择器嵌套(比如ul li这种形式),这并非配置错误,而是它的原生类型约束:ComplexStyleRule仅支持CSS属性、伪类/伪元素的嵌套(如&:hover),不支持后代选择器的直接嵌套,因此触发TypeScript类型错误。
解决方案1:启用嵌套插件(保留你偏好的写法)
通过@vanilla-extract/css/nested插件可以实现类似Sass/PostCSS的嵌套语法,既保留可读性,又能通过类型校验:
- 安装依赖(若未安装):
npm install @vanilla-extract/css @vanilla-extract/css/nested
- 修改样式文件代码:
import { style } from '@vanilla-extract/css'; import { nested } from '@vanilla-extract/css/nested'; export const navbar = style( nested({ transition: 'width 100ms ease-in-out, min-width 100ms ease-in-out', 'ul li': { position: 'relative', borderLeftWidth: `${borderWidth}px`, borderStyle: 'solid', borderLeftColor: 'transparent', '&.active': { borderLeftColor: 'orange', }, '&:hover': { borderLeftColor: 'purple', }, }, }) );
解决方案2:使用官方原生selectors字段(无需额外插件)
vanilla-extract提供了原生支持的selectors字段来定义嵌套/后代规则,完全符合类型要求:
import { style } from '@vanilla-extract/css'; export const navbar = style({ transition: 'width 100ms ease-in-out, min-width 100ms ease-in-out', selectors: { '& ul li': { position: 'relative', borderLeftWidth: `${borderWidth}px`, borderStyle: 'solid', borderLeftColor: 'transparent', '&.active': { borderLeftColor: 'orange', }, '&:hover': { borderLeftColor: 'purple', }, }, }, });
关于globalStyle的补充说明
你之前使用globalStyle遇到的类型错误,是因为GlobalStyleRule不支持&引用当前选择器的语法——globalStyle的选择器是全局作用域,&在这里没有语义,因此必须拆分:hover和.active为独立声明。但更推荐用上面两种方案处理组件内部的嵌套样式,避免使用globalStyle增加全局样式污染风险。
内容的提问来源于stack exchange,提问作者aviemet
相关产品推荐
相关产品推荐

