How to Integrate CSS and Sass in Next.js?

How to Integrate CSS and Sass in Next.js?

Next.js is a powerful React framework that provides built-in support for CSS and Sass, making it easier to style your applications. This article will guide you through the steps to integrate CSS and Sass into your Next.js project, covering both global and component-scoped styles.

Setting Up a Next.js Project

Before we begin, let's set up a new Next.js project. If you already have a project, you can skip this step.

npx create-next-app@latest my-nextjs-app
cd my-nextjs-app

Integrating Global CSS

Global CSS is applied to your entire application. In Next.js, you need to import your global CSS file in the custom _app.js file.

  • Create a Global CSS File:

    Create a styles directory in the root of your project and add a globals.css file.

    /* styles/globals.css */
    body {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
      font-family: Arial, sans-serif;
    }
    
    h1 {
      color: #333;
    }
    
  • Import Global CSS in _app.js:

    Open pages/_app.js and import the globals.css file.

    // pages/_app.js
    import "../styles/globals.css";
    
    function MyApp({ Component, pageProps }) {
      return <Component {...pageProps} />;
    }
    
    export default MyApp;
    

Integrating Component-Scoped CSS

Next.js supports CSS Modules, which allow you to scope CSS to a specific component. This prevents styles from leaking and makes it easier to manage your CSS.

Component-Scoped CSS

  • Create a CSS Module:

    Create a new CSS module file in the styles directory. For example, Home.module.css.

    /* styles/Home.module.css */
    .container {
      display: flex;
      justify-content: center;
      align-items: center;
      height: 100vh;
      background-color: #f0f0f0;
    }
    
    .title {
      color: #0070f3;
      font-size: 2rem;
    }
    
  • Import and Use the CSS Module:

    In your component, import and use the CSS module.

    // pages/index.js
    import styles from "../styles/Home.module.css";
    
    export default function Home() {
      return (
        <div className={styles.container}>
          <h1 className={styles.title}>Welcome to Next.js</h1>
        </div>
      );
    }
    

Integrating Sass

Next.js also supports Sass, a popular CSS preprocessor that adds features like variables, nested rules, and mixins. To use Sass in your Next.js project, you need to install the necessary packages.

  • Install Sass:

    npm install sass
    
  • Create a Sass File:

    Create a styles directory if you haven't already and add a globals.scss file.

    /* styles/globals.scss */
    $primary-color: #0070f3;
    
    body {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
      font-family: Arial, sans-serif;
    }
    
    h1 {
      color: $primary-color;
    }
    
  • Import Global Sass in _app.js:

    Open pages/_app.js and import the globals.scss file.

    // pages/_app.js
    import "../styles/globals.scss";
    
    function MyApp({ Component, pageProps }) {
      return <Component {...pageProps} />;
    }
    
    export default MyApp;
    
  • Using Sass Modules:

    Similar to CSS Modules, you can create Sass modules by using the .module.scss extension.

    /* styles/Home.module.scss */
    $primary-color: #0070f3;
    
    .container {
      display: flex;
      justify-content: center;
      align-items: center;
      height: 100vh;
      background-color: #f0f0f0;
    }
    
    .title {
      color: $primary-color;
      font-size: 2rem;
    }
    

    Import and use the Sass module in your component.

    // pages/index.js
    import styles from "../styles/Home.module.scss";
    
    export default function Home() {
      return (
        <div className={styles.container}>
          <h1 className={styles.title}>Welcome to Next.js</h1>
        </div>
      );
    }
    

Dynamic and Conditional Styling

With Next.js, you can dynamically apply styles based on conditions. For example, you can conditionally apply classes using template literals.

// pages/index.js
import styles from "../styles/Home.module.scss";

export default function Home({ isDarkMode }) {
  return (
    <div className={`${styles.container} ${isDarkMode ? styles.dark : ""}`}>
      <h1 className={styles.title}>Welcome to Next.js</h1>
    </div>
  );
}
/* styles/Home.module.scss */
$primary-color: #0070f3;
$dark-bg: #333;
$dark-color: #fff;

.container {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
  background-color: #f0f0f0;
}

.title {
  color: $primary-color;
  font-size: 2rem;
}

.dark {
  background-color: $dark-bg;
  color: $dark-color;
}

Benefit of integrating CSS and Sass in Next.js project

