🎨 CSS

Cascading Style Sheets — bahasa untuk mengatur tampilan dan desain halaman web.

📌 Baca ini dulu sebelum lanjut!

🧱 Fundamental CSS

Sebelum masuk detail property satu-satu, pahami dulu konsep-konsep inti ini. Cuma butuh beberapa menit, tapi bakal bikin materi selanjutnya jauh lebih gampang dicerna.

📌 Fundamental CSS udah kamu baca.

Pengenalan CSS

CSS adalah bahasa yang dipakai untuk mengatur tampilan elemen HTML — warna, ukuran, posisi, font, animasi, dan masih banyak lagi. Kalau HTML itu tulang dan struktur halaman, CSS itu kulit dan gaya berpakaiannya.

💡 CSS bekerja dengan cara memilih elemen (selector) lalu memberi aturan tampilan dalam format property: value;.
css
/* Struktur dasar CSS */
selector {
  property: value;
  property: value;
}

/* Contoh nyata */
h1 {
  color: blue;
  font-size: 2rem;
  font-weight: bold;
}
✅ Best Practice: Biasakan menulis CSS yang konsisten — pilih satu gaya penamaan class (mis. kebab-case seperti .tombol-utama) dan pakai terus di seluruh project supaya mudah dibaca tim lain.

Cara Pakai CSS

Ada 3 cara menulis CSS, masing-masing dengan kegunaan berbeda. Yang paling direkomendasikan untuk project nyata adalah cara eksternal (file terpisah).

  • Inline — langsung di atribut style elemen HTML, cocok untuk override cepat saja
  • Internal — di dalam tag <style> di <head>, cocok untuk halaman tunggal atau demo
  • Eksternal — file .css terpisah yang dilink ke HTML, cocok untuk project nyata karena bisa dipakai ulang di banyak halaman
html
<!-- 1. Inline -->
<p style="color: red; font-size: 18px;">Teks merah</p>

<!-- 2. Internal -->
<head>
  <style>
    p { color: blue; }
  </style>
</head>

<!-- 3. Eksternal (paling direkomendasikan) -->
<head>
  <link rel="stylesheet" href="style.css">
</head>
✅ Best Practice: Hindari inline style untuk styling utama — inline punya spesifisitas paling tinggi sehingga susah di-override, dan bikin HTML jadi kotor. Simpan untuk kasus dinamis lewat JavaScript saja.

Selector

Selector menentukan elemen HTML mana yang akan diberi style. Memahami selector dengan baik adalah salah satu kunci utama menguasai CSS.

css
/* Tag selector — semua elemen <p> */
p {
  color: gray;
}

/* Class selector — elemen dengan class="kartu" */
.kartu {
  background: white;
  border-radius: 8px;
}

/* ID selector — elemen dengan id="judul" */
#judul {
  font-size: 2rem;
}

/* Kombinasi */
.kartu p {         /* <p> di dalam .kartu */
  font-size: 0.9rem;
}

/* Pseudo-class */
a:hover {          /* link saat di-hover */
  color: blue;
}

input:focus {      /* input saat diklik */
  border-color: purple;
}
💡 Urutan prioritas selector (dari lemah ke kuat): tag → class → ID → inline style. Selector yang lebih spesifik akan menang kalau ada aturan yang bentrok.
✅ Best Practice: Lebih sering pakai class daripada id untuk styling — class bisa dipakai berkali-kali dan lebih fleksibel, sedangkan id sebaiknya disimpan untuk anchor link atau target JavaScript.

Warna & Background

CSS punya banyak cara untuk menuliskan warna. Untuk background, bisa berupa warna solid, gradient, atau gambar.

css
/* Format warna */
.kotak {
  color: red;                   /* nama warna */
  color: #ff0000;               /* hex */
  color: rgb(255, 0, 0);        /* rgb */
  color: rgba(255, 0, 0, 0.5);  /* rgba + opacity */
  color: hsl(0, 100%, 50%);     /* hsl */
}

