Tailwind CSS & CSS Modules

0/3 in this phase0/36 across the roadmap

📖 Concept

Styling in React can be done in many ways, each with its own trade-offs.

1. CSS Modules: This is the "standard" way. It uses regular CSS but locally scopes it by automatically generating unique class names.

  • Pro: Real CSS (no new syntax), isolated styles, no specificity wars.
  • Con: You still have to switch between JS and CSS files.

2. Tailwind CSS (Utility-First): Currently the most popular way to style React apps. Instead of writing CSS, you use pre-defined utility classes in your JSX.

  • Pro: Extremely fast development, no context switching, small final CSS bundle, consistent design system.
  • Con: JSX can look "cluttered" with many classes.

3. CSS-in-JS (Styled Components): Write CSS directly inside your JS files using tagged template literals.

  • Pro: Dynamic styles based on props, logic and styling in one file.
  • Con: Performance overhead (CSS is generated at runtime), larger JS bundle.

💻 Code Example

codeTap to expand ⛶
1// --- CSS MODULES EXAMPLE ---
2/* Button.module.css */
3.primary {
4 background-color: blue;
5 color: white;
6 padding: 10px;
7}
8
9// Button.tsx
10import styles from './Button.module.css';
11const Button = () => <button className={styles.primary}>Click Me</button>;
12
13// --- TAILWIND CSS EXAMPLE ---
14// Button.tsx
15const TailwindButton = () => (
16 <button className="bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded transition shadow-md">
17 Click Me
18 </button>
19);
20
21// --- DYNAMIC TAILWIND (using clsx or tailwind-merge) ---
22import { clsx, type ClassValue } from 'clsx';
23import { twMerge } from 'tailwind-merge';
24
25function cn(...inputs: ClassValue[]) {
26 return twMerge(clsx(inputs));
27}
28
29const DynamicButton = ({ active }) => (
30 <button className={cn(
31 "px-4 py-2 rounded",
32 active ? "bg-blue-500 text-white" : "bg-gray-200 text-gray-800"
33 )}>
34 Click Me
35 </button>
36);

🏋️ Practice Exercise

  1. Rebuild a simple 'Card' component twice: once using CSS Modules and once using Tailwind CSS.
  2. Set up a 'Tailwind Config' with custom colors and fonts.
  3. Use the tailwind-merge and clsx libraries to handle complex conditional classes.
  4. Experiment with 'Responsive' styling in Tailwind (e.g., md:flex-row flex-col).

⚠️ Common Mistakes

  • Using global CSS for everything (leading to naming conflicts).

  • Over-relying on inline styles (style={{...}}), which are hard to maintain and can't use pseudo-selectors (hover, focus).

  • Creating giant 'utils' files for styles instead of using a proper utility framework.

  • Not using a linter for Tailwind classes (to keep them in a consistent order).

💼 Interview Questions

🎤 Mock Interview

Practice a live interview for Tailwind CSS & CSS Modules