Integrating CSS and Sass in a Next.js project offers several benefits: benefits

  • Enhanced Styling Capabilities:

    • CSS Modules: Scoped CSS ensures styles apply only to the component, preventing style conflicts and making it easier to manage large projects.
    • Sass Features: Sass extends CSS with features like variables, nesting, and mixins, enabling more organized and maintainable stylesheets.
  • Improved Maintainability:

    • Modular Approach: Using CSS modules or Sass partials helps keep your styles modular and easier to maintain.
    • Variables and Mixins: Sass variables and mixins allow for consistent styling and easy updates across your project.
  • Better Performance:

    • Automatic Code Splitting: Next.js automatically splits your CSS, ensuring that only the styles needed for a particular page are loaded, which can improve performance.
    • Efficient CSS Loading: By importing CSS directly in components, you ensure that styles are only loaded when needed.
  • Developer Productivity:

    • Nesting: Sass allows for nesting of CSS selectors, which makes the stylesheet more readable and mimics the HTML structure.
    • Reusable Code: Sass mixins and functions enable the reuse of common styles, reducing duplication and speeding up development.
  • Consistency Across Application:

    • Global Styles: Easily define and apply global styles for consistent theming across your application.
    • CSS Variables: Use CSS variables for dynamic theming and easy style adjustments.
  • Integration with Modern CSS Tools:

    • PostCSS Support: Next.js supports PostCSS, allowing you to use modern CSS tools and plugins for tasks like autoprefixing and minification.
    • Future-proofing: Incorporating tools like PostCSS and Sass prepares your project for future CSS specifications and browser compatibility.
  • Ease of Setup:

    • Out-of-the-box Support: Next.js has built-in support for CSS and Sass, requiring minimal configuration to get started.
    • Flexibility: Easily switch between or combine global CSS, CSS modules, and Sass as per your project needs.

Example Integration

  • Global CSS:

    // pages/_app.js
    import "../styles/global.css";
    
    function MyApp({ Component, pageProps }) {
      return <Component {...pageProps} />;
    }
    
    export default MyApp;
    
  • CSS Modules:

    /* styles/Home.module.css */
    .title {
      color: blue;
    }
    
    // pages/index.js
    import styles from "../styles/Home.module.css";
    
    export default function Home() {
      return <h1 className={styles.title}>Hello World</h1>;
    }
    
  • Sass Integration:

    /* styles/Home.module.scss */
    $title-color: red;
    
    .title {
      color: $title-color;
    }
    
    // pages/index.js
    import styles from "../styles/Home.module.scss";
    
    export default function Home() {
      return <h1 className={styles.title}>Hello World</h1>;
    }
    

By integrating CSS and Sass in a Next.js project, you gain a robust, scalable, and maintainable styling solution that enhances both developer productivity and application performance.

Advanced Tips for Integrating CSS and Sass in Next.js Projects

Integrating CSS and Sass in Next.js projects provides powerful tools for creating modular, maintainable, and efficient styles. Here are advanced tips to take full advantage of CSS and Sass in your Next.js applications:

  • Using Sass Variables and Mixins Mixins

    • Variables: Define global variables for colors, fonts, and other design tokens for consistency.
    • Mixins: Create reusable code blocks for common patterns like media queries and flexbox layouts.
    /* styles/_variables.scss */
    $primary-color: #3498db;
    $font-stack: "Helvetica, Arial, sans-serif";
    
    /* styles/_mixins.scss */
    @mixin flex-center {
      display: flex;
      justify-content: center;
      align-items: center;
    }
    
    /* styles/global.scss */
    @import "variables";
    @import "mixins";
    
    body {
      font-family: $font-stack;
    }
    
    .header {
      background-color: $primary-color;
      @include flex-center;
    }
    
  • Leveraging CSS Modules with Sass : Combine CSS Modules and Sass for scoped and maintainable styles.

    /* styles/Home.module.scss */
    .title {
      color: red;
      &:hover {
        color: blue;
      }
    }
    
    // pages/index.js
    import styles from "../styles/Home.module.scss";
    
    export default function Home() {
      return <h1 className={styles.title}>Hello World</h1>;
    }
    
  • Dynamic Theming with CSS Variables and Sass : Use CSS variables for theming and change themes dynamically.

    /* styles/_themes.scss */
    :root {
      --primary-color: #3498db;
      --secondary-color: #2ecc71;
    }
    
    [data-theme="dark"] {
      --primary-color: #1abc9c;
      --secondary-color: #e74c3c;
    }
    
    /* styles/global.scss */
    @import "themes";
    
    body {
      background-color: var(--primary-color);
    }
    
    // pages/_app.js
    import "../styles/global.scss";
    import { useState } from "react";
    
    function MyApp({ Component, pageProps }) {
      const [theme, setTheme] = useState("light");
    
      return (
        <div data-theme={theme}>
          <button onClick={() => setTheme(theme === "light" ? "dark" : "light")}>
            Toggle Theme
          </button>
          <Component {...pageProps} />
        </div>
      );
    }
    
    export default MyApp;
    
  • Optimizing CSS Loading : Split CSS into different files for critical and non-critical styles. Load critical styles inline and defer the rest.

    // pages/_document.js
    import Document, { Html, Head, Main, NextScript } from "next/document";
    import { extractCritical } from "@emotion/server";
    
    export default class MyDocument extends Document {
      static async getInitialProps(ctx) {
        const initialProps = await Document.getInitialProps(ctx);
        const styles = extractCritical(initialProps.html);
        return { ...initialProps, ...styles };
      }
    
      render() {
        return (
          <Html>
            <Head>
              <style
                data-emotion-css={this.props.ids.join(" ")}
                dangerouslySetInnerHTML={{ __html: this.props.css }}
              />
            </Head>
            <body>
              <Main />
              <NextScript />
            </body>
          </Html>
        );
      }
    }
    
  • Using PostCSS with Sass : Add additional PostCSS plugins for features like autoprefixing, minification, and future CSS syntax.

    npm install postcss-preset-env
    
    // postcss.config.js
    module.exports = {
      plugins: {
        "postcss-preset-env": {
          stage: 1,
          features: {
            "nesting-rules": true,
          },
        },
      },
    };
    
  • Linting and Formatting Styles : Use stylelint and Prettier to enforce consistent style rules and formatting.

    npm install stylelint stylelint-config-standard stylelint-config-sass-guidelines
    
    // .stylelintrc
    {
      "extends": [
        "stylelint-config-standard",
        "stylelint-config-sass-guidelines"
      ]
    }
    
    npx stylelint "**/*.scss" --fix
    
  • Tree-shaking Unused CSS : Use PurgeCSS to remove unused CSS and reduce the final bundle size.

    npm install @fullhuman/postcss-purgecss
    
    // postcss.config.js
    const purgecss = require("@fullhuman/postcss-purgecss")({
      content: [
        "./pages/**/*.{js,jsx,ts,tsx}",
        "./components/**/*.{js,jsx,ts,tsx}",
      ],
      defaultExtractor: (content) => content.match(/[\w-/:]+(?<!:)/g) || [],
    });
    
    module.exports = {
      plugins: [
        "postcss-preset-env",
        ...(process.env.NODE_ENV === "production" ? [purgecss] : []),
      ],
    };
    

