Problem with the purity of :global() CSS-module selectors in NextJS

Currently in the process of migrating an app from CRA to NextJS, I've encountered an issue with the .module.scss files of certain components and pages:

Syntax error: Selector ":global(.label-primary)" is not pure (pure selectors must contain at least one local class or id)

This error persists for all :global and :local css-module selectors. From my research, it seems that I can resolve this problem by enclosing the selector in a class and making adjustments in the jsx. However, wouldn't this defeat the purpose?

I'm curious as to why this works in the CRA version of the app but not in NextJS.

EDIT: One solution I came across involves moving :global() selectors to the global css files imported in _app.js. My question is, is there any way to maintain the functionality of these styles as they currently are (:global(...))?

Answer №1

Currently, there is no known solution for this issue other than making changes to the webpack configuration itself. The problem arose because Create React App (CRA) likely uses mode: local, whereas Next.js uses pure.


Though I have not personally tried overriding the css-loader webpack config, I am suggesting a workaround approach. If you are working with SCSS, you can encapsulate your pseudo-global styles like this:

.root :global {
  .foo {
    color: red;
  }
}

To implement this, wrap your component/page in a div element and assign the class as styles.root to that element. Subsequently, you can directly apply className="foo" to all child elements.

import styles from "../styles/index.module.scss";

const IndexPage = () => (
  <div className={styles.root}>
    <div className="foo">This text will appear in red!</div>
  </div>
);

export default IndexPage;

Please be aware of specificity issues that may arise after following this method. Additionally, direct application of animations may require separating the keyframes and making them globally accessible.

Check out the Demo Sandbox


[1]: It's important to note that this method does not make the styles entirely global since they remain scoped. The class foo will only function if some parent element has styles.root as its class attribute. This approach is ideal if you didn't initially intend to utilize your :global(.selector) in other components, and were merely using it to dynamically manage class names via JavaScript without the use of a styles object.

If true global styling is required, consider adding styles.root to document.documentElement within a useEffect hook as shown below:

import { useEffect } from "react";
import styles from "../styles/index.module.scss";

const IndexPage = () => {
  useEffect(() => {
    document.documentElement.classList.add(styles.root);
    return () => {
      document.documentElement.classList.remove(styles.root);
    };
  }, []);

  return (
    <div className="foo">
      This text will display in red, even if placed within another component on the same page. For consistent application across multiple pages, inject it in _app or _document.
    </div>
  );
};

export default IndexPage;

View the Demo Sandbox

PS: Adding classes to html within _app or _document is not identical to utilizing a global stylesheet. In the case of a multi-page application, automatic CSS code-splitting by Next.js may result in only the necessary CSS being requested per page due to each component having distinct CSS. However, if all pages share the same CSS, sticking to the conventional method of importing styles in _app would suffice.

Answer №2

I encountered a similar issue, the correct syntax is as follows:

.root:global {
   color:red
}

Answer №3

To approach this in a different way, one can create a container, wrap it around, and then proceed as shown below:

import style from '../styles/style.module.css'
<div className={styles.container}>
    <p>Greetings Earthlings!</p>
</div>
.container p {
  font-size: 20px;
}

If you have numerous tags and conditions, you only need to include them in the CSS file.

Answer №4

For those seeking a way to apply global styles using CSS-Modules in Nextjs v14+ (Also compatible with App-router & TurboPack).

To define the global class in your CSS file, you can do it like this:

:global(.my__global__class) {
  color: violet;
}

In your JSX code, make sure to use the regular classname attribute instead of the CSS-Module specific one.

// Incorrect ❌ - Not functional

className={styles["my__global__class"]}

// Correct ✅ Works correctly

className="my__global__class"

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Using ReactJS to store form submissions for future API requests

I'm currently developing a React web application and facing an issue with saving input from a form submission to use in multiple API calls. While I am able to utilize the input initially for making an API call and displaying results, I am struggling ...

Looking for a solution to update data in React components after a refresh using databinding and array push

I am dealing with a challenge The webpage is not reacting to the signal consistently. Signals are not coming in regularly. In my scenarios (Array data pushed after refresh) No event is triggered Since I cannot use setState function I believe calling ...

When directed to a different page, Fetch does not activate

Having trouble getting the fetch function to run more than once in my application. It works the first time, loading the page with received data, but when I navigate to a new URL without refreshing the page, nothing changes - not even the state. The same is ...

