Closed BMCwebdev closed 5 years ago
The following will work, it just doesn't work in CodePen as the output code there has more text tacked onto it, and it hashes the const names all over again. But if you test in your own code base, this does work. I don't like doing it, it feels hacky. Would like Emotion to have something specific for these instances.
const cat = css`
color: red;
`;
const dog = css`
color: green;
.css-${cat.name} {
border-bottom: 1px solid currentColor;
}
`;
This isn't totally safe, mind you. If you are rendering subcomponents, they will not always get the same hashed class name. Additionally it also seems that Emotion will tack on the subcomponents name to the end of the hashed class name to avoid clashing I assume. So, proceed with caution. What I would really like is for Emotion to return the functionality it had in V.9 - an example of which is found in their V9 documentation, last example on this page:
https://5bb1495273f2cf57a2cf39cc--emotion.netlify.com/docs/nested
Yes, I agree this is needed! We can target with styled, but then composition is not as easy.
Workaround: use pre-generated name and object css.
const child = css`
color: green;
`;
const parent = css({
color: 'red',
[`.${child}`]: {
color: 'yellow',
},
});
I'm trying your suggestion, @TerenceZ , but I am not having any luck. The nested child styles do not appear to work.
If you use the /macro
or Babel preset you can reference other styled components in your selectors.
const Foo = styled.div``;
const bar = styled.div`
${Foo} {
color: red;
}
`;
If you want to use the syntax posted in your original post, you must make sure to use the emotion
package, not the React-specific @emotion/css
or @emotion/styled
ones, because they don't directly generate class names, but objects not meant to be consumed by 3rd party code.
I hope this answers your question!
@FezVrasta @mitchellhamilton Could this breaking change be referenced in the Emotion documentation? I have not seen anything written on it. On the page about migration, we could add a text explaining the need to use the babel-plugin-macros to keep "styled children target" work.
@thibaultboursier being able to use styled components as selector has always been a babel-powered feature
@Andarist Sure (https://emotion.sh/docs/styled#targeting-another-emotion-component). But we could add some information to say explicitly that it does not work anymore with Emotion 10.
This should very much work with Emotion 10. Maybe you experience some misconfiguration problem? Could you prepare a repro case on which I could take a look?
is there any solution to this? I am trying to achieve something like
const A = css`
// ...some style
`;
const B = css`
// some style
.${A} & {
// some update style
}
`;
but it seems that it doesn't work at all
@LXSMNSYC Does this work for you? It seems hacky and is recommended against above in this thread.
const A = css`
// ...some style
`;
const B = css`
// some style
.css-${A.name} & {
// some update style
}
`;
@ksweetie not with the emotion
package, it returns a string
Some update?
I don't think this is going to be changed. And the way I work with Emotion now, I wouldn't need it anymore. What is the use case you are trying to solve for @rochagbr ?
I also would like support for this feature. Coming from Emotion 9, having to update my entire CSS because of the drop in support for this is a HUGE pain. Styled components and standard CSS support nested selectors so why can't this as well?
The most common use case for me is when a parent component changes state, which affect the style of its children. Instead of adding a new class to every single one of them, I just have to add it to said parent, and select these children using nested selectors. As a plus, all the style changes are grouped up in one place in the code, which eases visibility.
Hello @BMCwebdev,
How would you write this code? I have nested classes in scss and not sure how to write it out in emotion.
.site-header {
padding: $spacing-m 0;
position: relative;
z-index: 10;
background: $white;
.site-signin {
line-height: 1.4rem;
color: $color-interface-light;
text-transform: capitalize;
background-color: $white;
box-sizing: border-box;
border-radius: 7rem;
position: absolute;
top: 1.6rem;
left: 1.6rem;
text-decoration: none;
}
.site-myaccount {
font-family: $text-font-ef;
background-color: $white;
border: none;
position: absolute;
top: 1.6rem;
left: 1.6rem;
font-size: 0;
&::after {
content: attr(data-username);
color: $white;
font-size: 1.6rem;
background-color: $crest-blue;
border-radius: 7rem;
width: 3.4rem;
height: 3.4rem;
display: inline-block;
line-height: 3.4rem;
text-align: center;
}
}
How do you work with emotion now?
Any help is much appreciated!
Thanks, Dan
Any update on this?
Is there a doc reference for add .css-
prefix?
There are a few ways to handle this in the latest version of Emotion (Emotion 11):
@emotion/css
, which produces normal class names.@emotion/babel-plugin
).import { css } from '@emotion/react'
const myCss = css`
div {
p {
color: red;
}
}
`
If none of these solutions help you and you think there is a need for a new feature to support this, please open a new issue.
Any update?
Silently breaking the api, and removing support of existing features, is incredibly frustrating.
I was lurking for a solution as well and ended up using emotion's labels feature and CSS attribute selectors. It's not pretty, but it works, and it's not as fragile, as that trick with .css-${style.name}
.
import { css } from '@emotion/react'
const parentCss = css`
color: red;
[class$="child"] {
color: yellow;
}
`
const childCss = css`
label: child;
color: green;
`
export default function Preview() {
return (
<>
<div css={parentCss}>I am red</div>
<div css={childCss}>I am green</div>
<div css={parentCss}>
<div css={childCss}>I am yellow</div>
</div>
</>
)
}
Thanks for the take, @norskeld!
Though, I'm afraid this solution is also a bit flaky - in a real project, with a substantial component tree, naming collisions are inevitable (how many false positives will this selector class$="child"
catch?)
I'm surprised this thread is closed and disregarded :\
is there any way to style class inside another element/class in object css?
Thanks for the take, @norskeld! Though, I'm afraid this solution is also a bit flaky - in a real project, with a substantial component tree, naming collisions are inevitable (how many false positives will this selector
class$="child"
catch?)I'm surprised this thread is closed and disregarded :\
I am also really surprised by the sparse documentation in this Emotion provides on this topic. Especially, because many of those consuming this project are transitioning from CSS or SASS into CSS-in-JS solutions like Emotion.
Previously in Emotion 9 you were able to use Emotion class names to take advantage of cascade. You would wrap the emotion const in curly brackets and prefix it with a period, and then dollar sign. For example, you could do this:
How can I go about achieving this behavior in Emotion 10? That is my question.
The following is further information about what happens when you don't use a period-dollar sign.
Now, the following was and is desirable: if no period are used in Emotion 9 or 10, the parent const will inherit the nested const styles. And furthermore, if that nested const then has overriding styles, those would ultimately be inherited by the parent.