By incorporating these advanced techniques, you can create more efficient, maintainable, and dynamic styling solutions in your Next.js projects.


Next.Js FAQ

To add global CSS in a Next.js project, you need to import the CSS file in your pages/_app.js file. Here’s how you can do it:

// pages/_app.js
import "../styles/global.css"; // Adjust the path as needed

function MyApp({ Component, pageProps }) {
  return <Component {...pageProps} />;
}

export default MyApp;

CSS modules in Next.js are used by naming your CSS files with the .module.css extension. Here’s an example:

/* styles/Home.module.css */
.title {
  color: blue;
}
// pages/index.js
import styles from "../styles/Home.module.css";

export default function Home() {
  return <h1 className={styles.title}>Hello World</h1>;
}

First, you need to install sass:

npm install sass

Then, create your .scss files and import them just like CSS modules. Next.js supports Sass out of the box.

/* styles/Home.module.scss */
.title {
  color: red;
}
// pages/index.js
import styles from "../styles/Home.module.scss";

export default function Home() {
  return <h1 className={styles.title}>Hello World</h1>;
}

Yes, you can use both global CSS and CSS modules in the same Next.js project. Import global CSS in pages/_app.js and use CSS modules in individual components or pages by naming the files with the .module.css or .module.scss extension.

Next.js automatically includes PostCSS. To customize PostCSS, create a postcss.config.js file in the root of your project:

// postcss.config.js
module.exports = {
  plugins: {
    "postcss-preset-env": {},
    // Add other plugins here
  },
};

Next.js will automatically detect this configuration and use it when processing CSS files. You can add various PostCSS plugins to enhance your CSS workflow.

Conclusion

Integrating CSS and Sass in Next.js is straightforward and powerful. You can use global CSS for general styles, CSS Modules for component-scoped styles, and Sass for advanced styling features. These capabilities enable you to create well-organized, maintainable, and scalable styles for your Next.js applications. By leveraging these techniques, you can ensure your application not only looks great but also maintains high performance and readability.

If you want to read the larger version of this then check out this article https://medium.com/@farihatulmaria/how-to-integrate-css-and-sass-in-next-js-6264e75bc268

Tags :
Share :

Related Posts

Integrating Next.js with Other Backend Technologies: Express, GraphQL, and Beyond

Integrating Next.js with Other Backend Technologies: Express, GraphQL, and Beyond

Next.js, a versatile React framework, is often used for building frontend applications. However, its flexibility extends beyon

Continue Reading
How Do You Efficiently Manage API Routes in Large-Scale Next.js Applications?

How Do You Efficiently Manage API Routes in Large-Scale Next.js Applications?

As Next.js grows in popularity for building full-stack applications, efficiently managing [API routes](https://nextjs.org/

Continue Reading
Exploring Advanced Data Fetching in Next.js

Exploring Advanced Data Fetching in Next.js

Data fetching is a critical aspect of web development, enabling applications

Continue Reading
How Does Next.js Handle Routing and What Are Its Advantages Over Client-Side Routing Libraries?

How Does Next.js Handle Routing and What Are Its Advantages Over Client-Side Routing Libraries?

Next.js is a popular React framework known for its robust features, including a powerful routing system. Routing is an

Continue Reading
Understanding Server-Side Rendering (SSR) in Next.js

Understanding Server-Side Rendering (SSR) in Next.js

Server-Side Rendering (SSR) is a crucial feature in modern

Continue Reading
How to Use TypeScript with Next.js and the Benefits of Using TypeScript?

How to Use TypeScript with Next.js and the Benefits of Using TypeScript?

TypeScript has gained significant popularity among developers due to its ability to catch errors at compil

Continue Reading