vercel / next.js

The React Framework
https://nextjs.org
MIT License
124.88k stars 26.66k forks source link

Verify CSS import ordering #16630

Closed Timer closed 10 months ago

Timer commented 4 years ago

A user on twitter reported that Next.js may not order CSS imports from JS correctly. We need to investigate and fix this!

https://twitter.com/samselikoff/status/1299032241100787712

NEXT-1350

santiagoRebella commented 4 years ago

this is still happening to me

santiagoRebella commented 4 years ago

@Timer I tried with latest versions including the v9.5.4-canary.5 the issue still there, I am importing global.scss from _app.js and then I have different scss module files. with yarn dev the order is correct, but when doing yarn build && yarn start the order gets changed, so for example, the global bootstrap classes override module classes as is loaded after

Screen Shot 2020-09-07 at 12 06 56 PM Screen Shot 2020-09-07 at 12 07 10 PM Screen Shot 2020-09-07 at 12 08 46 PM
santiagoRebella commented 4 years ago

could be related to https://github.com/vercel/next.js/issues/16723

Aichnerc commented 3 years ago

Hey! I'm having trouble with that too. See my repo for my code and Stackoverflow for my problem.

sunoj commented 3 years ago

same here

kenaku commented 3 years ago

Nextjs is one of the greatest things in JS landscape, thanks for great work!
Also this bug is killing me, we have a pretty big app with millions of users and update from 9.0.3 to 9.5.5 broke our app in so many places, I cant even imagine how to hotfix this... Please, fix this 🙏

usamamashkoor commented 3 years ago

Did anyone find any solution for this?

sunoj commented 3 years ago

i create a new css file:style.css and manual import css like the code below, replace the css import in _app.tsx before.

`@import './node_modules/@hackplan/uui/lib/index.css'; @import './node_modules/react-weui/build/packages/react-weui.css'; @import './node_modules/react-image-gallery/styles/css/image-gallery.css';

@import './static/css/app.css';

.style { color: aliceblue; }`

then add import '../style.css' in _app.tsx

usamamashkoor commented 3 years ago

Thanks, @sunoj but it did not work out for us.

ghost commented 3 years ago

same here

next@10 react@17

uthd-dev commented 3 years ago

I believe I have this issue as well

klaemo commented 3 years ago

Is there anything we can do to help resolve this issue?

iksent commented 3 years ago

I can confirm this bug exists at 10.0.3 also! Reproduction is here: #19055 Just can't use Next.js due to such annoying bug: I am using CSS Modules so can't order styles manually and only one possible fix is to add "!important", but for some projects this is a really inconvenient, for some - just impossible.

My own example:

2020-12-15_12-18-29

newtoniumx3 commented 3 years ago

same here, huge issue for us

klaemo commented 3 years ago

I've seen some improvement when going from 10.0.3 -> 10.0.5, but there remain cases where this bug occurs.

phbetbeze commented 3 years ago

I still have the same issue with 10.0.5. Order is still broken

Gilbert09 commented 3 years ago

Also a problem for me on 10.0.5. Temp fixed the issue with throwing in !important everywhere the ordering was broken

omarabid commented 3 years ago

Same issue version 10.0.5. How to disable code-splitting?

edgardz commented 3 years ago

For me, the problem was I had a global wrapper component imported on _app.js. It contained a navbar and a footer component and rendered the children in the middle. It seems there is not a CSS order problem, but a CSS class duplication problem, because while inspecting the build output I was able to see some classes from the global chunk being redeclared in the page chunk, and since the page chunk is added to the HTML after the global one, it caused some styles to be overwritten. My solution, for now, is to avoid importing any component inside _app.js, instead, I added my wrapper to every page. Not so DRY, but it is working now...

alexandre-marchina commented 3 years ago

