Styling Komponen — React

React komponen-based, tapi CSS sifatnya GLOBAL secara default — class .btn di file A bisa nabrak class .btn di file B. Perang specificity, override…

React komponen-based, tapi CSS sifatnya GLOBAL secara default — class .btn di file A bisa nabrak class .btn di file B. Perang specificity, override !important, naming convention BEM yang panjang — semua usaha buat ngakali fakta dasar bahwa CSS gak punya scope per-komponen. Tahun-tahun terakhir, ekosistem React jawab dengan banyak solusi: CSS Modules (auto-scope), Tailwind (utility-first), styled-components (CSS-in-JS), inline style (paling simple). Pilih yang cocok = produktivitas naik signifikan.

💡 2026 default = Tailwind. Survey developer 2024-2026, Tailwind dominasi di project React baru. Gak heran — utility-first ngehindarin masalah naming + global scope sekaligus, plus ada IntelliSense + design system built-in. Tapi paham 4 pendekatan dasar di bawah dulu — Tailwind cuma evolusi dari className-based.

1. Inline Style (Object)

function App() {
  return (
    <div style={{ backgroundColor: "skyblue", padding: "20px" }}>
      Kotak Biru
    </div>
  )
}

CSS property pakai camelCase (backgroundColor, bukan background-color) — itu JavaScript object key, bukan CSS string. Cocok buat dynamic style berdasar state.

2. className + CSS File

import "./Button.css"

function Button({ active }) {
  return (
    <button className={active ? "btn-active" : "btn-default"}>
      Tombol
    </button>
  )
}

3. Conditional / Combine Classes

// Template literal
<div className={`card ${highlighted ? "highlight" : ""}`}>

// Library `clsx` (popular, ringan)
import { clsx } from "clsx"
<div className={clsx("card", highlighted && "highlight", { error: hasError })}>

// Project ini pakai cn() utility (clsx + tailwind-merge)
<div className={cn("card", highlighted && "highlight")}>

4. CSS Modules — Auto-Scoped

import styles from "./Button.module.css"
// .primary class di Button.module.css jadi unique class name otomatis

function Button() {
  return <button className={styles.primary}>Klik</button>
}

Class name di CSS module di-hash otomatis (Button_primary_x7k2) → no more global naming clash.

5. Tailwind — Utility-First

function Button({ active }) {
  return (
    <button className={cn(
      "px-4 py-2 rounded font-medium transition",
      active ? "bg-blue-600 text-white" : "bg-gray-200 text-gray-700"
    )}>
      Tombol
    </button>
  )
}

Gak perlu nulis CSS file — tinggal compose utility class di className.

🎭 Analogi sehari-hari

Pendekatan styling = pilihan pakaian. Inline style kayak nge-paint baju langsung pas mau dipake — fleksibel, dynamic, tapi gak reusable. className + CSS file kayak baju seragam yang udah dijahit di pabrik — beli sekali, pake banyak orang, tapi modifikasi terbatas. CSS Modules kayak seragam dengan label nama jahit ("Andi-rom-3A") — gak akan ketuker meski ada yang punya seragam mirip. Tailwind kayak "Lego pakaian" — banyak komponen kecil terstandardisasi (saku, kerah, lengan), kombinasi tanpa batas, gak perlu jahit dari nol. Pilih sesuai kebutuhan: dynamic? Inline. Tim kecil + simple? CSS file. Project besar + scoped? CSS Modules. Speed + design system? Tailwind.

⚠️ Jebakan yang sering ditemui

🎯 Pilih pendekatan styling — pakai mana?

  • Project React baru 2026 → Tailwind (default modern, fast iteration)
  • Existing project + tim familiar dengan CSS → CSS Modules (gak ada lock-in, gradual adopt)
  • Component library yang shared antar project → CSS-in-JS (styled-components/emotion) atau CSS Modules
  • Style yang BENER-BENER dynamic dari runtime (color picker, drag position) → inline style
  • Side project quick prototype → inline style atau CSS biasa, gak perlu setup
  • Design system besar dengan token consistent → Tailwind + tailwind.config theming

Aturan: di belajarweb.dev/hypersheets project pakai cn() utility (clsx + tailwind-merge) — pattern modern Tailwind + safe class merging.

TL;DR: 4 pendekatan styling React: inline style={{}} (camelCase, dynamic), className + CSS file (simple, global), CSS Modules (auto-scoped, no naming clash), Tailwind (utility-first, modern default 2026). Inline style gak support :hover/@media. Gabung class? Pakai clsx atau project cn() utility. CSS-in-JS lib (styled-components) cocok untuk shared component library. Default 2026 untuk project baru: Tailwind.

Yang akan kamu pelajari