Quirks of CSS import order
Unanswered
Rhinelander posted this in #help-forum
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:
In this example, the stylesheets are being imported like so:
1.
2.
3.
Why despite the
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 library3.
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
RhinelanderOP
bump
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.
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.
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 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
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
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
https://developer.mozilla.org/en-US/docs/Web/CSS/@layer
https://caniuse.com/?search=layer
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 neededMultiple 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 intheme
andutilities
, the one inutilities
would win and be applied.