-
Notifications
You must be signed in to change notification settings - Fork 27.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Native CSS nesting support for css modules #55053
Comments
FWIW you can use this PostCSS plugin in the meantime: https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-nesting |
Thank you, we have used it since 2016 but now that we have the native nesting we need to remove it to reduce the css size. |
No worries. The plugin I've linked to (postcss-nesting) supports the new official syntax, which is slightly different from what SASS uses. That syntax has its own plugin as well (postcss-nested), which is what you're most likely referring to. Doesn't make a difference in the bundle size presumably, just more future-proof. |
Yep, we have used
Yep, it affects the final CSS drastically, here is a basic example: .MyLongClassName {
color: red;
&[data-button-color="blue"] {
color: blue;
}
&[data-button-color="green"] {
color: green;
}
} All of this, when processed, becomes: .MyLongClassName { color: red }
.MyLongClassName[data-button-color="blue"] { color: blue }
.MyLongClassName[data-button-color="green"] { color: green } As you can see the parent selector is repeated over and over, now multiply this for every nested selector. Without processing the nested syntax, we just get the exact same source code in browsers: .MyLongClassName {
color: red;
&[data-button-color="blue"] { color: blue }
&[data-button-color="blue"] { color: blue }
} 139 chars minified vs. 108 chars minified. On our side, this is a vast improvement considering the amount of CSS we ship. 😌
|
Is this issue planned? Any interest? |
I hope this is planned. Native nesting has been around since March 2023, and this week we have also got relaxed nesting rules natively. I also agree with @equinusocio, I would rather not have processed CSS when its not needed and let the platform do the work when its supported. |
I would love to see this. Currently builder blocking me from using them. |
hello my I had the same problem as you and I'll show you how I solved it: In this case, nesting only works if the selector to be nested is a class or an id, but if it is the selector of a label it does not work directly, but you can solve this if you name the parent class from which you are nesting again: .Layout {
border: 10px solid red;
&.layout body {
height: 100vh;
margin: 0;
border: 10px solid blue;
}
} That is to say that as long as you start with a class or id the nesting and from then on you can call the selectors you want, it is somewhat strange but at least it solves it, but on the other hand I was very happy working this way and then I realized Note that it only works well in client components; I work with Next and it turns out that with client components, nesting CSS in this way works, but as soon as I use it in a server component it stops working, it correctly identifies the classes and their nesting, but it omits properties like flex or some others , this is even rarer, for example .dataBox {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
gap: 1rem;
color: var(--color-S01-800);
width: 100%;
border: 1px solid;
border-color: var(--color-T1-400);
border-radius: 2rem;
padding: 4rem;
.dataTitleWrapper {
display: flex;
justify-content: space-between;
align-items: center;
gap: 1rem;
width: 100%;
}
.inlineField {
width: 100%;
display: flex;
gap: 1rem;
justify-content: center;
align-items: center;
}
} In this case, all the properties related to flex in both the .inlineField and .dataTitleWrapper classes, for some reason, when checking with devtools in the browser, they do not appear as if I had not written them and therefore the styles come out wrong, but if I pass them without the nesting, everything it turns out well. but if I pass that same code to a client component everything works out fine. I DON'T UNDERSTAND ANYTHING Sorry for my English, I only speak Spanish, it's a pure translator |
I'd also like to see this feature added/allowed. |
Since this feature is not included in Nextjs yet, an intermediate solution has been propsed: using postcss-nesting plugin. |
I would love to make this work natively with CSS modules. |
Postcss-nesting is not a solution for the issue. It compiles the css by removing the nesting and duplicating the selectors. Plus by using browsers list if the target browsers support nesting, the css will stay the same (with nested css) and gives the same error. |
Would like to add to this issue - it is making a lot of UI package updates VERY difficult. In my case - migrating @Mantine v6 -> 7 to get away from the CSS-in-JS emotion style so that we are not required to 'use client' on everything. Not only am I having to convert to the css module - but finding that my nesting is not working, so I have to refactor class names on the component code and flatten my css making the task quite a bit more painful. An example that I have using css module: This doesn't apply css to the 'badge':
But the badge is a 'div' so this works oddly enough:
As a test I tried using Would be great to get basic css class nesting in place to help adoption and migration efforts. |
I'm in the same boat, build error when using CSS modules nested selector. It seems that when adding "scripts": {
"dev": "next dev --turbo"
} This results in same behaviour as the postcss-nesting package mentioned above, it at least works for local development. /* [project]/src/components/AppHeader.module.css [app-client] (css) */
.topButtons__AppHeader__9b530d28 {
position: absolute;
right: 0;
}
.topButtons__AppHeader__9b530d28 button:last-of-type {
padding-right: 0;
} This won't work for shipping production builds, as Turbopack doesn't support that yet. Would be nice to see this supported natively in Next.js 👍 |
We can't just forget about core CSS features like this while supporting the bleeding edge of React. The community at large has been anticipating built-in CSS nesting for a long time, and now Next.js devs are still waiting. |
After 5 months no response from them. I guess they don't care. |
That is very sad because it is a blocker in my agency. If we cannot trust the system to support at least the browsers core features, we cannot use it. |
Well, damn. I was hoping to switch away from SCSS because all I was using it for was the nesting syntax. |
I'm not sure what nextjs uses to parse the CSS modules, but css-loader already has fixed this same issue 2 months ago. Supposing they use css-loader, they just have to update. |
Doesn't seems a fix because CSS nesting doesn't require |
Well, the |
today ~83% of all browsers support css nesting: https://caniuse.com/css-nesting ![CSS Nesting Browser Support](https://github.com/css-modules/postcss-modules-local-by-default/assets/4113649/141f8dce-a8bd-4df4-b2bd-210252189711) https://caniuse.com/css-nesting https://developer.mozilla.org/en-US/docs/Web/CSS/Nesting_selector therefore this pr upgrades postcss-modules-local-by-default which fixes a bug in css-modules/postcss-modules-local-by-default#64) - `.foo { &:hover { a_value: some-value; } }` is pure - `.foo { html &:hover { a_value: some-value; } }` is pure - `.foo { &:global(.bar) { a_value: some-value; } }` is pure - `:global(.foo) { &:hover { a_value: some-value; } }` is **not** pure upgrading the package will allow using css nestings with or **without** postcss compilation it fixes the following error: ``` CssSyntaxError: postcss-modules-local-by-default: <css input>:1:8: Selector "&:hover" is not pure (pure selectors must contain at least one local class or id) ``` Fixes #55053 Fixes #33734 Fixes #10475 Co-authored-by: Sam Ko <sam@vercel.com>
@vicentel89 Can you try the latest |
@samcx It seems to work only with the |
@equinusocio I think this is fine—my current understanding is that CSS Modules doesn't support CSS nesting without explicitly using |
Same here. What happened to this fix? it seems fixed only in Since 14.1.1 (which should include the fix from It's also blocking everyone targeting |
@equinusocio The past two stable patch versions likely does not have this change (backported stable patch versions). The latest canary does indeed have the dependency bump. |
This closed issue has been automatically locked because it had no new activity for 2 weeks. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you. |
Link to the code that reproduces this issue or a replay of the bug
https://codesandbox.io/p/sandbox/magical-chatelet-9ddsys?file=%2Fnext.config.js%3A4%2C3
To Reproduce
Current vs. Expected behavior
Nextjs and the check it performs on CSS modules prevents from using the new CSS native nesting syntax (which is now supported by evergreen browsers).
It returns error about a simple nested CSS while this should be allowed as valid CSS syntax now.
Error:
Selector "& body" is not pure (pure selectors must contain at least one local class or id)
See the reproduction link.
Next should allow native and valid CSS syntax and avoid extra checks on "pure selectors" where not needed.
Verify canary release
Provide environment information
Operating System: Platform: linux Arch: x64 Version: #1 SMP PREEMPT_DYNAMIC Sun Aug 6 20:05:33 UTC 2023 Binaries: Node: 16.17.0 npm: 8.15.0 Yarn: 1.22.19 pnpm: 7.1.0 Relevant packages: next: 13.0.8-canary.0 eslint-config-next: N/A react: 18.2.0 react-dom: 18.2.0
Which area(s) are affected? (Select all that apply)
Not sure
Additional context
The selector
.Layout { & body {} }
should be validated as.Layout body {}
which is a "pure" css module selector.The text was updated successfully, but these errors were encountered: