Skip to content
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

Inconsistent CSS resolution order #64921

Open
GabenGar opened this issue Apr 23, 2024 · 15 comments
Open

Inconsistent CSS resolution order #64921

GabenGar opened this issue Apr 23, 2024 · 15 comments
Labels
bug Issue was opened via the bug report template. linear: next Confirmed issue that is tracked by the Next.js team.

Comments

@GabenGar
Copy link
Contributor

Link to the code that reproduces this issue

https://github.com/GabenGar/repros/blob/main/nextjs/css-out-of-order/README.md

To Reproduce

Reproduction steps are in the README.md

Current vs. Expected behavior

Current:
Different CSS resolution order between development and production. Before I had weird client vs. render CSS issues, but it looks like they are fixed in 14.2, although they weren't super reproducible before either.
Expected:
Work basically like pages router.

Provide environment information

Operating System:
  Platform: win32
  Arch: x64
  Version: Windows 10
  Available memory (MB): 7990
  Available CPU cores: 4
Binaries:
  Node: 20.9.0
  npm: N/A
  Yarn: N/A
  pnpm: N/A
Relevant Packages:
  next: 14.2.2 // Latest available version is detected (14.2.2).
  eslint-config-next: 14.2.2
  react: 18.2.0
  react-dom: 18.2.0
  typescript: 5.4.5
Next.js Config:
  output: N/A

Which area(s) are affected? (Select all that apply)

Not sure

Which stage(s) are affected? (Select all that apply)

next dev (local), next build (local), next start (local), Vercel (Deployed)

Additional context

No response

@GabenGar GabenGar added the bug Issue was opened via the bug report template. label Apr 23, 2024
@GabenGar
Copy link
Contributor Author

It seems 14.2.2 fixed this for development but not for prod.

@samcx
Copy link
Member

samcx commented Apr 24, 2024

@GabenGar Thanks for sharing a :repro:—we will be taking a look at this!

@benjitastic
Copy link

We are seeing the same issue on 14.2.2 where on production builds the CSS styles get included in an unexpected order.

The specific example we are seeing is that CSS styles imported into layout.js are overriding CSS styles set in a component level stylesheet even though they have the same CSS specificity and the component CSS should override the layout's CSS. This bug appears to be due to the order that the CSS is included in the final static .css files that are included in the production build.

@samcx
Copy link
Member

samcx commented May 1, 2024

@benjitastic What kind of CSS styling are you using in this case (e.g., css modules)?

@benjitastic
Copy link

benjitastic commented May 2, 2024

@benjitastic What kind of CSS styling are you using in this case (e.g., css modules)?

No, not modules. Just like this inside the component:

import './styles.css'


Some more details:

In this case layout.js had this at the top:
import '@/styles/customTheme.scss'

And customTheme.scss had this inside it:
@import 'bootstrap/scss/bootstrap';

That bootstrap file has a css style declared for .btn like this:
.btn { padding: .375rem .75rem }

Then in the component we have an element <button className="btn filter-pill"> and that component includes a styles.css. Inside that styles.css there's this declaration: .filter-pill { padding: 8px 33px 8px 14px }

The expectation is that .filter-pill padding can override .btn padding. But .btn was overriding .filter-pill styles. This was because of the 5 /_next/static/css/*.css files appearing in the DOM the 1st one contained .filter-pill and the 2nd one contained .btn. This is backwards from expected order. Regardless of it they are in the same static CSS file or not the .btn declaration should come before the .filter-pill declaration.

Hard to post a repro since I think you need a project that has enough CSS to result in multiple static CSS files being generated.

We reverted back to 14.1.4 and the CSS went back to the correct order.

@github-actions github-actions bot added the linear: next Confirmed issue that is tracked by the Next.js team. label May 13, 2024
@paulyi
Copy link

paulyi commented May 16, 2024

I am seeing this issue as well, particularly for global styles as well as styles using css modules. As mentioned in this issue, it only happens in production builds.

@dstaley
Copy link
Contributor

dstaley commented May 22, 2024

Setting experimental: { cssChunking: 'strict' } in next.config.js resolves this issue for us. Not ideal, but better than broken CSS ordering in production!

@benjitastic
Copy link

benjitastic commented May 22, 2024

Setting experimental: { cssChunking: 'strict' } in next.config.js resolves this issue for us. Not ideal, but better than broken CSS ordering in production!

Interesting -- I can't find any docs anywhere on the cssChunking parameter.

Does anybody know exactly what "strict" css chunking does?

@Netail
Copy link
Contributor

Netail commented May 23, 2024

Setting experimental: { cssChunking: 'strict' } in next.config.js resolves this issue for us. Not ideal, but better than broken CSS ordering in production!

It does not seem to resolve the issue for us :(

@paulyi

This comment has been minimized.

@samcx
Copy link
Member

samcx commented May 24, 2024

@Netail Thanks for sharing.

Are there any updates on this issue from the nextjs team?

I can confirm there are several broken cases with the ordering of CSS, after looking at several :repro:s. We've been busy with the 15 release—since that's out of the way, we will be prioritizing this!

Does anybody know exactly what "strict" css chunking does?

Getting some answers internally to further clarify this—will respond back soon!

@Netail
Copy link
Contributor

Netail commented May 24, 2024

That would be great. We use a design system package and a navigation package which uses the design system package (with some overrides) and the app using the design system, but the overwrites are currently not working on productions. Thus making NextJS kind of unusable currently for us. So the sooner the better 😅

Do you by any chance have a ETA when development on this will happen?

@mrabuse
Copy link

mrabuse commented May 28, 2024

Can confirm this issue also comes up in a project using Next.js 14.2., Mantine v7.10 components, and css modules. Works fine in development mode, loads incorrectly in production.

@michaelkostal
Copy link

michaelkostal commented May 29, 2024

I had a similar issue, where global styles were bundled after component styles. Running dev I never had an issue, only on production. I'm using Next 14.2.2 with App router and SSG.

My workaround is only for getting global scss that's imported in layout.js to load ahead of client component scss modules. But perhaps this will be helpful for someone else / debugging the overall issue.

In my root layout.js I was importing /global.scss

There is an @import css rule in there that should be loaded first since that is the first css imported on the page and before any components. However, in dev tools I had the following Issue: An @import rule was ignored because it wasn't defined at the top.

Indeed there was css rules added above the global.scss.

After analyzing it seems that the css above my @import was all related to client components. This led me to believe that next must prioritize client component styles when bundling css during production builds.

My workaround fix is to make a new client component that imports the styles

"use client";

import "@/scss/global.scss";
const GlobalStyles = () => {
    return <></>;
};

export default GlobalStyles;

and then import that component in my root layout.js

import GlobalStyles from "./GlobalStyles";
export default function RootLayout({ children }) {
    return (
        <html lang="en">
            <GlobalStyles />
            <body>
                {children}
            </body>
        </html>
    );
}

This resolved the issues I was getting in dev tools, and also some issues with specificity (component styles were no longer overriding global styles before the workaround).

@samcx
Copy link
Member

samcx commented May 29, 2024

Do you by any chance have a ETA when development on this will happen?

@Netail No ETA to share yet, but this issue is definitely high on our plate!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Issue was opened via the bug report template. linear: next Confirmed issue that is tracked by the Next.js team.
Projects
None yet
Development

No branches or pull requests

8 participants