Skip to content

Next.js CSS Styling

In Next.js, there are multiple ways to add styles to your application, from simple global stylesheets to powerful CSS-in-JS libraries. This chapter introduces several of the most common methods, helping you choose the most suitable styling solution for your project needs.

1. Global Styles

Global styles apply to the entire application and are typically used for defining base styles, resetting default styles, or importing third-party style libraries.

How to Add Global Stylesheets

  1. Create a style file: Create a CSS file in the styles directory, for example styles/globals.css.
  2. Import in _app.js: Import the stylesheet in the pages/_app.js file. This is the only place where you can import global styles.
jsx
// pages/_app.js

import '../styles/globals.css';

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

export default MyApp;

styles/globals.css example:

css
body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
    Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
  line-height: 1.6;
  font-size: 18px;
}

* {
  box-sizing: border-box;
}

a {
  color: #0070f3;
  text-decoration: none;
}

a:hover {
  text-decoration: underline;
}

Note: Global styles affect all pages and components, so use them carefully to avoid style conflicts.

2. Component-Level CSS

To avoid naming conflicts and scope issues with global styles, Next.js has built-in support for CSS Modules. CSS Modules can scope CSS to a single component.

How to Use CSS Modules

  1. Create a modular CSS file: Create a CSS file ending with .module.css, for example components/Button.module.css.
  2. Import in the component: Import the CSS file in your component file and use it like an object.

components/Button.module.css example:

css
.error {
  color: white;
  background-color: red;
  padding: 10px 20px;
  border-radius: 5px;
  border: none;
  cursor: pointer;
}

.success {
  color: white;
  background-color: green;
}

components/Button.js example:

jsx
import styles from './Button.module.css';

export default function Button({ type, children }) {
  const buttonClass = type === 'error' ? styles.error : styles.success;

  return (
    <button type="button" className={buttonClass}>
      {children}
    </button>
  );
}

When using CSS Modules, Next.js automatically generates a unique hash for each class name, ensuring styles only apply to the component that imports them. For example, styles.error might be compiled to Button_error__1a2b3c.

3. Sass/SCSS Support

Next.js has built-in support for Sass. Before using it, you need to install the sass package:

bash
npm install sass
# or
yarn add sass

After installation, you can use .scss or .sass files just like regular CSS files.

Global Sass/SCSS

You can import a globals.scss file into pages/_app.js:

jsx
// pages/_app.js
import '../styles/globals.scss';

Component-Level Sass/SCSS

You can also combine Sass with CSS Modules by naming files with .module.scss or .module.sass:

components/Alert.module.scss example:

scss
$primary-color: #0070f3;

.alert {
  padding: 1rem;
  border-radius: 5px;
  &.info {
    background-color: lighten($primary-color, 40%);
    color: darken($primary-color, 20%);
  }
}

components/Alert.js example:

jsx
import styles from './Alert.module.scss';

export default function Alert({ children }) {
  return <div className={`${styles.alert} ${styles.info}`}>{children}</div>;
}

4. CSS-in-JS

CSS-in-JS is a technique that writes CSS directly in JavaScript code. This approach provides powerful dynamic styling capabilities and componentization benefits. Next.js supports all major CSS-in-JS libraries, such as:

  • Styled-components
  • Emotion

These libraries typically require some additional configuration to achieve server-side rendering (SSR) in Next.js.

Using Styled-components Example

  1. Install dependencies:

    bash
    npm install styled-components
  2. Configure _document.js: To make Styled-components render correctly on the server, you need to create a custom pages/_document.js file to collect styles.

    jsx
    // pages/_document.js
    import Document, { Html, Head, Main, NextScript } from 'next/document';
    import { ServerStyleSheet } from 'styled-components';
    
    export default class MyDocument extends Document {
      static async getInitialProps(ctx) {
        const sheet = new ServerStyleSheet();
        const originalRenderPage = ctx.renderPage;
    
        try {
          ctx.renderPage = () =>
            originalRenderPage({
              enhanceApp: (App) => (props) =>
                sheet.collectStyles(<App {...props} />),
            });
    
          const initialProps = await Document.getInitialProps(ctx);
          return {
            ...initialProps,
            styles: (
              <>
                {initialProps.styles}
                {sheet.getStyleElement()}
              </>
            ),
          };
        } finally {
          sheet.seal();
        }
      }
    
      render() {
        return (
          <Html>
            <Head />
            <body>
              <Main />
              <NextScript />
            </body>
          </Html>
        );
      }
    }
  3. Create Styled Component:

    jsx
    import styled from 'styled-components';
    
    const Title = styled.h1`
      font-size: 3rem;
      color: palevioletred;
      text-align: center;
    `;
    
    export default function HomePage() {
      return <Title>Hello World!</Title>;
    }

Summary

Next.js provides flexible and diverse styling solutions that you can choose based on project needs and team preferences:

  • Global Styles: Suitable for base styles and third-party libraries.
  • CSS Modules: Recommended for component-level styles, providing local scope and avoiding conflicts.
  • Sass/SCSS: If you prefer preprocessors, Next.js provides out-of-the-box support.
  • CSS-in-JS: Suitable for complex applications requiring dynamic styles and high componentization.

In the next chapter, we'll explore how to integrate and use Tailwind CSS, a powerful utility-first CSS framework, in Next.js projects.

Content is for learning and research only.