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

Component styles are overridden when rendered inside Next.js layout #199

Closed
corydeppen opened this issue Aug 7, 2024 · 4 comments · Fixed by #226 · May be fixed by #240
Closed

Component styles are overridden when rendered inside Next.js layout #199

corydeppen opened this issue Aug 7, 2024 · 4 comments · Fixed by #226 · May be fixed by #240
Assignees
Labels
bug 🐛 Something doesn't work nextjs

Comments

@corydeppen
Copy link

corydeppen commented Aug 7, 2024

Steps to reproduce

Review the styles being applied to the nav links in the mobile appbar of both Next.js and Vite versions of the example app. Observe how the styles are incorrect when on the home page of the Next app but are correct on the about page.

Current behavior

I've run into an issue that appears when using the Next.js plugin but doesn't exist when using the Vite plugin. As you'll see in the example app, the nav links in the appbar drawer on mobile don't have the correct alignment or padding specified by the ListItemButton styles. However, if you flip to the About page and inspect the links in the drawer, you'll see the ListItemButton styles are being applied as expected.

From what I can tell, it looks like the Next.js plugin is generating styles at a route file level (e.g. page.tsx, layout.tsx) instead of at a component/module level like the Vite plugin appears to do. In the Next app, (public)/page.tsx has another Button on the page so the base button styles from page.tsx take precedence over the styles being generated for layout.tsx that renders the SiteAppBar component containing the links. In the Vite example app, though, the styles are being generated separately for the site-app-bar.tsx module and take precedence so the ListItemButton alignment and padding are applied as expected.

Expected behavior

Styles for components rendered within Next.js layout components should not be overridden by those in page components.

Context

No response

Your environment

npx @mui/envinfo
System:
  OS: Linux 5.0 undefined
Binaries:
  Node: 18.20.3 - /usr/local/bin/node
  npm: 10.2.3 - /usr/local/bin/npm
  pnpm: 8.15.6 - /usr/local/bin/pnpm
Browsers:
  Chrome: Not Found
npmPackages:
  @emotion/react:  11.13.0 
  @emotion/styled:  11.13.0 
  @mui/core-downloads-tracker:  6.0.0-dev.240424162023-9968b4889d 
  @mui/icons-material: 6.0.0-beta.4 => 6.0.0-beta.4 
  @mui/material: 6.0.0-beta.4 => 6.0.0-beta.4 
  @mui/material-pigment-css: 6.0.0-beta.4 => 6.0.0-beta.4 
  @mui/private-theming:  6.0.0-beta.4 
  @mui/styled-engine:  6.0.0-beta.4 
  @mui/system:  6.0.0-beta.4 
  @mui/types:  7.2.15 
  @mui/utils:  6.0.0-beta.4 
  @types/react: ^18.2.47 => 18.3.3 
  react: ^18.2.0 => 18.3.1 
  react-dom: ^18.2.0 => 18.3.1

Search keywords: nextjs vite plugin layout components override

@corydeppen corydeppen added the status: waiting for maintainer These issues haven't been looked at yet by a maintainer label Aug 7, 2024
@zannager zannager added the package: system Specific to @mui/system label Aug 8, 2024
@corydeppen
Copy link
Author

This appears to only be an issue when building for development. If I build for production, the style sheets are generated as expected and don't cause the precedence issue that I'm seeing in development. For example, in dev, the ButtonBase styles are being generated and included in both layout.css and page.css files. However, those styles are only included in a single generated file when building for prod and allow more specific styles to be applied by style sheets being included later in the document.

@aarongarciah aarongarciah removed the package: system Specific to @mui/system label Aug 15, 2024
@siriwatknp siriwatknp added bug 🐛 Something doesn't work nextjs and removed status: waiting for maintainer These issues haven't been looked at yet by a maintainer labels Aug 19, 2024
@siriwatknp
Copy link
Member

siriwatknp commented Aug 20, 2024

I am using AppBar is an example here. The AppBar is a component that wraps Paper and override the background. In Next.js app router, AppBar is used in layout.tsx and then a Paper is used in page.tsx.

The root cause comes from the styles of the Paper being generated to both layout.css and page.css and Next.js orders the <link> by loading the layout.css before page.css (meaning page.css has higher priority than layout.css for the same classes):

Because the produced HTML of AppBar includes classes of the Paper like this:

<div class="appbar paper">

// layout.css
.paper { background: white };
.appbar { background: blue };

// page.css 
.paper { background: white };

This causes .paper in page.css to win the .appbar in layout.css.

image

In production, the CSS files are built with a different process, so there are no duplicate CSS however, there is a possibility that the order of the might be different.

Update

This issue involves Next.js because page.tsx is processed before layout.tsx. This makes it hard for Pigment CSS to know if Paper is already used in the upper layout or not.

@royporter7
Copy link

Just bumped into this bug as well with my project. Would love to see it resolved.

@brijeshb42
Copy link
Contributor

Hey folks. I am looking into this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug 🐛 Something doesn't work nextjs
Projects
None yet
7 participants