- Bab 6 dari 7
- 30 menit
- 1 latihan kode
- 4 soal kuis
Studi Kasus: Tombol Mode Gelap dari Tiga Berkas
Di bab ini (9 bagian)
Tujuan bab ini
- Membangun proyek mini tombol mode gelap dari tiga berkas:
index.html,style.css, danscript.js. - Menyiapkan tema dengan CSS variables dan selector atribut
[data-tema="gelap"]. - Menghubungkan klik tombol ke perubahan
dataset, teks tombol, dan tampilan. - Menyimpan pilihan tema dengan
localStoragesecara aman di dalamtry...catch.
Apa yang kita bangun
Halaman sederhana berisi judul, paragraf, dan satu tombol. Tampilan bawaannya terang. Sekali klik, seluruh halaman jadi gelap dan teks tombol berubah dari "Mode Gelap" jadi "Mode Terang". Klik lagi, balik terang. Bonusnya: saat halaman dibuka ulang, pilihan terakhir diingat.
Proyek kecil ini sengaja dipilih karena memakai semua koneksi yang sudah kamu pelajari: HTML memanggil CSS, HTML memanggil JS, JS membaca DOM, dan JS memicu aturan CSS.
Di slide, saklarnya adalah class gelap pada <body>. Di bab ini kita naik satu tingkat: saklarnya berupa atribut data-tema pada elemen <html>, dan warnanya disimpan di CSS variables. Hasilnya sama, tapi lebih rapi kalau nanti temanya bertambah.
Langkah 1: index.html, struktur dan titik koneksi
Perhatikan tiga titik koneksinya:
<link rel="stylesheet" href="css/style.css">di<head>. Path-nya relatif terhadapindex.html, jadi browser mencari foldercssdi sebelahnya.<script src="js/script.js" defer>juga di<head>. Berkatdefer, script diunduh sambil parsing dan baru dijalankan setelah tombol ada di DOM (ingat bab sebelumnya).id="saklar"adalah alamat yang dipakai JavaScript, sedangkanclass="tombol"adalah alamat yang dipakai CSS. Satu elemen boleh punya keduanya.
aria-pressed memberi tahu screen reader bahwa tombol ini bisa "ditekan" dan "dilepas". Bonus aksesibilitas yang murah.
Langkah 2: style.css, dua tema disiapkan duluan
Cara bacanya:
:rootadalah elemen<html>. Di sini kita mendefinisikan variabel untuk tema terang. Variabel CSS diwariskan ke semua anak, jadibodydan.tombolbisa memakainya.[data-tema="gelap"]berlaku untuk elemen yang punya atributdata-tema="gelap". Saat JavaScript memasang atribut itu di<html>, nilai ketiga variabel ditimpa. Specificity:rootdan selector atribut sama-sama satu (0,1,0), jadi aturan yang ditulis belakangan yang menang. Itulah kenapa blok gelap ditaruh di bawah.bodydan.tomboltidak tahu-menahu soal tema. Mereka cuma bilang "pakai--latar", dan nilai--lataryang berubah.transitionmembuat perpindahan warna halus selama 0,3 detik tanpa satu baris JavaScript pun.
Hasilnya saat tema gelap aktif: latar halaman biru tua #1b2030, teks hampir putih, dan tombol berubah dari oranye ke kuning keemasan.
Langkah 3: script.js, merekatkan klik dan tampilan
Langkah demi langkah:
- Ambil elemen.
getElementById("saklar")membaca DOM lewat penanda dari HTML.document.documentElementadalah<html>. dataset. Propertiakar.dataset.temaadalah cerminan atributdata-tema. Menulisakar.dataset.tema = "gelap"sama dengan memasangdata-tema="gelap";delete akar.dataset.temamenghapus atributnya. Namadata-nama-panjangjadidataset.namaPanjang(camelCase).- Fungsi
terapkan. Satu fungsi untuk satu pekerjaan: menyamakan atribut, teks tombol, danaria-presseddengan tema. Dipakai saat halaman dibuka dan saat tombol diklik, jadi logikanya tidak ditulis dua kali. - Baca pilihan lama.
localStorage.getItem("tema")mengembalikan string ataunullbila belum pernah disimpan. - Event klik. Tentukan tema baru, terapkan, lalu simpan.
Perhatikan: JavaScript tidak menulis satu kode warna pun. Ia cuma mengganti satu atribut, dan CSS yang memutuskan semua warnanya.
Kenapa localStorage harus dibungkus try...catch?
localStorage terlihat sepele, tapi aksesnya bisa melempar error, bukan sekadar mengembalikan null. Contohnya:
- Pengguna memblokir cookie dan data situs di pengaturan browser.
- Halaman berjalan di iframe sandbox tanpa izin storage. Latihan kode di Ruang Materi termasuk kasus ini.
- Kuota penuh, sehingga
setItemmelemparQuotaExceededError.
Tanpa try...catch, error di baris pertama script menghentikan seluruh script. Tombol tidak dipasangi event dan fitur mode gelap mati total, padahal fitur intinya tidak butuh penyimpanan sama sekali. Dengan try...catch, kegagalan menyimpan cuma berarti "pilihan tidak diingat", dan tombol tetap berfungsi.
Hasil akhirnya
Buka index.html di browser:
- Pertama kali dibuka, halaman terang dan tombol bertuliskan "Mode Gelap".
- Klik sekali:
<html>mendapatdata-tema="gelap"(cek di panel Elements), warna berpindah halus, tombol jadi "Mode Terang". - Refresh: halaman langsung gelap karena pilihan dibaca dari
localStorage. - Klik lagi: atribut hilang, semua kembali terang.
Mungkin kamu melihat kedipan terang sesaat sebelum tema gelap terpasang saat refresh. Itu karena script defer baru jalan setelah parsing selesai. Untuk proyek belajar ini tidak masalah; situs besar biasanya menaruh script kecil khusus tema langsung di <head>.
Kesalahan umum
- Nama atribut beda. CSS menulis
[data-theme="gelap"], JS menulisdataset.tema. Atribut terpasang, tapi tidak ada aturan yang cocok. - Blok
[data-tema="gelap"]ditaruh di atas:root. Karena specificity-nya sama,:rootyang belakangan menang dan tema gelap tidak pernah terlihat. - Lupa
var(). Menulisbackground: --latar;tidak valid, jadi diabaikan browser. localStoragetanpatry...catch. Satu error di awal mematikan seluruh script.- Menulis warna di JavaScript (
body.style.background = "#1b2030"). Bekerja, tapi keputusan tampilan jadi tersebar di dua berkas.
Rangkuman
index.htmlpunya tiga titik koneksi:<link>ke CSS,<script defer>ke JS, danid/classsebagai alamat elemen.style.cssmenyiapkan kedua tema lewat CSS variables;[data-tema="gelap"]menimpa nilainya.script.jscuma menggantidataset.tema, teks tombol, danaria-pressed, lalu CSS mengurus warnanya.- Akses
localStorageselalu dibungkustry...catchkarena bisa diblokir.
Slide 19 sampai 22 dari deck HTML CSS JavaScript. Penjelasan lengkapnya ada di Bacaan.

