Home Quizzes Leaderboard Competitions Learn Hire Us
About Contact
Log In Sign Up
Learn Next.js Styling --- CSS Modules, Tailwind & Global CSS

Styling --- CSS Modules, Tailwind & Global CSS

⏱ 12 min read read
Three Main Styling Approaches:

1. CSS Modules --- scoped CSS per component (.module.css files)

2. Tailwind CSS --- utility-first CSS framework (most popular with
Next.js)

3. Global CSS --- app/globals.css, imported in root layout

CSS Modules --- Scoped Styles:

/* components/Button.module.css */

.button {

background: #0070f3;

color: white;

padding: 8px 16px;

border-radius: 6px;

border: none;

cursor: pointer;

}

.button:hover { background: #0051cc; }

// components/Button.tsx

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

export default function Button({ children }: { children:
React.ReactNode }) {

return <button className={styles.button}>{children}</button>;

}

Tailwind CSS --- Utility-First:

Tailwind is pre-installed when you choose it during create-next-app.
Write styles as class names --- no separate CSS file needed.

export default function Card({ title, desc }: { title: string; desc:
string }) {

return (

<div className="rounded-xl border border-gray-200 p-6 shadow-sm
hover:shadow-md transition">

<h2 className="text-xl font-bold text-gray-900
mb-2">{title}</h2>

<p className="text-gray-600 text-sm">{desc}</p>

</div>

);

}

Conditional Classes with clsx / cn:

import { clsx } from 'clsx';

function Button({ variant = 'primary', disabled }: Props) {

return (

<button

className={clsx(

'px-4 py-2 rounded font-medium transition',

variant === 'primary' && 'bg-blue-600 text-white
hover:bg-blue-700',

variant === 'ghost' && 'border border-gray-300 hover:bg-gray-50',

disabled && 'opacity-50 cursor-not-allowed',

)}

>

Click

</button>

);

}

shadcn/ui is the most popular component library for Next.js +
Tailwind.

Install: npx shadcn-ui@latest init

Add components: npx shadcn-ui@latest add button card input

Components are copied into your project --- fully customisable.
Code Example
// app/globals.css --- imported once in root layout

/* @tailwind base;

@tailwind components;

@tailwind utilities; */

/* Custom CSS variable theming */

:root {

--primary: #0070f3;

--background: #ffffff;

--foreground: #1a1a1a;

}

// components/StudentCard.tsx --- Tailwind example

type Student = { name: string; grade: number; subject: string };

function gradeColor(g: number) {

if (g >= 90) return 'text-green-600 bg-green-50';

if (g >= 70) return 'text-blue-600 bg-blue-50';

return 'text-red-600 bg-red-50';

}

export default function StudentCard({ name, grade, subject }:
Student) {

return (

<div className="rounded-xl border border-gray-200 p-5 shadow-sm">

<div className="flex items-center justify-between mb-3">

<h3 className="font-semibold text-lg text-gray-900">{name}</h3>

<span className={`px-3 py-1 rounded-full text-sm font-bold
${gradeColor(grade)}`}>

{grade}

</span>

</div>

<p className="text-sm text-gray-500">{subject}</p>

</div>

);

}

// CSS Module version --- components/Badge.module.css

/*.badge { border-radius: 9999px; padding: 2px 10px; font-size:
12px; font-weight: 700; }

.green { background: #dcfce7; color: #166534; }

.red { background: #fef2f2; color: #991b1b; } */

// import styles from './Badge.module.css';

// <span className={`${styles.badge} ${pass ? styles.green :
styles.red}`}>

// {pass ? 'Pass' : 'Fail'}</span>
← API Routes & Route Handlers Components, Props & TypeScript →

Log in to track your progress and earn badges as you complete lessons.

Log In to Track Progress