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
- Inline
style={{...}}syntax — DUA kurung kurawal: outer{}= "ini ekspresi JS", inner{}= "ini object literal". Pemula sering tulisstyle={"color: red"}(string) — gak jalan. - camelCase di inline, kebab-case di CSS file —
style={{ backgroundColor: "red" }}(JS) vs.foo { background-color: red }(CSS). Beda, gak ketuker. - Inline style gak support pseudo-class —
:hover,:focus,@mediagak bisa di inline. Pakai CSS file atau library CSS-in-JS. classNamestring concat berantakan —className={"a " + (cond ? "b" : "")}— pakaiclsx/cnlebih clean.- CSS spec property as JS key —
style={{ "z-index": 1 }}(string with dash) deprecated. PakaizIndex: 1. Custom property--varboleh string:style={{ "--theme": "dark" }}. - Tailwind class string panjang — readability turun. Extract ke variable atau pakai
@applydi CSS modules untuk pattern berulang. - Forget
tailwind.config.js— install Tailwind tapi class gak jalan. Setup config + content paths wajib.
🎯 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.