/* Background */
.hero {
  background-color: #0f0f1c;
  background-image: url("bg.jpg");
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}

/* Gradient */
.btn {
  background: linear-gradient(135deg, #60a5fa, #a78bfa);
}

.radial {
  background: radial-gradient(circle, #1e1e35, #07070f);
}
✅ Best Practice: Pakai format hsl() kalau sering bikin variasi warna (mis. lebih gelap/terang) — tinggal ubah angka lightness, lebih intuitif dibanding utak-atik hex.

Teks & Font

CSS punya banyak properti untuk mengatur tampilan teks, mulai dari ukuran sampai jarak antar huruf. Font kustom juga bisa diambil dari layanan seperti Google Fonts.

css
/* Import Google Fonts di HTML */
/* <link href="https://fonts.googleapis.com/css2?family=Inter&display=swap" rel="stylesheet"> */

body {
  font-family: 'Inter', sans-serif;  /* pakai Google Fonts */
  font-size: 16px;                   /* ukuran dasar */
  line-height: 1.6;                  /* jarak antar baris */
  color: #333;
}

h1 {
  font-size: 2.5rem;     /* 1rem = 16px default */
  font-weight: 700;      /* tebal */
  letter-spacing: -1px;  /* jarak antar huruf */
  text-align: center;
}

p {
  font-size: 1rem;
  font-weight: 400;
  text-transform: uppercase;  /* HURUF KAPITAL */
  text-decoration: underline; /* garis bawah */
}
✅ Best Practice: Gunakan satuan rem untuk ukuran font, bukan px — rem mengikuti ukuran font dasar browser, jadi lebih ramah untuk pengguna yang mengubah pengaturan aksesibilitas.

🧱 Bikin Kotak di Web

Salah satu skill paling dasar (tapi paling sering dipakai) di CSS adalah bikin "kotak" — elemen persegi dengan ukuran, warna, dan sudut sendiri. Kotak ini nantinya jadi bahan dasar untuk kartu, tombol, badge, dan hampir semua komponen UI. Yuk kita bangun satu kotak dari nol, langkah demi langkah. Coba ketik sendiri kodenya di kotak edit setiap langkah!

1

Mulai dari elemen kosong

Di HTML, siapkan sebuah <div> dengan class kotak. Tanpa CSS sama sekali, div ini tidak kelihatan — tingginya 0 karena tidak ada isi/konten di dalamnya.

HTML: <div class="kotak"></div>
2

Kasih ukuran: width & height

Supaya kotaknya kelihatan, kasih ukuran pakai width (lebar) dan height (tinggi). Coba ubah angkanya di kotak edit di bawah dan lihat perubahannya langsung.

Coba: ubah width jadi 150px dan height jadi 100px.
3

Kasih warna: background-color

Kotak sudah kelihatan bentuknya, tapi masih abu-abu polos. Tambahkan background-color untuk mewarnainya. Boleh pakai nama warna, hex, atau rgb — bebas.

Coba: ganti warnanya jadi warna favoritmu, misalnya #60a5fa atau tomato.
4

Tambahkan garis pinggir: border

border menambahkan garis di sekeliling kotak. Formatnya: border: [ketebalan] [jenis garis] [warna]; — bisa ditulis dalam satu baris seperti itu (disebut shorthand).

Coba: ubah ketebalannya jadi 4px atau ganti jenis garisnya jadi dashed.
5

Lengkungkan sudutnya: border-radius

Supaya kotak tidak terlalu kaku, tambahkan border-radius untuk melengkungkan sudutnya. Semakin besar angkanya, semakin bulat sudutnya. Kalau nilainya setengah dari lebar/tinggi (atau 50%), kotak akan jadi lingkaran sempurna!

Coba: ubah border-radius jadi 50% dan lihat kotak berubah jadi lingkaran.
6

Kasih jarak dalam: padding

Kalau nanti kotakmu diisi teks atau ikon, kamu butuh padding supaya isinya tidak menempel di pinggir kotak. Di step ini kita tambahkan sedikit teks + padding supaya lebih realistis.

Coba: perbesar padding jadi 24px dan lihat kotak jadi lebih lega.
Halo!

📋 Rekap: Anatomi Kotak CSS

  • width / height — ukuran lebar & tinggi kotak
  • background-color — warna latar kotak
  • border — garis pinggir kotak
  • border-radius — lengkungan sudut kotak
  • padding — jarak dari pinggir kotak ke isi/konten di dalamnya
✅ Best Practice: Kalau kotakmu punya padding dan border sekaligus, selalu tambahkan box-sizing: border-box supaya ukuran total kotak tetap sesuai width/height yang kamu tentukan, bukan malah membesar.

Satuan Ukuran (Units)

CSS punya banyak satuan ukuran, dan masing-masing punya kegunaan yang beda. Memilih satuan yang tepat bikin layout-mu lebih fleksibel dan gampang di-maintain.

120px (tetap)
40% (dari parent)
20vw (dari layar)
10rem (dari font dasar)
css
/* px — ukuran tetap (fixed), tidak menyesuaikan apa pun */
.kotak-px { width: 120px; }

/* % — relatif terhadap ukuran parent/induknya */
.kotak-persen { width: 50%; }   /* setengah lebar induknya */

/* vw / vh — relatif terhadap ukuran layar (viewport) */
.hero { height: 100vh; }        /* setinggi layar penuh */
.banner { width: 50vw; }        /* separuh lebar layar */

/* rem — relatif terhadap font-size root (<html>), biasanya 16px */
h1 { font-size: 2rem; }         /* 2 x 16px = 32px */

/* em — relatif terhadap font-size elemen induknya sendiri */
.desc { font-size: 1.5em; }     /* 1.5 x ukuran parent langsung */
  • px — pas untuk border, shadow, atau detail kecil yang memang harus presisi
  • % — pas untuk lebar kolom/kartu yang mengikuti kontainernya
  • vw / vh — pas untuk elemen full-screen seperti hero section
  • rem — pas untuk font-size dan spacing, karena ikut menyesuaikan kalau user ubah setting aksesibilitas browser
💡 Kalau bingung mulai dari mana: pakai rem untuk font-size & spacing, % untuk lebar layout, dan px hanya untuk detail kecil seperti border.
✅ Best Practice: Hindari terlalu banyak px untuk ukuran besar (lebar section, tinggi container) — itu bikin layout kaku dan susah responsif. Simpan px untuk hal-hal kecil saja.

Box Model

Setiap elemen HTML pada dasarnya adalah "kotak" yang punya 4 lapisan: content, padding, border, dan margin. Memahami box model dengan baik sangat penting untuk mengatur layout.

💡 box-sizing: border-box bikin ukuran elemen lebih mudah diprediksi — padding dan border ikut dihitung masuk ke dalam ukuran total, bukan menambah ukuran dari luar.
css
/* Reset global yang disarankan */
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.kartu {
  width: 300px;
  height: auto;

  /* Padding — jarak konten ke border */
  padding: 20px;           /* semua sisi */
  padding: 10px 20px;      /* atas-bawah | kiri-kanan */
  padding-top: 10px;       /* satu sisi */

  /* Border */
  border: 1px solid #ccc;
  border-radius: 12px;     /* sudut melengkung */

  /* Margin — jarak ke elemen lain */
  margin: 0 auto;          /* tengah horizontal */
  margin-bottom: 16px;
}
✅ Best Practice: Selalu mulai stylesheet dengan reset box-sizing: border-box secara global — ini standar industri yang menghindari banyak bug layout tak terduga.

Display: block, inline, inline-block

Properti display menentukan bagaimana sebuah elemen "berperilaku" di halaman — apakah dia mengambil satu baris penuh, atau cuma sebesar isinya. Ini konsep dasar yang penting dipahami sebelum masuk ke Flexbox.

block — ambil satu baris penuh
block lain — otomatis pindah baris
inline — sebesar isinya, nempel sejajar teks

inline-block Ainline-block B
css
/* block — selalu mulai baris baru, lebar penuh secara default */
div, p, h1, section {
  display: block;   /* ini nilai default tag-tag tersebut */
}

/* inline — sejajar dengan teks, TIDAK bisa diberi width/height */
span, a, strong {
  display: inline;  /* ini nilai default tag-tag tersebut */
}

/* inline-block — sejajar seperti inline, TAPI bisa diberi width/height */
.badge {
  display: inline-block;
  width: 80px;
  padding: 6px 10px;
}

/* none — menyembunyikan elemen sepenuhnya (tidak makan ruang) */
.tersembunyi {
  display: none;
}
💡 Elemen inline seperti <span> tidak bisa diberi width/height — kalau kamu butuh mengatur ukurannya, ganti jadi inline-block atau block.
✅ Best Practice: Kalau elemen tidak tampil sesuai harapan saat diberi width atau margin atas-bawah, cek dulu nilai display-nya — kemungkinan besar dia masih inline.

Flexbox

Flexbox adalah sistem layout satu dimensi (baris atau kolom) yang bikin pengaturan posisi elemen jadi gampang. Paling sering dipakai untuk navbar, card list, dan centering.

css
/* Container flex */
.navbar {
  display: flex;
  align-items: center;       /* rata tengah vertikal */
  justify-content: space-between; /* sebar kiri-kanan */
  gap: 1rem;                 /* jarak antar item */
}

/* Tengah sempurna */
.hero {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
}

/* Grid kartu responsif pakai flex-wrap */
.grid {
  display: flex;
  flex-wrap: wrap;           /* pindah baris kalau penuh */
  gap: 1rem;
}

.grid-item {
  flex: 1 1 250px;           /* min 250px, bisa melebar */
}

/* Kolom vertikal */
.card {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}
✅ Best Practice: Pakai Flexbox untuk layout satu arah (baris/kolom sederhana) seperti navbar atau toolbar. Untuk layout dua dimensi yang lebih kompleks, CSS Grid biasanya lebih cocok — lihat section berikutnya.

Responsive Design

Responsive artinya tampilan menyesuaikan diri dengan ukuran layar perangkat. Pakai @media query untuk mengatur style berbeda berdasarkan lebar layar.

💡 Pendekatan mobile-first: tulis style dasar untuk HP dulu, baru tambahkan @media (min-width: ...) untuk layar yang lebih besar. Ini biasanya menghasilkan CSS yang lebih ringkas.
css
/* Default: mobile */
.grid {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

h1 { font-size: 1.8rem; }

/* Tablet (min 768px) */
@media (min-width: 768px) {
  .grid {
    flex-direction: row;
    flex-wrap: wrap;
  }

  h1 { font-size: 2.5rem; }
}

/* Desktop (min 1024px) */
@media (min-width: 1024px) {
  .grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
  }

  h1 { font-size: 3rem; }
}

/* Sembunyikan di mobile */
@media (max-width: 767px) {
  .nav-links { display: none; }
}
✅ Best Practice: Jangan terlalu banyak breakpoint. Biasanya 2-3 breakpoint (mobile, tablet, desktop) sudah cukup untuk sebagian besar project — fokus pada konten yang butuh penyesuaian, bukan ukuran layar tertentu.

CSS Grid

CSS Grid adalah sistem layout dua dimensi (baris dan kolom sekaligus), berbeda dengan Flexbox yang cuma satu dimensi. Grid sangat cocok untuk layout halaman secara keseluruhan, galeri foto, atau dashboard.

css
.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);  /* 3 kolom sama lebar */
  gap: 1rem;
}