@edgardz your case seems to be the same we're discussing here https://github.com/vercel/next.js/issues/20203. In our particular scenario, we're experiencing both: the duplication occurs by using components with style inside _app.js (and thus there's a style chunk created for the "_app.js"), and the chunk responsible for the "_app.js" style is ordered after the page chunk, causing the rewrite in different classes (global ones), like the comment from @santiagoRebella https://github.com/vercel/next.js/issues/16630#issuecomment-688382667

edgardz commented 3 years ago

@edgardz your case seems to be the same we're discussing here #20203. In our particular scenario, we're experiencing both: the duplication occurs by using components with style inside _app.js (and thus there's a style chunk created for the "_app.js"), and the chunk responsible for the "_app.js" style is ordered after the page chunk, causing the rewrite in different classes (global ones), like the comment from @santiagoRebella #16630 (comment)

Yup. I just checked and my solution is making the component to be re-rendered at each navigation as described in the other issue. So now I changed it a bit, instead of adding the Layout to the render function, I just import it at each page. It is a workaround... Hope they fix this soon.

spaghettiguru commented 3 years ago

We are experiencing the same problem. Did anybody manage to solve this?

theivanfranco commented 3 years ago

+1 on this thread. When will this be fixed?

AlexandrKolesnikov commented 3 years ago

+1

ViktorSoroka07 commented 3 years ago

+1

Capeleto commented 3 years ago

I had a similar issue using postcss, and it was an issue occurring in prod and dev environments.

If I had a nested rule, the nested rule was created before the actual class rule, and with that, the nested rule was overwritten by the class one, and it also happened with media-queries.

so if I had a css file like:

.someClass {
  background-color: red;

  &Blue {
    background-color: blue;
  }
}

My css result was:

.someClassBlue {
  background-color: blue;
}

.someClass {
  background-color: red;
}

I was using Next 10.0.7 and the plugin that was causing an issue for me was: postcss-nested.

I Changed postcss-nested for precss and it solved my issue, so if you are experiencing some weird-ass css ordering with postcss you can try removing some plugins and see if things get to work.

If you are using postcss, you can also add postcss-sorting and try fixing it by force.

wenerme commented 3 years ago

extract import to css works in webpack4

@import '~normalize.css/normalize.css';
@import '~@blueprintjs/icons/lib/css/blueprint-icons.css';
@import '~@blueprintjs/core/lib/css/blueprint.css';
@import '~@blueprintjs/select/lib/css/blueprint-select.css';
@import '~@blueprintjs/datetime/lib/css/blueprint-datetime.css';
@import '~@blueprintjs/popover2/lib/css/blueprint-popover2.css';
@import '~@blueprintjs/table/lib/css/table.css';
@import '~tailwindcss/tailwind.css';
@import '~nprogress/nprogress.css';

If enable webpack5 feature, this will not works.

Pranav2612000 commented 3 years ago

Has this been fixed?

yenicelik commented 3 years ago

any update?

marcos-abreu commented 3 years ago

I'm having the same issue. This is the first project I work using NextJS and this is making it impossible to proceed. I don't know if this is an issue with a specific configuration (even though my project is really barebones now) or if this issue is affecting everyone.

I would assume that is not affecting everyone, otherwise it would be impossible for others to complete any project, so I will try to start a new project and only import a global css and a module css and check the order with build and export.

If anyone has a solution for this please let me know, currently this is the only issue blocking me from using NextJS

oaa97181 commented 3 years ago

Saaaame "next": "^11.0.1", "react": "^17.0.2",

Only hotfix i found out is to throw an !important on every css module class that's broken.

clementbiron commented 3 years ago

Same here. Is there any workaround who doesn't use !important ?

Hellaeh commented 3 years ago

The only clean workaround\solution i found is: 1) Do not override previous CSS rules 2) Use conditional styles like, row ? Style.flexRow : Style.flexColumn in component itself. ("row" is a prop)

Works well if you writing your components from ground up. For example:

const Flex = ({ className, row, ...rest}) => {
  ...
  const style = classNames(Style.flex, row ? Style.row : Style:column) //classNames is a helper function.
  return <div className={style} {...rest}/>
}

Use !important as a last resort.

clementbiron commented 3 years ago

The only clean workaround\solution i found is:

1. Do not override previous CSS rules

2. Use conditional styles like, `row ? Style.flexRow : Style.flexColumn` in component itself. ("row" is a prop)

Works well if you writing your components from ground up. For example:

const Flex = ({ className, row, ...rest}) => {
  ...
  const style = classNames(Style.flex, row ? Style.row : Style:column) //classNames is a helper function.
  return <div className={style} {...rest}/>
}

Use !important as a last resort.

Thanks for your reply.

Very often we have to overload styles (with a css reset for example or a third party library) and it is essential to respect the loading order.

oaa97181 commented 3 years ago

The only clean workaround\solution i found is:

1. Do not override previous CSS rules

2. Use conditional styles like, `row ? Style.flexRow : Style.flexColumn` in component itself. ("row" is a prop)

Works well if you writing your components from ground up. For example:

const Flex = ({ className, row, ...rest}) => {
  ...
  const style = classNames(Style.flex, row ? Style.row : Style:column) //classNames is a helper function.
  return <div className={style} {...rest}/>
}

Use !important as a last resort.

Thanks for your reply.

Very often we have to overload styles (with a css reset for example or a third party library) and it is essential to respect the loading order.

@clementbiron what third party libraries have you used that actually work/fix this problem? And also... how do you make a css reset? Does it work with this threads problem? :D

clementbiron commented 3 years ago

The only clean workaround\solution i found is:

1. Do not override previous CSS rules

2. Use conditional styles like, `row ? Style.flexRow : Style.flexColumn` in component itself. ("row" is a prop)

Works well if you writing your components from ground up. For example:

const Flex = ({ className, row, ...rest}) => {
  ...
  const style = classNames(Style.flex, row ? Style.row : Style:column) //classNames is a helper function.
  return <div className={style} {...rest}/>
}

