Gradient adalah perpindahan warna yang halus dari satu warna ke warna lain. Kamu cuma menyebut beberapa warna (color stop), dan browser mengisi semua warna di antaranya. Bayangin langit subuh dari bukit Sikunir, dekat homestay Bu Sri: biru tua di atas, oranye di cakrawala, dan gak ada garis di mana birunya berhenti. Modifikasi warna adalah membuat varian dari satu warna dasar, seperti pelukis yang menambah cat putih (tint), cat hitam (shade), atau cat abu-abu (tone, warna yang lebih kalem) ke satu tube warna yang sama.
🧪 Tebakan cepat: Foto Kamar Teras punya teks putih di bagian bawahnya. Kamu pasang gradient gelap dari bawah setinggi 30% foto, lalu menggelapkannya terus sampai 90%. Nama kamarnya akhirnya lolos kontras? Jawabannya ada di bagian "Ukur di titik paling terang".
Gradient di CSS: arah dan color stop
.banner {
background: linear-gradient(135deg, #15803d, #10602d);
}
linear-gradient(arah, warna, warna)menggambar gradient lurus. Kalau arahnya gak ditulis, defaultnya ke bawah (to bottom, sama dengan180deg).- Sudutnya diukur searah jarum jam dari atas:
0degke atas,90degke kanan,180degke bawah, dan135degke kanan bawah. Diagonal 135deg ini arah yang paling sering dipakai untuk latar dekoratif. Itu kebiasaan, bukan hukum. - Di kotak persegi,
to bottom rightsama dengan135deg. Di kotak yang lebar,to bottom rightdihitung ulang supaya sudut kanan atas dan kiri bawah dapat warna tengah, jadi sudutnya bukan 135deg lagi.
Color stop boleh diberi posisi. Dua warna di posisi yang sama bikin garis tegas, bukan perpindahan halus. Begitu cara foto Kamar Teras digambar dengan CSS: langit dari biru #2563eb ke oranye #f59e0b sampai 90% tinggi foto, lalu bukit gelap di 10% terbawah.
.photo { background: linear-gradient(#2563eb, #f59e0b 90%, #3f6212 90%, #1a2e05); }
Tint, shade, dan muted dengan HSL
HSL menulis warna sebagai hue (rona, 0 sampai 360 derajat), saturation (seberapa pekat), dan lightness (seberapa terang). Hijau Bu Sri, #15803d, kira-kira hsl(142 72% 29%). Dari satu warna ini kamu bisa membuat tiga varian:
| Varian | Yang diubah | Hasil | Dipakai untuk |
|---|---|---|---|
| Tint (lebih terang) | lightness naik ke 95% | hsl(142 72% 95%) = #e9fbf0 |
latar catatan "Gratis batal..." |
| Shade (lebih gelap) | lightness turun ke 22% | hsl(142 72% 22%) = #10602d |
tombol pesan saat hover |
| Muted (lebih kalem) | saturation turun ke 25% | hsl(142 25% 29%) = #375c45 |
ikon kebun yang gak boleh mencuri perhatian |
Menurunkan saturation untuk warna yang lebih kalem disebut muted (atau desaturate). Hue-nya tetap, jadi ketiganya masih terasa satu keluarga.
Satu hal yang HSL gak bilang: lightness-nya gak sama dengan terang yang dilihat mata. hsl(60 100% 50%) (kuning) dan hsl(240 100% 50%) (biru) sama-sama lightness 50%, tapi kontrasnya terhadap putih 1,07:1 dan 8,59:1. Muted juga mengubah kontras walau lightness-nya tetap: #15803d 5,02:1 terhadap putih, #375c45 7,56:1. Jadi setelah memodifikasi warna, ukur lagi kontrasnya. Teks hijau #15803d di atas tint 95% masih 4,66:1, tapi di atas tint 90% (#d3f8e1) cuma 4,37:1.
Scrim: teks putih di atas foto
Di kartu Kamar Teras, nama kamar dan harga ditulis putih langsung di atas foto. Masalahnya, foto punya bagian terang (langit dekat cakrawala) dan bagian gelap (bukit). Solusinya scrim: gradient gelap transparan di atas foto, paling gelap di belakang teks dan memudar ke atas, jadi langitnya tetap kelihatan.
.photo {
position: relative;
height: 240px;
background:
linear-gradient(to top, rgba(31, 41, 55, 0.8), rgba(31, 41, 55, 0) 60%), /* scrim */
linear-gradient(#2563eb, #f59e0b 90%, #3f6212 90%, #1a2e05); /* foto */
}
.photo .caption { position: absolute; left: 16px; bottom: 16px; color: white; }
.photo h2 { margin: 0 0 4px; font-size: 24px; font-weight: 700; line-height: 1.25; }
.photo p { margin: 0; font-size: 16px; line-height: 1.5; }
backgroundboleh berisi beberapa lapis, dipisah koma. Lapis pertama ada di paling atas, jadi scrim ditulis sebelum foto.to topmulai dari bawah:#1f2937dengan alpha 0,8 di dasar, memudar ke alpha 0 di 60% tinggi foto (144px dari bawah).- Warna akhirnya
rgba(31, 41, 55, 0), warna yang sama dengan alpha 0, jadi yang berubah cuma transparansinya. - Teksnya di kiri bawah: nama kamar menempati baris 166 sampai 196px dari atas foto, harga 200 sampai 224px.
Ukur di titik paling terang
Mata membaca teks di bagian yang paling lemah. Jadi kontras teks di atas foto diukur di titik paling terang di bawah teks, bukan rata-rata fotonya. Batasnya dari WCAG 1.4.3: teks biasa minimal 4,5:1, teks besar (24px ke atas, atau 18,67px tebal) minimal 3:1. Nama kamar 24px tebal termasuk teks besar; harga 16px teks biasa.
| Scrim | Nama (butuh 3:1) | Harga (butuh 4,5:1) |
|---|---|---|
| Tanpa scrim | 2,39:1 di 196px, gagal | 2,16:1 di 215px, gagal |
| Tinggi 30%, gelap 90% | 2,79:1 di 168px, gagal | 4,67:1, lolos |
| Tinggi 60%, gelap 80% | 5,20:1 di 166px, lolos | 6,61:1, lolos |
Baris kedua menjawab tebakannya: gak lolos. Scrim setinggi 30% berhenti di 72px dari bawah, yaitu di 168px dari atas, sedangkan nama kamar mulai di 166px. Ujung atas nama kamar ada di atas langit oranye, tempat scrim-nya sudah memudar ke 0. Menggelapkan bagian bawah sampai 90% gak menyentuh titik itu. Itu jawaban tebakannya. Yang menolong adalah scrim yang lebih tinggi: dengan 60% dan gelap 80%, titik paling terang di bawah nama jadi #84683c, dan kontrasnya 5,20:1.
Ruang interpolasi: sRGB atau oklch
Browser mengisi warna di antara dua color stop dengan menghitung di sebuah ruang warna. Gradient yang ditulis dengan hex atau rgb() dihitung di sRGB. Di sRGB, jalan lurus dari biru ke oranye lewat abu-abu: titik tengah langit Kamar Teras jadi #8d817b, cokelat kusam. Tulis in oklch, dan browser menghitung di oklch, ruang warna yang menjaga kepekatan dan memutar hue-nya: titik tengahnya jadi #df57a9, merah muda seperti langit subuh sungguhan.
.photo {
background: linear-gradient(#2563eb, #f59e0b 90%, #3f6212 90%, #1a2e05); /* cadangan */
background: linear-gradient(in oklch, #2563eb, #f59e0b 90%, #3f6212 90%, #1a2e05);
}
- Browser lama yang belum mengenal
in oklchmembuang deklarasi kedua dan memakai yang pertama. - Untuk dua warna yang hue-nya dekat (hijau ke hijau tua), hasil sRGB dan oklch hampir sama. Bedanya terasa di warna yang hue-nya jauh.
💡 Banding: pita di gradient yang halus
Layar biasa menyimpan tiap channel merah, hijau, biru dalam 256 tingkat. Dari #1f2937 ke #111827, merah cuma turun 14 tingkat, hijau 17, biru 16. Jadi di antara keduanya cuma ada 48 warna. Direntangkan sejauh 800px, tiap warna kebagian sekitar 17px, dan kadang terlihat sebagai pita bertingkat (banding). Chrome dan Safari menyamarkannya dengan dithering: dua warna tetangga ditaburkan titik demi titik. Firefox, saat kami uji, menggambar 48 pita rata. Cara mengurangi banding: perpendek jaraknya, perbesar beda warnanya, atau tambahkan tekstur noise tipis.
⚠️ Jebakan yang sering ketemu
- Mengukur kontras di bagian gelap foto. Ukur di titik paling terang di bawah teks, karena di situ teks paling susah dibaca.
- Scrim terlalu pendek. Menggelapkan bagian bawah gak menolong baris teks yang ada di atas scrim. Tinggikan scrim-nya sampai menutup seluruh blok teks.
- Gradient di belakang paragraf. Kontras berubah di sepanjang baris, jadi tiap kata harus lolos. Taruh teks panjang di latar polos.
- Percaya lightness HSL. Lightness yang sama bisa berarti kontras yang jauh beda. Tint, shade, dan muted harus dicek kontrasnya lagi.
TL;DR: linear-gradient(arah, warna, warna) menggambar gradient; 135deg (ke kanan bawah, sama dengan to bottom right di kotak persegi) adalah diagonal yang paling umum untuk latar dekoratif, dan dua color stop di posisi yang sama bikin garis tegas. Dari satu warna HSL: tint = lightness naik, shade = lightness turun, muted = saturation turun; lightness HSL gak sama dengan terang di mata, jadi ukur kontrasnya lagi. Teks putih di atas foto butuh scrim, gradient gelap transparan yang ditulis sebagai lapis pertama background, dan kontrasnya diukur di titik paling terang di bawah teks: 4,5:1 untuk teks biasa, 3:1 untuk teks besar. Scrim yang terlalu pendek gak menolong walau digelapkan. Gradient hex dihitung di sRGB dan bisa kusam di tengah; in oklch menjaga warnanya tetap hidup. Gradient yang beda warnanya kecil di jarak jauh bisa berpita (banding).