Tailwind CSS, Responsive Layouts, Dark Mode & More in Next.js 14+
In this module, you’ll master styling your app using Tailwind CSS — a utility-first CSS framework that’s fast, responsive, and perfect for modern UIs. We’ll explore global styling, reusable components, and even build a dark mode toggle using Zustand (for practice and fun).
Prerequisite: Tailwind should already be installed via
create-next-app
. If not, scroll to the setup section below.
✅ Tailwind CSS Setup Recap (Optional)
If you missed this during create-next-app
setup, follow this:
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
Update tailwind.config.ts
:
export default {
content: [
"./src/**/*.{js,ts,jsx,tsx}"
],
theme: {
extend: {},
},
plugins: [],
}
And in src/app/globals.css
:
@tailwind base;
@tailwind components;
@tailwind utilities;
Then import it in src/app/layout.tsx
:
import './globals.css';
🧰 Creating a Responsive Layout
Let’s build a responsive 2-column layout with header and footer using Tailwind.
🧱 src/components/Layout.tsx
// src/components/Layout.tsx
type Props = {
children: React.ReactNode;
};
export default function Layout({ children }: Props) {
return (
<div className="flex flex-col min-h-screen">
<header className="bg-blue-600 text-white p-4">My Next.js 14 App</header>
<main className="flex-1 flex flex-col md:flex-row p-4 gap-4">
<aside className="md:w-1/4 bg-gray-100 p-4">Sidebar</aside>
<section className="md:w-3/4">{children}</section>
</main>
<footer className="bg-blue-600 text-white p-4 text-center">© 2025</footer>
</div>
);
}
🏠 Use it in src/app/page.tsx
import Layout from '@/components/Layout';
export default function HomePage() {
return (
<Layout>
<div className="space-y-4">
<h1 className="text-3xl font-bold">Welcome to the App!</h1>
<p>This is a responsive layout built with Tailwind CSS.</p>
</div>
</Layout>
);
}
🖌️ Global Styles & CSS Modules
Use globals.css for common resets and custom utilities.
Use CSS Modules for scoped component styles:
🔹 src/components/Button.module.css
.btn {
@apply px-4 py-2 bg-green-600 text-white rounded hover:bg-green-700;
}
🔹 src/components/Button.tsx
import styles from './Button.module.css';
type Props = {
label: string;
};
export default function Button({ label }: Props) {
return <button className={styles.btn}>{label}</button>;
}
📱 Mobile-First Design with Tailwind
Tailwind is mobile-first by default. You scale up using breakpoints like md:
, lg:
, etc.
<div className="p-4 text-sm md:text-base lg:text-lg">
Responsive text size!
</div>
Example: Responsive Grid
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-4">
<div className="bg-gray-200 p-4">Box 1</div>
<div className="bg-gray-200 p-4">Box 2</div>
<div className="bg-gray-200 p-4">Box 3</div>
</div>
🌗 Implementing Dark Mode with Zustand
🧠 Zustand Store: src/store/theme.ts
import { create } from 'zustand';
type ThemeState = {
dark: boolean;
toggle: () => void;
};
export const useTheme = create<ThemeState>((set) => ({
dark: false,
toggle: () => set((state) => ({ dark: !state.dark })),
}));
🌘 Toggle Button Component
"use client";
import { useTheme } from "@/store/theme";
export default function ThemeToggle() {
const { dark, toggle } = useTheme();
return (
<button
onClick={toggle}
className="px-4 py-2 rounded border mt-4"
>
{dark ? "🌙 Dark Mode" : "☀️ Light Mode"}
</button>
);
}
💡 Apply Theme in Layout
Update src/components/Layout.tsx
to reflect dark mode:
"use client";
import { useTheme } from "@/store/theme";
export default function Layout({ children }: { children: React.ReactNode }) {
const { dark } = useTheme();
return (
<div className={dark ? "dark" : ""}>
<div className="flex flex-col min-h-screen bg-white dark:bg-gray-900 text-black dark:text-white">
<header className="bg-blue-600 text-white p-4">My App</header>
<main className="flex-1 p-4">{children}</main>
<footer className="bg-blue-600 text-white p-4 text-center">© 2025</footer>
</div>
</div>
);
}
And finally update tailwind.config.ts
:
darkMode: 'class', // enable class-based dark mode
✅ Summary
In this module, you’ve learned:
- How to apply styles using Tailwind CSS
- How to build a responsive layout
- How to use CSS Modules and global styles
- How to create and apply a dark mode toggle using Zustand
You’re now ready to make your app visually dynamic and mobile-friendly.
🔜 Next Up:
In Module 4, we’ll build smart reusable components like buttons, cards, and handle loading and error states — the building blocks of any real-world UI.
Would you like this as a downloadable .md
file or embedded on your blog?