NextJS is experiencing issues with client side routing functionality

Update: Issue Resolved! I made a minor error by not providing the language in the href and query params, despite having a [language]/folder setup. The pages I have are: pages/_app.js pages/_document.js pages/index.js pages/order.js pages/discover/[catego ...

Still having trouble getting @font-face to work with Firefox and htaccess

I've been struggling to load my custom font in Firefox despite numerous attempts. Here is the @font-face property code I have placed in the head section: @font-face { font-family: 'MeanTimeMedium'; src: url('http://sweetbacklove.com ...

The main div element is experiencing an overflow due to the excessive

I am struggling to create a homepage layout with three columns of varying heights within the 'content' division. The columns keep overflowing onto the content below, causing layout issues. I have attempted using positioning to solve this problem ...

Updating the text inside a div element in React when the state changes

Is it possible to dynamically update the text in a div tag based on changes in startDate and endDate values? Despite attempting to do so, the div continues to display old values. How can I ensure that the text in the div is updated when the state changes ...

What could be causing the issue with absolute positioning not functioning correctly?

I'm having trouble keeping my footer at the bottom of the page: body, html{position:relative;} footer{position:absolute;} Even when I use bottom: 0;, the footer doesn't seem to go all the way to the bottom. Is there anyone who can help me troub ...

"Troubles with directing on websites using jQuery, CSS,

I have been struggling with creating this navigation bar for weeks now and I keep running into issues. What I am attempting to achieve is a primary navigation bar that, when hovered over, displays a secondary navigation menu below and slightly to the righ ...

Stack three DIVs vertically on the entire screen with a fixed page margin, ensuring no need for a scroll bar

I need help creating a layout with 3 DIVs stacked vertically, each taking up one third of the screen without causing a scroll-bar to appear. I also want an 8px margin around all three of them. Here's an image for reference... example image Ultimatel ...

Content width exceeds body width

Having an issue with body width that seems strange. Check out this fiddle link to see for yourself. <div class="topbar" style="width:100%; background:#000; color:#fff"> <div class="container" style="width:970px; margin:0 auto;">Lorem ipsum ...

There are no matching overloads in React for this call

Below is an error message in the code. It seems to be related to the usage of <IHistorical[]> in useQuery, but unfortunately, I haven't found a solution for it yet. Overload 1 of 2, '(props: Props | Readonly<Props>): ReactApexChart& ...

Ways to create distance between columns in Bootstrap 5

screenshot i want like this Looking at the image provided, there seems to be an issue with spacing between the red and blue columns. Despite trying various Bootstrap classes, the desired result has not been achieved. Adding m-4 to the Navbar, Header, and ...

Pressing the button disables the button's click functionality

I am currently developing a react application that incorporates Button from material-ui. I am aiming to implement drag and drop functionality for a component that contains a button. To facilitate drag and drop, I have integrated react-sortable-hoc into my ...

How can I incorporate a custom color into a preset navbar on an HTML webpage?

<div class="navbar-header"> <button aria-controls="navbar" aria-expanded="false" data-target="#navbar" data-toggle="collapse" style="color: blue;" class="navbar-toggle collapsed" type="button"> <i class="fa fa-reo ...

Discovering the top method to locate an Error Modal Message using Selenium

I am looking to automate a specific process that involves an Error modal popping up. I am trying to use Selenium to capture this modal which appears in multiple instances. So far, I have attempted to locate it by XPath without success. Using CSS selector o ...

The hostname "imgur.com" is missing from the images configuration in your `next.config.js` file. However, it is correctly included in my next.config.js. Could you please check what might be causing this

I am attempting to upload an image from MongoDB. { '_id': 1, 'type': 'shirt', 'price': 20, 'pic': 'https://imgur.com/6D53pAF'} An error message is indicating that my next.config.js file is not co ...

What is the proper way to retrieve this stylesheet and add it to the header of my HTML file?

I want to utilize a style sheet from Wikipedia. However, when I fetch the style sheet and attempt to pass the URL retrieved through AJAX to the head of my HTML document, the URL behaves unexpectedly. Initially, I tried to use the fetched URL directly: var ...

When a dialog box is displayed, a scrollbar will automatically appear

I've encountered a strange issue while working with Angular dialogs: A vertical scrollbar unexpectedly appears, even though I've set the dialog to have a fixed width. component.ts const dialog = this.dialog.open(DialogComponent, { width: ...