Wiki/Topics/Frontend/Tools/CSS Approaches — Pure CSS, Modules, Tailwind, and More

CSS Approaches — Pure CSS, Modules, Tailwind, and More

csstailwindcss-modulesbootstrapstyling2026-04-07

The Problem CSS Frameworks Solve

CSS itself is simple. The problems arise at scale:

1. Name collisions — Two files both define .card, they conflict
2. Inconsistency — One dev uses 14px, another uses 16px, another uses 1rem
3. Responsiveness — Writing media queries for every breakpoint is repetitive
4. Dark mode — Doubling every color definition
5. Maintenance — CSS files grow, dead rules accumulate, nobody dares delete

Different CSS approaches solve different subsets of these problems.

The Approaches

1. Pure CSS — Write it yourself

/* styles.css */
.card {
  background: white;
  border-radius: 8px;
  padding: 16px;
  box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}

.card-title {
  font-size: 20px;
  font-weight: bold;
  color: #333;
}
import './styles.css'

<div className="card">
  <h3 className="card-title">Project</h3>
</div>
ProsCons
No dependenciesClass name collisions across files
Full controlNo built-in design system
No learning curveDark mode / responsive = manual work

2. CSS Modules — Scoped by file

The .module.css extension tells the build tool to make class names unique per file.

/* Card.module.css */
.card {
  background: white;
  border-radius: 8px;
  padding: 16px;
}

.title {
  font-size: 20px;
  font-weight: bold;
}
import styles from './Card.module.css'

<div className={styles.card}>
  <h3 className={styles.title}>Project</h3>
</div>

// Rendered HTML: <div class="Card_card_x7ks2">
// The class name is auto-generated — no collisions possible
ProsCons
No class name collisionsSeparate .module.css file per component
Standard CSS syntaxDark mode / responsive still manual
Built into Next.js, no setupNo design system — consistency is your job
Easy to understandSwitching between .tsx and .css files

3. Tailwind CSS — Utility classes in HTML

Instead of writing CSS rules, you compose pre-defined utility classes directly in your HTML/JSX.

// No CSS file needed

<div className="bg-white dark:bg-gray-800 rounded-lg p-4 shadow-md hover:shadow-lg transition-shadow">
  <h3 className="text-xl font-bold text-gray-900 dark:text-white">Project</h3>
  <p className="text-gray-600 dark:text-gray-300 mt-2">Description here</p>
</div>

Each class does one thing:

bg-white         background: white
dark:bg-gray-800  in dark mode: background: gray-800
rounded-lg       border-radius: 0.5rem
p-4              padding: 1rem
shadow-md        box-shadow: medium
text-xl          font-size: 1.25rem
font-bold        font-weight: 700
mt-2             margin-top: 0.5rem
hover:shadow-lg  on hover: larger shadow
md:grid-cols-2   at medium screen: 2 columns
ProsCons
No CSS files to manageclassName strings get long
Built-in design system (colors, spacing, typography)Need to learn class names (editor helps)
Dark mode: dark: prefixHTML looks cluttered at first
Responsive: md: lg: prefixesHarder to read for CSS-experienced devs
Only ships CSS you actually useReusing styles requires components or @apply
Massive community and plugin ecosystem

4. CSS-in-JS — Write CSS in JavaScript

Libraries like styled-components or Emotion:

import styled from 'styled-components'

const Card = styled.div`
  background: white;
  border-radius: 8px;
  padding: 16px;
  
  &:hover {
    box-shadow: 0 4px 8px rgba(0,0,0,0.1);
  }
`

const Title = styled.h3`
  font-size: 20px;
  font-weight: bold;
`

<Card>
  <Title>Project</Title>
</Card>
ProsCons
CSS scoped to component automaticallyRuntime overhead (generates CSS in browser)
Dynamic styles based on propsLarger bundle size
Co-located with component codeNot compatible with React Server Components
Falling out of favor in React ecosystem

Note: CSS-in-JS was popular 2018-2022 but is declining because React Server Components (Next.js 13+) don't support runtime CSS-in-JS. The ecosystem is moving toward Tailwind and CSS Modules.

5. Component Libraries — Pre-built UI

Libraries that give you ready-made components (buttons, modals, forms):

// shadcn/ui (currently most popular, built on Tailwind)
import { Button } from "@/components/ui/button"
import { Card, CardHeader, CardTitle } from "@/components/ui/card"

<Card>
  <CardHeader>
    <CardTitle>Project</CardTitle>
  </CardHeader>
  <Button variant="outline">View</Button>
</Card>
LibraryBased onNotes
shadcn/uiTailwind + RadixMost popular in 2024+. Copy-paste, not npm install
Material UI (MUI)CSS-in-JSGoogle's Material Design. Heavy
Ant DesignCSSPopular in China. Enterprise-focused
BootstrapCSSThe original. Still used, feels dated
Chakra UICSS-in-JSDeveloper-friendly API. Declining
DaisyUITailwindTailwind component classes

Comparison Matrix

                Pure CSS    CSS Modules   Tailwind    CSS-in-JS
────────────    ────────    ───────────   ────────    ─────────
Collision-free  ❌          ✅            ✅          ✅
Design system   ❌ manual   ❌ manual     ✅ built-in ❌ manual
Dark mode       😰 manual   😰 manual     ✅ easy     ✅ possible
Responsive      😰 manual   😰 manual     ✅ easy     😰 manual
Bundle size     ✅ minimal  ✅ minimal    ✅ purged   ❌ runtime
Server Comp.    ✅          ✅            ✅          ❌
Learning curve  ✅ none     ✅ minimal    ⚠️ medium   ⚠️ medium
File management ❌ grows    ⚠️ many files ✅ none     ✅ co-located
Next.js support ✅          ✅ built-in   ✅ official ⚠️ limited

The Current Trend (2025-2026)

Rising:    Tailwind CSS + shadcn/ui (component library built on Tailwind)
Stable:    CSS Modules (safe, boring, works)
Declining: CSS-in-JS (styled-components, Emotion) — killed by Server Components
Legacy:    Bootstrap, pure CSS at scale