/* Responsif otomatis tanpa media query */
.grid-auto {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 1rem;
}

/* Elemen bisa menempati beberapa kolom/baris */
.featured {
  grid-column: span 2;   /* lebar 2 kolom */
  grid-row: span 2;      /* tinggi 2 baris */
}

/* Layout halaman dengan grid-template-areas */
.layout {
  display: grid;
  grid-template-columns: 200px 1fr;
  grid-template-areas:
    "sidebar header"
    "sidebar main";
}
.sidebar { grid-area: sidebar; }
.header  { grid-area: header; }
.main    { grid-area: main; }

Contoh hasil dari grid-template-columns: repeat(auto-fill, minmax(80px, 1fr)) — coba lebarkan/perkecil jendela browser untuk lihat perubahannya:

1
2
3
4
5
6
✅ Best Practice: Pakai Grid untuk struktur layout besar (halaman, dashboard), dan Flexbox untuk menyusun isi di dalam tiap komponen kecil. Keduanya sering dipakai berbarengan, bukan saling menggantikan.

🎛 Playground Box Model

Geser slider-nya dan lihat langsung gimana padding, margin, border-radius, border, dan font-size ngaruh ke kotak — sambil baca kode CSS-nya yang otomatis ke-generate di bawah.

Halo!
css (auto-generated)
.kotak {
  padding: 20px;
  margin: 0px;
  border-radius: 8px;
  border: 2px solid #60a5fa;
  font-size: 16px;
}

