Komponen React diberi style dengan CSS biasa. Beri elemen sebuah class dengan prop className dan tulis aturannya di stylesheet, pakai prop style untuk nilai yang berasal dari JavaScript, dan gunakan CSS Modules atau Tailwind saat proyek makin besar. Contoh di bawah mendefinisikan CSS-nya di dalam elemen <style> agar bisa berjalan di halaman ini; di sebuah proyek, CSS itu akan berada di file .css.
Ganti #2563eb menjadi #16a34a di aturan .btn dan tombolnya berubah hijau. Semua yang kamu tahu tentang CSS tetap berlaku: selector, media query, state hover, animasi.
className, bukan class
JSX dikompilasi menjadi JavaScript, dan di sana class adalah kata kunci yang dicadangkan, jadi React memakai className, nama yang dipakai DOM sendiri untuk property itu (element.className). Browser tetap menerima atribut class biasa. Penggantian nama yang sama berlaku untuk htmlFor sebagai pengganti for pada label. React 19 menerima class dengan peringatan di development, tapi className adalah nama yang benar dan yang dipakai di setiap codebase.
className menerima string, jadi beberapa class dipisahkan spasi: className="btn btn-primary". Karena nilainya adalah JavaScript, nilai itu bisa dihitung.
Class kondisional
Untuk menambahkan class hanya dalam kasus tertentu, susun string-nya dengan ternary atau template literal. Tab bar yang menyorot tab terpilih adalah contoh klasiknya.
Klik Lessons dan garis bawahnya berpindah, karena sekarang hanya string milik tombol itu yang berisi active. Reviews mendapat class disabled dan atribut disabled, jadi tombol itu abu-abu dan mengabaikan klik. Template literal meninggalkan spasi ekstra saat sebuah kondisi bernilai false, dan browser mengabaikannya. Saat sebuah komponen punya banyak class kondisional, array lebih rapi:
const classes = ['tab', isActive && 'active', isDisabled && 'disabled']
.filter(Boolean)
.join(' ');
Banyak proyek memakai package kecil clsx untuk tugas yang sama: clsx('tab', { active: isActive, disabled: isDisabled }).
Prop style
Prop style menerima object JavaScript, bukan string. Itulah sebabnya ada kurung kurawal ganda: pasangan luar membuka ekspresi JavaScript, pasangan dalam adalah object literal. Nama property ditulis dalam camelCase (backgroundColor, fontSize, borderRadius), dan nilainya berupa string atau angka. Angka pada property panjang menjadi piksel, jadi padding: 12 berarti 12px.
Style inline paling berguna saat sebuah nilai dihitung saat render, seperti lebar progress bar.
Klik Add 10% sampai bar-nya penuh dan warnanya berubah hijau. Perhatikan width: percent + '%': angka saja akan berarti piksel, jadi satuan selain px ditulis dalam string. Property tanpa satuan tetap berupa angka biasa, seperti opacity: 0.8, zIndex: 2, flexGrow: 1, dan lineHeight: 1.5 (yang merupakan pengali, bukan piksel).
Style inline punya batasan. Style inline tidak bisa menyatakan :hover, :focus, media query, atau animasi keyframe, dan setiap elemen membawa salinan aturannya sendiri. Pakai untuk nilai dinamis dan simpan sisanya di CSS.
Variabel CSS dari props
Jalan tengah yang bagus adalah mengatur CSS custom property di style lalu memakainya dari stylesheet. Aturannya tetap di CSS, termasuk state hover, dan hanya nilainya yang berasal dari JavaScript.
Pilih warna baru dan kedua tombol mengikutinya, dan warna isi saat hover tetap berfungsi karena itu CSS biasa. Nama custom property tetap memakai tanda hubungnya di object style, jadi namanya ditulis dalam tanda kutip: { '--accent': accent }.
File CSS
Di proyek sungguhan, kamu menulis style di file .css dan meng-import-nya dari komponen yang membutuhkannya. Dengan Vite, import saja sudah cukup: build tool melihat import './Button.css', menambahkan stylesheet ke halaman selama development, dan membundelnya menjadi file CSS untuk production. Tidak ada export yang dipakai; import itu ada hanya untuk efek sampingnya.
// Button.jsx
import './Button.css';
export default function Button({ children }) {
return <button className="button">{children}</button>;
}
/* Button.css */
.button {
background: #2563eb;
color: white;
border-radius: 6px;
}
Masalahnya, setiap stylesheet yang di-import bersifat global. Aturan .button di Button.css memberi style pada setiap elemen dengan class itu, di mana pun di aplikasi, dan dua file yang sama-sama mendefinisikan .title akan saling menimpa. Tim mengatasi ini dengan konvensi penamaan seperti BEM (.card__title), atau dengan CSS Modules.
CSS Modules
File yang berakhiran .module.css adalah CSS Module. Meng-import-nya memberimu object yang memetakan setiap nama class yang kamu tulis ke nama unik yang dibuat otomatis, jadi sebuah class hanya bisa berlaku di tempat kamu memakainya. Vite dan Next.js mendukung ini tanpa setup.
// Card.jsx
import styles from './Card.module.css';
export default function Card({ title, children, featured }) {
return (
<section className={featured ? `${styles.card} ${styles.featured}` : styles.card}>
<h3 className={styles.title}>{title}</h3>
{children}
</section>
);
}
/* Card.module.css */
.card { border: 1px solid #ddd; border-radius: 10px; padding: 16px; }
.featured { border-color: #2563eb; }
.title { margin: 0; }
Di browser, class-nya muncul sebagai sesuatu seperti _card_1x2ab_1. Komponen lain bisa mendefinisikan .title miliknya sendiri dan keduanya tidak akan pernah bentrok. Kamu menulis CSS biasa, termasuk aturan hover dan media query, itulah sebabnya CSS Modules sering menjadi pilihan default untuk style komponen.
Tailwind CSS dengan React
Tailwind memakai pendekatan berbeda: alih-alih menulis aturan, kamu menyusun class utility kecil langsung di className. px-4 mengatur padding horizontal, rounded-lg membulatkan sudut, hover:bg-blue-700 mengubah background saat hover. Tailwind memindai file-filemu dan hanya membuat CSS untuk class yang kamu pakai.
Memasangnya di aplikasi React dengan Vite (Tailwind v4) butuh tiga langkah:
npm install tailwindcss @tailwindcss/vite
// vite.config.js
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import tailwindcss from '@tailwindcss/vite';
export default defineConfig({
plugins: [react(), tailwindcss()],
});
/* src/index.css, imported from main.jsx */
@import "tailwindcss";
Lalu beri style pada komponen dengan class:
function UpgradeCard({ active }) {
return (
<div className="max-w-xs rounded-xl border border-gray-200 p-4">
<h3 className="mb-2 text-lg font-semibold">Pro plan</h3>
<button
className={`rounded-md px-4 py-2 text-white ${active ? 'bg-green-600' : 'bg-blue-600 hover:bg-blue-700'}`}
>
{active ? 'Active' : 'Upgrade'}
</button>
</div>
);
}
Tailwind tidak tersedia di editor halaman ini, jadi contohnya ditampilkan sebagai kode statis. Class kondisional bekerja persis seperti di contoh tab di atas, tapi tulis setiap nama class secara utuh: Tailwind menemukan class dengan memindai teks sumbermu, jadi nama yang dirakit saat runtime seperti `bg-${color}-600` tidak akan pernah dibuat.
Kapan memakai yang mana
- File CSS biasa cocok untuk aplikasi kecil dan style global (reset, font, layout halaman). Waspadai bentrokan nama class saat aplikasi makin besar.
- CSS Modules cocok untuk sebagian besar style komponen: CSS biasa, otomatis ber-scope, tanpa library tambahan.
- Tailwind cocok untuk tim yang lebih suka memberi style di markup dan ingin skala desain bersama untuk jarak dan warna.
- Prop
styleuntuk nilai yang dihitung saat render: lebar, posisi, warna pilihan pengguna. Pasangkan dengan variabel CSS agar aturan hover dan media tetap di CSS.
Kamu bisa mencampurnya. Aplikasi pada umumnya punya satu stylesheet global, CSS Modules atau Tailwind untuk komponen, dan beberapa style inline untuk nilai dinamis. Library CSS-in-JS seperti styled-components dan Emotion adalah pilihan lain yang akan kamu temui di codebase lama. Halaman tentang cara menginstal React menunjukkan cara memulai proyek Vite tempat semua cara ini berfungsi.
Pertanyaan yang sering diajukan
Mengapa React memakai className, bukan class?
JSX dikompilasi menjadi JavaScript, dan class adalah kata kunci yang dicadangkan di sana. React memakai nama property DOM, className, yang juga merupakan nama element.className di JavaScript biasa. Di HTML, nilainya tetap menjadi atribut class biasa.
Bagaimana cara menulis style inline di React?
Berikan object ke prop style, dengan nama property dalam camelCase: style={{ backgroundColor: 'teal', fontSize: 18 }}. Kurung kurawal luar membuka ekspresi JavaScript dan kurung kurawal dalam adalah object-nya. Angka menjadi piksel untuk property yang menerima panjang.
Bagaimana cara menambahkan class secara kondisional di React?
Susun string-nya di JavaScript: className={isActive ? 'tab active' : 'tab'} atau template literal seperti className={`tab ${isActive ? 'active' : ''}`}. Untuk banyak kondisi, helper kecil seperti package clsx menjaga kode tetap mudah dibaca.
Apakah file CSS di React berlaku global?
Ya. import './App.css' menambahkan stylesheet ke seluruh halaman, jadi nama class-nya bisa bentrok dengan file lain. CSS Modules (App.module.css) mengganti nama setiap class menjadi nama unik sehingga hanya berlaku di tempat kamu meng-import-nya.
Bagaimana cara memakai Tailwind dengan React?
Di proyek Vite, instal tailwindcss dan @tailwindcss/vite, tambahkan plugin-nya ke vite.config.js, lalu taruh @import "tailwindcss"; di baris teratas file CSS utamamu. Setelah itu tulis class utility di className, misalnya className="px-4 py-2 rounded bg-blue-600 text-white".