CSS伪类是以冒号(:)开头的选择器,用于选中元素特定状态(如:hover、:active)或结构关系(如:first-child、:nth-child()),不可直接在JS对象中写作键名,需依CSS-in-JS库规则使用&嵌套或驼峰命名。

不能直接在JS对象里写 :hover 或 :active —— 这是多数初学者卡住的第一步。 因为JS对象键名不支持冒号,{ ':hover': { color: 'red' } } 这种写法会被Emotion、styled-components等主流库静默忽略,JSS则会报错或生成无效CSS。
Emotion / styled-components 中必须用 & 嵌套写法
它们靠 & 识别伪类归属,不是语法糖,是作用域锚点。漏掉 & 就等于把规则扔进全局,可能污染其他元素。
-
&:hover表示“当前组件根节点的 hover 状态”,最终生成类似.css-abc123:hover -
&:active同理,但注意移动端 click 触发顺序:iOS Safari 中:active持续时间极短,常需配合touchstartJS 逻辑补足 - 组合伪类如
&:hover:active是合法的,但浏览器支持度低;更可靠的是分开写&:hover和&:active,让样式层叠处理 - 错误示范:
{ hover: { color: 'red' } }(JSS 语法)误用在 Emotion 里 → 完全不生效
JSS 的驼峰键名写法与限制
JSS 把伪类转成驼峰属性名,不依赖 &,但只支持有限集合,且无法表达嵌套伪类结构。
- 正确:
hover: { opacity: 0.8 }、active: { transform: 'scale(0.95)' } - 错误:
'&:hover': { ... }(JSS 不认带&的字符串键)、'focus-visible': { ... }(不支持连字符,得用focusVisible) - 不支持
&:hover &:before这类跨层级伪类联动,只能退回到普通CSS或改用模板字符串方案 - 若需
:focus-within,JSS v10+ 支持focusWithin,但旧版需手动加前缀或放弃
动态激活态(如 :focus-visible)要手动降级
CSS-in-JS 不做兼容性兜底,&:focus-visible 在 Chrome 86 以下、Firefox 80 以下直接失效,不会 fallback 到 :focus。
立即学习“前端免费学习笔记(深入)”;
- 安全写法是并行声明:
&:focus-visible, &:focus { outline: 2px solid blue; } - 不要依赖 Babel 插件自动加前缀——伪类前缀是运行时行为,插件只处理属性(如
transform),不处理选择器 - 服务端渲染(SSR)时,
:focus-visible规则仍会输出,但首次 hydration 后才生效,视觉上会有延迟 - 测试时务必在真机 Safari 和旧版 Edge 上验证,DevTools 的 “Toggle element state” 功能对
:focus-visible不可靠
真正容易被忽略的是:伪类规则是否被 CSS-in-JS 库实际注入到 DOM。有些场景下(比如条件渲染组件未挂载、theme context 断开),整个样式块都不会生成,连 &:hover 都查不到对应 class —— 此时看 DevTools 的 Styles 面板比看 React 组件树更直接。


















