emotion
emotion copied to clipboard
& + & isn't working
Current behavior:
I made a tab components using @emotion/styled, I want each tab margin left 20px except the first one. so I used & + & to refer each tab compnent I want to style. but the component isn' t styled correctly
To reproduce:
I made a example here ==> https://stackblitz.com/edit/react-pcrmlh
found that when there are some logic inside the css delcaration, classname changed, but the css rules does not response to that.

Expected behavior:
& + & should be able to refer to self correctly
Environment information:

& is equal to the class name generated for each set of properties. So the class name for your active item is different to the inactive ones. Therefore the CSS rule is not applied. You need give it a static class name and use that instead of &. Or use :not(:first-child) selector.
There is already similar issue: https://github.com/emotion-js/emotion/issues/1827
& is equal to the class name generated for each set of properties. So the class name for your active item is different to the inactive ones. Therefore the CSS rule is not applied. You need give it a static class name and use that instead of &. Or use :not(:first-child) selector.
I understant the solution, but I don't think :not(:first-child) will work because the logic inside cause generating new css rules and new classname which make the css rules which rely on sibling elements' relationship broken in this case.
I tested styled-components for the same case, it seems generating extra class name to maintain the relationship instead of breaking it.
I tested styled-components for the same case, it seems generating extra class name to maintain the relationship instead of breaking it.
Yes, they introduce extra class names to accommodate for that - we do not plan to do that though. Especially given that the preferred (by our team) way to style components is through the css prop and in this case it's just impossible to do this as styles are not owned by any particular component - there are just styles that you can apply to some components but there is no direct relationship between those 2.
I understant the solution, but I don't think :not(:first-child) will work because the logic inside cause generating new css rules and new classname which make the css rules which rely on sibling elements' relationship broken in this case.
It should work. Check this out: https://stackblitz.com/edit/react-j5jnjy
I understant the solution, but I don't think :not(:first-child) will work because the logic inside cause generating new css rules and new classname which make the css rules which rely on sibling elements' relationship broken in this case.
It should work. Check this out: https://stackblitz.com/edit/react-j5jnjy
🙈, You're right, I think I had misunderstanding of this pseudo-class, I didn't test the solution myself, thanks a lot for correcting me。😄
I tested styled-components for the same case, it seems generating extra class name to maintain the relationship instead of breaking it.
Yes, they introduce extra class names to accommodate for that - we do not plan to do that though. Especially given that the preferred (by our team) way to style components is through the
cssprop and in this case it's just impossible to do this as styles are not owned by any particular component - there are just styles that you can apply to some components but there is no direct relationship between those 2.
Mm.., I think I got your point, but I still have question, shouldn't relationship be part of styling, how relationship be represented from emotion's solution? I went throuth the docs, seem there is no clearification for that。
Creating those relationships in CSS makes styling less predictable and also might break our composition patterns. When we write this:
[fooStyles, { color: 'hotpink' }]
the expectation is that the color will be 'hotpink', but if you introduce any combinators to fooStyles or in other styles this doesn't hold true anymore, because the CSS specificity wins. For example, in React Native there are no combinators like in the CSS and people still manage to style their apps, it requires some shift of the mind, but it actually comes with good benefits. Some existing CSS design systems/styling approaches also ban those combinators, so it's not like we are alone in this.
I'm running into this now too. My workaround is that I've created wrappers in order to get the effect that I want. The wrapper's styles are always static, and the descendants have the dynamic styles. It's not ideal, and I was expecting & + & to work. A suggestion would be to create a new hash and class when encountering & styles.
Edit: the wrapper is more of a pain than I anticipated. Not only does it add an extra DOM element, bringing in some complexity when dealing with flex and grid, but sometimes I need to apply properties to those elements themselves.
Here's the cludgy fix I implemented to stop this from happening with one of my elements.
import { css, Global } from "@emotion/core"
import { cx } from "emotion"
<Global
styles={{
".panel + .panel": {
"@media (min-width: 1200px)": {
marginLeft: 16
},
"@media (max-width: 1200px)": {
marginTop: 16
}
}
}}
></Global>
const Panel = styled(({ className, ...props }) => (
<Flex {...props} className={cx("panel", className)} />
))(
css`
background-color: #1d1e20;
padding: 24px;
border-radius: 3px;
`
)
Edit: I'm still dealing with this. My cludgy workaround wasn't all that great.
Creating those relationships in CSS makes styling less predictable and also might break our composition patterns. When we write this:
I agree with you, should this be the core concept of emotion?and worth being put into the documentation if there were some code of conduct for how to solve the problem like & + & will be much better。
I having been using styled-components and attracted by the smaller size of emotion, want to give it a try. So I expected the same behavior as styled-components when I am using @emotion/styled.
hight performance、modular css、logic allowed and full styling capability is the why I choose a css in js library, I really want it to be "perfect"😂
I agree this could be documented - documentation PRs are always welcome.