🧲 Playground Flexbox & Grid

Klik tombol-tombol properti di bawah dan lihat langsung gimana posisi kotak-kotak di dalam kontainer berubah. Flexbox itu paling gampang dipahami kalau langsung diliat gerak, bukan cuma dibaca.

1
2
3
css (auto-generated)

🐛 Betulin CSS Rusak

6 kode CSS di bawah ini sengaja dibikin rusak — typo nama properti, lupa titik koma, lupa satuan, sampai selector yang salah. Edit langsung di kotak abu-abu, klik ▶ Jalankan & Cek buat lihat apakah perbaikanmu bikin tampilannya bener.

Progress: 0 / 6 kode berhasil dibetulin

⚔️ Selector Specificity Battle

Konsep yang paling sering bikin bingung: kenapa CSS yang udah ditulis kadang nggak "kepakai"? Jawabannya soal specificity — aturan siapa yang lebih "kuat". Di bawah ini dua aturan CSS berebut styling elemen yang sama — tebak siapa yang menang, terus buktikan sendiri hasilnya.


🎬 Animasi Playground

Pilih jenis animasinya, atur durasi & easing-nya, terus klik ▶ Play buat liat efeknya langsung di kotak. Animasi CSS itu paling asik dipelajari kalau langsung diliat gerak, bukan cuma dibaca kodenya.

