How to use Next.js' built-in CSS

The amount of work that goes into styling is a crucial aspect of development. The first language that comes to mind while aiming to alter the presentation of our web content is CSS.

CSS stands for Cascading Style Sheets and is a powerful rule-based language for establishing both the aesthetic and structure side of content.

Traditional page with HTML / CSS / JS
Traditional page with HTML / CSS / JS

Next.js, being a web development framework, is not a stranger to CSS. Therefore, we can easily incorporate styling in this framework.

Next.js and CSS

Fortunately for us, Next.js provides its users with 5 ways to use CSS within a Next project.

  1. Global CSS: A CSS file that allows us to apply specified CSS globally.

  2. Tailwind CSS: A CSS framework that provides rapid designs by utility classes.

  3. CSS Modules: Local scope CSS classes that solve name concerns and conflicts.

  4. CSS in JS: A new way of embedding CSS within Javascript's components.

  5. Sass: A CSS extension built on top of CSS with a wide range of capabilities.

Among these, Global CSS, CSS Modules, and CSS in JS are three ways that do not require external entities such as Tailwind, etc. We'll be covering these three concepts primarily.

Global CSS

Remember the CSS that we generally add in simple HTML / CSS / JS applications? That is exactly what we're talking about here!

Global CSS refers to CSS styles that can be applied to any component globally anywhere within the application. With this, our main aim is to define styles in a centralized way. A centralized way means the separation of the CSS stylesheet and the rest of the application.

Note: A consistent visual appearance can be achieved through this method.

Code Sample

styles.css file

body{
font-size: 20px;
margin: 10px;
padding: 15px;
height: 100vh;
}
.btn{
background-color: white;
}
  • Lines 1–6: We define a font-size of 20 pixels, margin and padding of 10 and 15 pixels respectively, and the total height of our main body to be 100% of the view height vh.

  • Lines 8–10: We add styles to our custom btn class. A white background-color is assigned to it.

MyButton file

import '../styles.css';
export function MyButton() {
return(
<button
type = 'button'
className = 'btn'
>
Join Educative here!
</button>
)
}

MyButton2 file

import '../styles.css';
export function MyButton2() {
return(
<button
type = 'button'
className = 'btn'
>
Check our Educative Courses!
</button>
)
}
  • Line 1: The first and foremost task we perform is to import the global CSS file in both of our button files. Now, each class mentioned there is accessible in these files.

  • Lines 3–13: We can now add the btn class in any file by simply assigning the className a value of btn. The styles applied to the body will be visible in both components as well.

Benefits of global CSS

  • Ease of use due to familiarity

  • Consistent styling

  • Application wide usage

CSS modules

Now let's suppose we want to alter our global CSS concept a bit and add modularity to it. We can choose to do this when we aim to practice separation of concerns and solving naming conflicts is pivotal.

Note: Each CSS class we define in a module is scoped only locally to the page it is imported in.

CSS module usage is an approach that gives us the opportunity to write local scope CSS classes, where each content component is bound to a different style component.

Code Sample

MyButton.module.css file

.submitBtn {
font-size: 15px;
border: 1px solid black;
background-color: green;
}
  • Lines 1–5: We define a font-size of 15 pixels, a border with a width of 1 pixel, solid lines, and black color. The background-color of our button is kept green.

MyButton file

import styles from './MyButton.module.css';
export function MyButton() {
return(
<button
type = 'button'
className = {styles.submitBtn}
>
Join Educative here!
</button>
)
}
  • Line 1: Since we're dealing with modular styling now, we will import the styles specific to the MyButton module. These are defined in MyButton.module.css. We further use an alias name styles for the import so that no naming conflicts occur.

  • Lines 3–13: The submitBtn in the CSS file is distinguished by using the keyword styles.submitBtn.

Note: If a class of the same name as 'submitBtn' belongs to another module, say styles2, using styles2.submitBtn will not lead to any naming concern.

Benefits of CSS modules

  • Preventing style or name issues

  • Scoped styling

  • Better reusability and maintainability

Pop Quiz on CSS modules!

Question

Why don’t CSS modules have naming conflicts?

Show Answer

CSS in JavaScript (JS)

CSS in JS is an approach through which we can involve CSS styling within a JavaScript component. This helps us accomplish dynamic or scoped styling. Instead of separating our styles and component code, we can merge the two and get the best of both worlds.

By dynamic styling, we mean the ability to dynamically generate styles based on the props or state of our application.

Note: These styles can also be changed based on interactions or events.

Code Sample

MyComponent file

function MyComponent() {
return (
<div>
<h2>Hello, Next.js!</h2>
<p>This is some scoped text</p>
<style jsx>{`
h2 {
color: green;
}
div {
background: yellow;
}
@media (max-width: 750px) {
div {
background: blue;
}
}
`}</style>
<style jsx global>{`
body {
background: blue;
}
`}</style>
</div>
);
}
export default MyComponent;
  • Lines 6–7: A few fundamental HTML tags such as a level two heading h2 that says "Hello, Next.js" and a paragraph p that says "This is some scoped text" are rendered on our page.

  • Lines 9–29: To add a few aesthetics to our content, we can now make use of styling. This way introduces CSS within JavaScript components. For this purpose, we can opt for two further methods.

    • We enclose our local styling i.e. the styling only applied to the elements of this component within a <style jsx> tag and then write CSS as it is within the tags. In the example, the styles defined for h2 and div are scoped to the enclosing MyComponent component.

    • Another feature provided by CSS in JS is the <style jsx global> tag. This is brilliant for also adding styles to the whole HTML and applying them to the whole application. In the example, the body style is defined using jsx global, which means it will apply to the entire body of the rendered HTML, regardless of the component hierarchy.

  • Line 31: We export the component so that it can be rendered in other components.

Enabling or disabling Javascript

Users also have the option to disable JavaScript in production. In this case, the styling through CSS still gets loaded.

Benefits of CSS in JS

  • Dynamic styling

  • Scoped styling

  • JavaScript integration

Recap

We have now understood the dynamics of CSS in Next.js, and we highly encourage you to try it out! Lastly, to summarize, we have put forth a condensed view of some notable points for each method.

Key comparisons in built-in CSS options


CSS Modules

Global CSS

CSS in JS

Definition

Locally scoped CSS classes.

Applied globally throughout the app.

Embed CSS directly in JavaScript components.

Pros

Prevents naming conflicts.

Improved maintainability.

Easy to manage and organize styles.


Familiar for traditional CSS developers.

Easy to use and understand.

Simple setup and usage.

Dynamic and scoped styling.

Ability to use JavaScript features like variables and mixins.

Component-based styling with encapsulation.

Cons

Requires importing and using class names.

Can lead to larger CSS bundles.

Potential performance overhead .

Learning curve

Extra learning curve for newer users.

Less learning curve but difficult to manage styles as app grows.

Learning curve for new people to CSS in JS solutions.

Usage

Component-level styling with encapsulation.

Global styles and application-wide styles.

Dynamic styling and complex styling requirements.

Syntaz

Import styles from './styles.module.css';

import '../global.css';

<style jsx> or <style jsx global>

Pop Quiz on Next.js Styling!

Q

Where is Tailwind an optimal choice?

A)

In naming conflicts

B)

In global scope

C)

In dynamic scope

D)

Quick designs through class names

Free Resources

Copyright ©2025 Educative, Inc. All rights reserved