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
- Create a style file: Create a CSS file in the
stylesdirectory, for examplestyles/globals.css. - Import in
_app.js: Import the stylesheet in thepages/_app.jsfile. This is the only place where you can import global styles.
// pages/_app.js
import '../styles/globals.css';
function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />;
}
export default MyApp;styles/globals.css example:
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
- Create a modular CSS file: Create a CSS file ending with
.module.css, for examplecomponents/Button.module.css. - Import in the component: Import the CSS file in your component file and use it like an object.
components/Button.module.css example:
.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:
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:
npm install sass
# or
yarn add sassAfter 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:
// 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:
$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:
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
Install dependencies:
bashnpm install styled-componentsConfigure
_document.js: To make Styled-components render correctly on the server, you need to create a custompages/_document.jsfile 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> ); } }Create Styled Component:
jsximport 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.