Jenis Animasi
Easing
css (auto-generated)

Positioning

Properti position menentukan bagaimana sebuah elemen ditempatkan di halaman, lepas dari alur normal dokumen kalau diperlukan.

  • static — posisi normal (default), mengikuti alur dokumen
  • relative — bergeser dari posisi normalnya, tapi ruang aslinya tetap dijaga
  • absolute — keluar dari alur dokumen, posisinya relatif terhadap parent terdekat yang ber-position
  • fixed — menempel di posisi tertentu pada viewport, tidak ikut scroll
  • sticky — gabungan relative & fixed, "menempel" saat melewati titik tertentu saat scroll
css
/* Badge notifikasi di pojok kanan atas ikon */
.ikon-wrap {
  position: relative;   /* jadi acuan untuk anak absolute */
}
.badge {
  position: absolute;
  top: -6px;
  right: -6px;
  background: red;
  border-radius: 50%;
  width: 18px; height: 18px;
}

/* Navbar yang selalu di atas saat di-scroll */
.navbar {
  position: sticky;
  top: 0;
  z-index: 100;
}

/* Tombol "scroll to top" mengambang */
.scroll-top {
  position: fixed;
  bottom: 24px;
  right: 24px;
  z-index: 200;
}
.ikon-wrap
🔔3
💡 z-index hanya berfungsi pada elemen yang sudah punya position selain static. Semakin besar nilainya, semakin elemen itu tampil di lapisan paling atas.
✅ Best Practice: Hindari position: absolute untuk layout besar — pakai untuk elemen kecil saja seperti badge, tooltip, atau dropdown. Untuk layout utama, andalkan Flexbox atau Grid.

