react-emotion嵌套伪CSS选择器问题:为何:after作用不符合预期?
Let's break down what's happening here — this isn't an unexpected behavior from Emotion, it's a quirk of how nested CSS selectors work in preprocessors like Emotion (which follows Sass-like nesting rules).
The Root Cause
When you write nested selectors without using the & reference, Emotion treats the inner selector as a descendant selector instead of attaching it directly to the parent.
Let's compare the parsed CSS for both of your examples:
Working Code (Non-Nested)
Your first snippet:
const StyledButton = styled('button')` // Some styles here :first-child { // Some other styles } :first-child:after { content: 'F'; } `
Gets parsed to:
StyledButton:first-child { /* ... */ } StyledButton:first-child:after { content: 'F'; }
This correctly targets the :after pseudo-element directly on the :first-child of StyledButton.
Broken Code (Incorrect Nested)
Your second snippet:
const StyledButton = styled('button')` // Some styles here :first-child { // some other styles :after { content: 'F'; } } `
Gets parsed to:
StyledButton:first-child { /* ... */ } StyledButton:first-child :after { content: 'F'; }
Notice the space between :first-child and :after! This selector targets every descendant element's :after pseudo-element inside StyledButton:first-child — not the :first-child itself. That's why you're seeing the pseudo-element on all child elements.
The Fix: Use & to Reference the Parent Selector
To attach the :after pseudo-element directly to the parent :first-child selector in nested syntax, you need to use & (which represents the parent selector in Emotion/Sass):
const StyledButton = styled('button')` // Some styles here :first-child { // some other styles &:after { content: 'F'; } } `
This will parse to the exact same CSS as your working snippet:
StyledButton:first-child:after { content: 'F'; }
Now the :after pseudo-element will only apply to the :first-child of StyledButton, just like you intended.
Quick Recap
- Use
&in nested Emotion styles when you want to target the parent selector itself (not its descendants) with a pseudo-class/pseudo-element. - Without
&, nested selectors become descendant selectors, which changes the targeting scope entirely.
内容的提问来源于stack exchange,提问作者Sanjay Joshi

