Next.js Discord

Discord Forum

Quirks of CSS import order

Unanswered
Rhinelander posted this in #help-forum
Open in Discord
Avatar
RhinelanderOP
Are there any gotchas I should be aware of in terms of import ordering of CSS files between server and client components?

I’m encountering an issue where the imports of global (external) CSS files are happening out of order and I’m unsure if there’s some quirk about client-side components I should be aware of that would be affecting when my styles are loaded .For example, are client-component styles always imported first by default, regardless of the order of imports in my files?

I’ve followed Next.js' guidelines for import ordering but it doesn’t seem to be entirely accurate for my application: https://nextjs.org/docs/app/building-your-application/styling#ordering-and-merging.

Here’s a brief example:

// layout.tsx - server component
import { ReactNode } from "react"
import "external-css-library" // this is an example external library
import "./globals.css;
import BaseLayout from "@/components/BaseLayout/index"

const RootLayout = ({
   children
}: Readonly<{ children: ReactNode }>) => (
  <html lang="en">
    <body>
      <BaseLayout>{children}</BaseLayout>
    </body>
  </html>
);


// BaseLayout.tsx - server component
import Hero from "./Hero/index" // server component
import Sidebar from "./Sidebar/index" // client component
import { ReactNode } from "react"
import "./style.module.css"

// slimmed down example
const BaseLayout = ({ children }: { children: ReactNode }) => (
  <>
    <Hero />
    <Sidebar />
    {children}
  </>
);


In this example, the stylesheets are being imported like so:
1. BaseLayout.tsx imports Sidebar/styles.module.css (the only use client component)
2. layout.tsx import for the external library
3. layout.tsx import for ./global.css and BaseLayout.tsx imports Hero/styles.module.css and it's own stylesheet.

Why despite the BaseLayout being listed as the last import within layout.tsx does it's client component import it's stylesheets first?

5 Replies

Avatar
RhinelanderOP
bump
Avatar
Harrier
I think it shouldn't really matter, as once CSS loads, it's browser job to apply the styles. As long as the styles don't collide (that is you have the same selector defined in both files) you'll be fine.

It's natural that the files requested by the browser won't always follow the same order and stressing too much about it - unless there's a real problem - doesn't really add much value.
Avatar
RhinelanderOP
Hi Kuba 👋, thanks for the response. I’ve opened the thread because I’m looking for more information to resolve my situation.

I’m using an external library whose global styles are meant to load as the base styles for the project. Custom styles can then be applied on top of this libraries design system, following the natural cascade. However, if the global styles of this external library are not loaded at the root, then any custom styles I write will be overridden without increasing specificity with !important (for example).

This is atypical in terms of import expectations and the Next.js docs discuss import ordering having a direct impact on when stylesheets load:

“The CSS order is determined by the order in which you import the stylesheets into your application code.” (https://nextjs.org/docs/app/building-your-application/styling#ordering-and-merging)

The information seems accurate when it comes to an app that has server components only but when client components are introduced, the import ordering does not seem to take the same effect (for my specific case), and becomes unintuitive. My question is meant to address the mental model I should have when it comes to stylesheet import order in a hybrid app, so that I can combat any situation where the order causes conflicts with custom styles.

Do you have any insight or suggestions? Thanks for your time
Avatar
Harrier
Hi Brian 👋 this changes a matter a bit. I've personally never run into such issues, but now I understand why it matters.

Have you tried resolving it with CSS @layer? It seems that you could put external CSS into one layer, and your own into another one. This potentially would allow you to control the cascading of styles.

https://developer.mozilla.org/en-US/docs/Web/CSS/@layer
https://caniuse.com/?search=layer
Quick glance and short brainstorming hint me, that you could define a layer, which uses CSS @import to import the external styles, then order them as needed

Multiple layers can be defined at once, as shown below:
@layer theme, layout, utilities;

This is useful because the initial order in which layers are declared indicates which layer has precedence. As with declarations, the last layer to be listed will win if declarations are found in multiple layers. Therefore, with the preceding example, if a competing rule was found in theme and utilities, the one in utilities would win and be applied.