Border Tricks

border bisa lebih dari sekadar garis pinggir biasa. Dengan sedikit trik, border bisa dipakai untuk aksen visual, bahkan membuat bentuk seperti segitiga tanpa gambar sama sekali.

Border per Sisi

Kamu tidak harus memberi border ke semua sisi sekaligus — tiap sisi bisa diatur beda-beda.

accent atas
border-top tebal
dashed
border-style: dashed
outline
border + outline
css
/* Border per sisi — sering dipakai untuk aksen "garis warna" */
.kartu-aktif {
  border-top: 4px solid #60a5fa;
  border-bottom: 1px solid #1e1e35;
  border-left: 1px solid #1e1e35;
  border-right: 1px solid #1e1e35;
}

/* Border-style selain solid */
.kotak-dashed  { border: 2px dashed #a78bfa; }
.kotak-dotted  { border: 2px dotted #4ade80; }

/* outline berbeda dengan border: tidak memengaruhi ukuran elemen
   dan bisa punya jarak (outline-offset) dari border */
.kotak-fokus {
  border: 1px solid #1e1e35;
  outline: 3px solid #fbbf24;
  outline-offset: 3px;
}

Border Jadi Bentuk Segitiga

Trik klasik CSS: kalau lebar dan tinggi sebuah elemen adalah 0, lalu diberi border tebal di beberapa sisi dengan warna transparent pada sisi lainnya, hasilnya akan membentuk segitiga.

css
.segitiga {
  width: 0;
  height: 0;
  border-left: 30px solid transparent;
  border-right: 30px solid transparent;
  border-bottom: 50px solid #60a5fa;
}
/* Sering dipakai untuk ikon "panah dropdown" atau ekor tooltip */
✅ Best Practice: Untuk ikon panah/segitiga kecil, trik border jauh lebih ringan daripada memakai gambar — tidak perlu request file tambahan dan warnanya gampang diganti lewat CSS.

Shadow & Depth

Bayangan (shadow) membuat elemen terasa punya kedalaman — seolah "mengambang" di atas halaman. Ada dua jenis utama: box-shadow untuk elemen, dan text-shadow untuk teks.

sm
shadow tipis
md
shadow sedang
lg
shadow besar
glow
shadow warna (glow)
css
/* Format: box-shadow: offset-x offset-y blur warna; */

.shadow-tipis {
  box-shadow: 0 2px 6px rgba(0,0,0,.35);
}

.shadow-sedang {
  box-shadow: 0 8px 20px rgba(0,0,0,.45);
}

.shadow-besar {
  box-shadow: 0 20px 45px rgba(0,0,0,.55);
}

/* Glow — shadow berwarna, sering dipakai di dark theme */
.shadow-glow {
  box-shadow: 0 0 24px rgba(96,165,250,.5);
}

/* Bisa ditumpuk lebih dari satu, dipisah koma */
.shadow-berlapis {
  box-shadow:
    0 1px 2px rgba(0,0,0,.2),
    0 8px 20px rgba(0,0,0,.3);
}

Untuk teks, gunakan text-shadow dengan format yang mirip:

Halo, web-ngoding!
css
.judul-glow {
  text-shadow: 0 2px 10px rgba(96,165,250,.6);
}
💡 Semakin besar nilai blur (angka ketiga), semakin lembut/menyebar bayangannya. Nilai offset-y positif membuat bayangan jatuh ke bawah, seolah cahaya datang dari atas.
✅ Best Practice: Jangan pakai warna hitam solid (#000) untuk shadow — pakai rgba(0,0,0, opacity) supaya bayangannya terlihat lebih natural dan lembut, bukan kotak gelap tegas.

Animasi & Transition

transition dipakai untuk membuat perubahan style jadi halus (mis. saat hover), sementara @keyframes + animation dipakai untuk animasi yang lebih kompleks dan bisa berjalan otomatis/berulang.

css
/* Transition — perubahan halus antar state */
.btn {
  background: #6366f1;
  transform: scale(1);
  transition: transform .2s ease, background .2s ease;
}
.btn:hover {
  background: #4f46e5;
  transform: scale(1.05);
}

/* Keyframes — animasi custom */
@keyframes pulse {
  0%   { transform: scale(1);   opacity: 1; }
  50%  { transform: scale(1.1); opacity: .7; }
  100% { transform: scale(1);   opacity: 1; }
}

.dot {
  animation: pulse 1.5s ease-in-out infinite;
}

Coba arahkan kursor ke kotak pertama, dan perhatikan kotak kedua yang beranimasi otomatis:

hover aku
auto pulse
✅ Best Practice: Animasikan hanya properti transform dan opacity kalau bisa — keduanya paling ringan diproses browser dibanding properti lain seperti width atau top, sehingga animasi lebih mulus.

CSS Variables

CSS Variables (Custom Properties) memungkinkan kita menyimpan nilai yang bisa dipakai ulang di banyak tempat, dan diubah secara terpusat — mirip variabel di bahasa pemrograman, tapi langsung dipahami browser.

css
/* Deklarasi variabel di :root (berlaku global) */
:root {
  --warna-utama: #6366f1;
  --radius: 12px;
  --spasi: 1rem;
}

/* Pemakaian lewat var() */
.btn {
  background: var(--warna-utama);
  border-radius: var(--radius);
  padding: var(--spasi);
}

/* Variabel bisa di-override per komponen/tema */
.btn.danger {
  --warna-utama: #ef4444;
}

[data-theme="light"] {
  --warna-utama: #2563eb;
}

Contoh kartu di bawah ini stylingnya 100% dikontrol lewat var(--aksen):

biru
ungu
hijau
💡 Ganti satu variabel, semua elemen yang memakainya ikut berubah otomatis. Ini sangat berguna untuk bikin fitur dark/light theme atau ganti tema warna brand.
✅ Best Practice: Simpan warna, spacing, dan ukuran font yang sering dipakai sebagai CSS Variables di :root sejak awal project — ini bikin perubahan desain di kemudian hari jauh lebih cepat, tinggal ubah satu tempat.

✦ Coba Sendiri

Tulis kode HTML, CSS, dan JavaScript di tiga tab berbeda, klik Run, lalu lihat hasil gabungannya langsung di panel kanan.

Live Editor
code
preview

🚀 Mini Project: Kartu Produk Interaktif

Saatnya gabungkan semua materi CSS yang sudah dipelajari — Flexbox/Grid untuk layout, transition untuk efek hover, positioning untuk badge, dan CSS Variables untuk warna aksen — jadi satu kartu produk yang interaktif.

💡 Tantangan:
1. Buat layout kartu pakai flexbox atau grid.
2. Tambahkan badge "Diskon" dengan position: absolute.
3. Buat tombol beli yang membesar halus saat di-hover pakai transition.
4. Atur warna aksen kartu lewat satu CSS Variable di :root.
5. (Opsional) Tambahkan interaksi sederhana lewat JavaScript, mis. tombol "Tambah ke Keranjang".
Mini Project Editor
code
preview
🎯 Lanjutkan belajarmu: Setelah kartu produkmu jadi, lanjut ke materi JavaScript supaya kamu bisa bikin interaksi yang lebih kompleks, seperti filter produk atau keranjang belanja sungguhan!
🔄 Versi baru tersedia