compiled
compiled copied to clipboard
Decide on long-term solution on ampersand in CSS selectors (e.g. `:hover` and `&:hover`) in `styled` and `css` APIs
ty @kylorhall-atlassian for bringing this up internally and for providing the examples.
With SCSS and the upcoming CSS Nesting module, there is a distinction made between:
-
:hover
(targeting a child element, like.class :hover
or.class *:hover
) and -
&:hover
(targeting the current element, like.class:hover
)
Examples include SCSS and CSS Nesting module
The Compiled css
and styled
APIs treat both :hover
and &:hover
as targeting the same element (self), instead of a child element. In other words, a developer may write this without realising that both color
and backgroundColor
are actually targeting the same <div>
element:
<div css={css({
':hover': { color: 'blue' }
'&:hover': { backgroundColor: 'pink' }
})}>Hello world</div>
On the other hand, cssMap
and xcss
only allow &:hover
, with :hover
not being valid according to the typescript types: https://github.com/atlassian-labs/compiled/blob/9857009f59f2089ca8c026745f3070b0e7b02e4c/packages/react/src/types.ts#L45
Perhaps we should change css
and styled
to forbid :hover
, and only allow &:hover
. Of course, this doesn't just affect :hover
, but also every other CSS selector that exists.
Potential solutions:
- Create ESLint rule to convert all ampersand-less selectors to ampersand-ful ones. Then require the ampersand-ful version
&:hover
through typing and runtime checks, in time for v1 release.- Recommended for consistency with CSS Nesting, Emotion(?),
xcss
andcssMap
APIs, Sass, etc.
- Recommended for consistency with CSS Nesting, Emotion(?),
- The above solution, but instead, converting all ampersand-ful selectors to ampersand-less ones.
- Not sure if there are any pros to this
Unresolved problems:
- What if a developer wants to use
:hover
for a child element?- Potential solution: discourage them from doing this in the first place (only allow styles to apply to the current element), or use
*:hover
as a workaround instead?
- Potential solution: discourage them from doing this in the first place (only allow styles to apply to the current element), or use