React使用@emotion/styled如何实现.tooltip .tooltiptext的嵌套样式
@emotion/styled 实现后代嵌套样式的方案
对应传统CSS中 .父类 .子类 的嵌套选择器逻辑,@emotion/styled 提供了两种无额外配置的实现方式,完全可以1:1复现你原来的tooltip效果:
方案一(官方推荐):直接在父级样式中引用子级Styled组件
这是Emotion设计中最贴合组件化思路的写法,不需要手动声明任何类名,编译后生成的CSS选择器和原生的 .tooltip .tooltiptext 行为完全一致:
- 先定义对应提示文本的子级样式组件,把原来
.tooltiptext的基础样式写入:const TooltipText = styled('span')` visibility: hidden; width: 120px; background-color: black; color: #fff; text-align: center; border-radius: 6px; padding: 5px 0; position: absolute; z-index: 1; top: 100%; left: 50%; margin-left: -60px; ` - 在父级
TooltipContainer的样式块中,直接把${TooltipText}作为选择器写入嵌套样式即可:const TooltipContainer = styled('div')` position: relative; display: inline-block; border-bottom: 1px dotted black; /* 这部分编译后就是等价于 .tooltip .tooltiptext 的后代选择器 */ ${TooltipText} { visibility: hidden; } ` - 组件使用方式和原生HTML结构完全对应,不需要给组件手动传任何类名:
function Tooltip() { return ( <TooltipContainer> Hover over me <TooltipText>Tooltip text</TooltipText> </TooltipContainer> ) }
这种写法的优势是没有硬编码的类名耦合,TypeScript 可以对组件引用做类型检查,不会出现类名拼写错误、样式污染的问题。
方案二:兼容传统类名写法(适合旧代码迁移)
如果是从原生项目迁移、不想拆分子组件为Styled组件,也可以直接在父级样式块中写和传统CSS完全一致的类选择器:
const TooltipContainer = styled('div')` position: relative; display: inline-block; border-bottom: 1px dotted black; /* 和原生CSS写法完全一样 */ .tooltiptext { visibility: hidden; width: 120px; background-color: black; color: #fff; text-align: center; border-radius: 6px; padding: 5px 0; position: absolute; z-index: 1; top: 100%; left: 50%; margin-left: -60px; } `
对应的JSX只需要给内部的span加上className="tooltiptext"即可,行为和原原生CSS完全一致。
注意:不要硬编码Emotion自动生成的带hash的类名做选择器,这类类名每次构建都会随机变化,硬写的样式不会生效。
内容的提问来源于stack exchange,提问作者James Arnold
相关产品推荐
相关产品推荐