Use !important as a last resort.

Thanks for your reply. Very often we have to overload styles (with a css reset for example or a third party library) and it is essential to respect the loading order.

@clementbiron what third party libraries have you used that actually work/fix this problem? And also... how do you make a css reset? Does it work with this threads problem? :D

the only workaround i know is to use !important

rumsky commented 3 years ago

I solved it,inspired by this: https://github.com/SolidZORO/mkn/blob/master/src/pages/_app.tsx Disable ssr transition,add these lines code:

In _document.tsx:

export const DISABLE_SSR_TRANSITION = "disable-SSR-transition"; 
...
<body>
  <Main />
  <NextScript />
  <style
    id={DISABLE_SSR_TRANSITION}
    // eslint-disable-next-line react/no-danger
    dangerouslySetInnerHTML={{
      __html: "*, *::before, *::after { transition: none !important; }",
    }}
  />
</body>

In _app.tsx:

import { DISABLE_SSR_TRANSITION } from "./_document";

export const isServer = () => typeof window === "undefined";
function MyApp({ Component, pageProps }: AppProps) {
useEffect(() => {
// avoid CSS animation flashing
if (!isServer()) {
const disableTransitionDom = document.getElementById(DISABLE_SSR_TRANSITION);

  if (disableTransitionDom) disableTransitionDom.remove();
}
}, []);

return <Component {...pageProps} />;
}
export default MyApp;

Thanks to @SolidZORO

santiagoRebella commented 3 years ago

The simplest solution is to wrap your component styles in the scss with #__next { your styles }, no need to complex refactors

pak-ferry commented 3 years ago

@santiagoRebella Wow, Wrapping my CSS classes into one component style really fixed my case! And yes, for now. Thanks!

GalInvesting commented 3 years ago

Wrapping my scss file with #__next didn't help, any news regarding this issue?

ShahriarKh commented 3 years ago

I'm using 11.1.0 and still have this issue.

my code is like this:

import css from "./file.module.scss";

<div className={css["felan"]}>
   <p> has no class </p>
</div>

the div has correct css order: file.module.scss > global.scss but p doesn't: global.scss > file.module.scss

Kamleshpaul commented 2 years ago

i'm using nextjs12 and used bootstrap/dist/css/bootstrap.min.css in my application so we i want to overwrite some css from bootstrap it is not working in dev everything works fine but in prod having issue

EmirBoyaci commented 2 years ago

@Timer having that same issue. We were using Next.js@11.1.2 and it wasn't the case but I updated Next.js@12.0.7 after that we face with this issue. That issue is only works in production, dev is fine. Could you please check that?

slorber commented 2 years ago

@timneutkens @sokra have you been able to investigate a bit this issue and know where this might come from?

We have a quite similar CSS ordering problem on Docusaurus with Webpack 5 and a single CSS file output: https://github.com/facebook/docusaurus/pull/6227

What I see is that:

cgarrovillo commented 2 years ago

The simplest solution is to wrap your component styles in the scss with #__next { your styles }, no need to complex refactors

@santiagoRebella @penguin-io Care to give more insight on this? Wrapping the class in the .scss? In the import?

cgarrovillo commented 2 years ago

Is this still on the radar @timneutkens? From what I've gathered researching in the past hour, any references to this issue is either

  1. closed as "resolved" despite many others claiming the issue still exists ( https://github.com/vercel/next.js/issues/10148, https://github.com/vercel/next-plugins/issues/399 )
  2. Removed from milestones, seemingly not added again (https://github.com/vercel/next.js/milestone/66, https://github.com/vercel/next.js/milestone/69)

And as others have also said, workarounds like !important flags could only go so far, and a large refactor like say migrating to CSS in JS is not a single day task in a production application

timneutkens commented 2 years ago

Yes, @sokra is currently working on built-in CSS support in webpack which will solve this.

Regarding 2. we no longer use milestones to track issues.

heylols commented 2 years ago

Am also facing the issue: https://github.com/vercel/next.js/issues/34264 Only in v12 in PRODUCTION. Works fine in v11

Any solutions other than using !important ?

Kamleshpaul commented 2 years ago

@heylols for now i manage to work this by. app.scss in _app.tsx

then inside app.scss import all th css in right order i m using nextjs 12

visnup commented 2 years ago

For Next 12, a version of this bug occurs with any css files imported in _app that begin with an @import line. I have a reproduction at https://codesandbox.io/s/cold-cookies-23gxz?file=/pages/green.css:

There are two CSS files being included in the intended order in _app.js: red then green. In development, you see a green page. When you build the app with next build and view the page yarn start -p 3001 the background changes to red because the order of CSS changes.

Expected behavior: the presence of @import on the very first line of a CSS file should have no impact on the ordering of the CSS.

👉 Workaround: simply adding a comment or newline before the @import in green.css or removing the line fixes the issue.