Selesaikan bab ini
- 1. Baca materi
- 2. Latihan kode (1)
- 3. Kuis (4 soal)
Latihan kode: Tombol mode gelap dengan data-tema
Lengkapi proyek mode gelap:
- Di CSS, tambahkan aturan
[data-tema="gelap"]di bawah:rootyang mengubah--latarjadi#1b2030dan--teksjadi#f3f5fa. - Di JS, saat
#saklardiklik: pasangdata-tema="gelap"padadocument.documentElementbila belum gelap, atau hapus atributnya bila sudah gelap (pakaidataset). - Teks tombol jadi
Mode Terangsaat gelap aktif danMode Gelapsaat terang. - Simpan pilihan ke
localStoragedengan kunci"tema", dibungkustry...catch. Latihan ini berjalan di iframe sandbox yang memblokir storage, jadi tanpa itu script langsung error.
Cek pemahaman
1Tombol diklik, panel Elements menunjukkan `data-tema="gelap"` sudah terpasang di `<html>`, tapi warna tidak berubah. Penyebab paling mungkin?
2Warna latar apa yang dipakai `body`?
<html data-tema="gelap"> <head> <style> :root { --latar: #ffffff; } [data-tema="gelap"] { --latar: #1b2030; } body { background: var(--latar); } </style> </head> <body>...</body> </html>3Atribut `data-tema="gelap"` pada `<html>` bisa dibaca di JavaScript lewat `document.documentElement.dataset.tema`.
4Kenapa akses `localStorage` di `script.js` dibungkus `try...catch`?