Warna di UI punya dua tugas. Warna struktural membangun halaman: latar, permukaan kartu, garis, dan teks biasa. Warna interaktif menandai yang bisa ditekan: tombol, link, pilihan yang aktif. Bayangin gedung kantor. Dinding, lantai, dan pintu ruangan dicat putih dan abu-abu, tapi tombol lift dan tuas alarm kebakaran berwarna mencolok. Kalau dindingnya dicat merah menyala juga, tuas alarmnya gak ketemu saat dibutuhkan. Warna mencolok cuma berguna kalau dia satu-satunya.
🧪 Tebakan cepat: Bu Sri membuat harga "Rp 350.000 / malam" hijau
#15803dsupaya menonjol, sama hijaunya dengan tombol pesan. Harganya memang jadi menonjol. Apa yang hilang dari tombol "Pesan kamar"? Jawabannya ada di bagian "Tes: hijau yang gak bisa ditekan".
Dua tugas warna di halaman Bu Sri
| Struktural | Interaktif | |
|---|---|---|
| Tugasnya | membangun halaman, gak mengundang aksi | menandai yang bisa ditekan |
| Warnanya | abu-abu kebiruan dan putih | hijau #15803d |
| Di halaman | latar #f1f5f9, kartu #fff, garis #e2e8f0, teks #1f2937 dan #475569 |
tombol pesan, pilihan malam terpilih, link "Lihat aturan batal lengkap", cincin fokus |
Aturannya satu kalimat: di halaman ini, hijau cuma dipakai untuk yang bisa ditekan. Kalau tamu belajar bahwa hijau artinya "tekan aku", dia gak perlu menebak lagi.
Beri nama warna menurut tugasnya
Simpan warna sebagai CSS custom property, dan beri nama menurut tugasnya, bukan menurut warnanya:
:root {
/* struktural */
--surface-page: #f1f5f9;
--surface-card: #ffffff;
--border: #e2e8f0;
--text: #1f2937;
--text-muted: #475569;
/* interaktif */
--action: #15803d;
--action-hover: #166534;
--action-active: #14532d;
--on-action: #ffffff;
}
body { color: var(--text); background-color: var(--surface-page); }
.kabut { background-color: var(--surface-card); border: 1px solid var(--border); }
.price { color: var(--text); }
.book { color: var(--on-action); background-color: var(--action); }
.book:hover { background-color: var(--action-hover); }
.book:active { background-color: var(--action-active); }
.policy { color: var(--action); text-decoration: underline; }
--surface-*,--border, dan--text*adalah warna struktural. Semuanya abu-abu atau putih.--actiondan turunannya adalah warna interaktif. Hover#166534dan tekan#14532ddiambil dari skala hijau yang sama (step 800 dan 900), jadi tetap terbaca sebagai "hijau aksi". Teks putih di atasnya 7,13:1 dan 9,11:1.- Namanya
--action, bukan--green. Kalau suatu hari brand Bu Sri berganti warna, cukup satu baris yang diubah. Dan kalau ada yang menuliscolor: var(--action)di harga, kesalahannya langsung kelihatan dari namanya.
Status nonaktif bukan warna aksi
Tombol pesan nonaktif sebelum tamu memilih jumlah malam. Tombol nonaktif gak bisa ditekan, jadi dia pakai warna struktural: latar #e2e8f0 dengan teks #475569 (6,15:1, tetap terbaca walau WCAG membebaskan komponen nonaktif dari aturan kontras). Hijau pucat masih bilang "tekan aku", padahal gak bisa.
.book:disabled { color: var(--text-muted); background-color: var(--border); cursor: not-allowed; }
Tes: hijau yang gak bisa ditekan
Versi halaman yang "hijau di mana-mana":
| Elemen hijau | Bisa ditekan? |
|---|---|
| Pita header "Homestay Kabut · Dieng" | Tidak |
| Harga "Rp 350.000 / malam" | Tidak |
| Garis kartu | Tidak |
| Tombol "Pesan kamar" | Ya |
| Pilihan malam yang terpilih | Ya |
Tiga dari lima elemen hijau gak bisa ditekan. Jadi jawaban tebakannya: tombol pesan kehilangan tandanya yang khusus. Hijau berhenti berarti "bisa ditekan", karena sekarang hijau juga berarti "penting" atau "hiasan". Di pelajaran affordance, Pak Hadi mengetuk kotak tanggal hijau dua kali karena terlihat seperti tombol; harga hijau mengundang ketukan sia-sia yang sama. Itu jawaban tebakannya. Perbaikannya: kembalikan pita, harga, dan garis ke warna struktural. Harga tetap menonjol lewat tebal dan ukuran, bukan lewat warna aksi.
Latihan: kartu fitur berwarna biru
Latihannya memakai kartu lain dengan warna aksi biru #2563EB. Aturannya sama, cuma warnanya beda:
.card { background-color: #F9FAFB; border: 1px solid #E5E7EB; } /* struktural */
button { background-color: #2563EB; color: white; } /* interaktif */
a { color: #2563EB; } /* interaktif */
- Kartu memakai abu-abu sangat terang
#F9FAFBdan garis#E5E7EB: permukaan yang tenang. - Tombol dan link sama-sama biru, karena keduanya bisa ditekan. Teks putih di tombol 5,17:1, link biru di atas kartu 4,95:1. Dua-duanya lolos 4,5:1.
⚠️ Jebakan yang sering ketemu
- Warna aksi untuk latar besar. Pita header atau section hijau membuat hijau berarti "latar", dan tombol hijau tenggelam di dalamnya.
- Status sukses sewarna tombol. Label "Lunas" di dasbor Bu Sri jangan dibuat tombol hijau penuh. Pakai label tanpa bentuk tombol, misalnya teks
#14532ddi latar#dcfce7(8,30:1) ditambah tulisan atau ikon centang. - Tombol nonaktif tetap berwarna aksi. Hijau atau biru pucat masih mengundang ketukan. Pakai abu-abu.
- Link berwarna struktural. Link abu-abu tanpa garis bawah terlihat seperti teks biasa, jadi gak ada yang menekannya.
TL;DR: Warna struktural (latar, permukaan, garis, teks biasa) membangun halaman dan memakai abu-abu atau putih; di halaman Bu Sri #f1f5f9, #fff, #e2e8f0, #1f2937, dan #475569. Warna interaktif menandai yang bisa ditekan (tombol, link, pilihan aktif) dan cuma dipakai di situ: hijau #15803d, hover #166534, tekan #14532d. Beri nama token menurut tugasnya (--action, --surface-card), bukan warnanya. Tombol nonaktif dan label status bukan warna aksi. Di latihan, aturan yang sama memakai biru: kartu #F9FAFB, tombol dan link #2563EB.