Dalam penyegaran baru-baru ini pada desain situs web saya, saya menerapkan opsi tema yang berbeda. Sekarang mungkin untuk memilih di antara enam skema warna yang berbeda saat membaca blog saya.
Kebutuhan akan lebih dari sekadar tema terang dan tema gelap berasal dari fakta bahwa secara pribadi, ketika saya mengalami migrain parah dan sakit kepala, warna kontras rendah terasa lebih nyaman di mata saya, jadi saya ingin setidaknya menambahkan opsi kontras rendah gelap di selain tema terang dan gelap biasa.
Setelah dukungan untuk dua tema pertama ditambahkan, menyediakan lebih banyak opsi menjadi sangat mudah, jadi mudah bagi saya untuk bersenang-senang membuat tema yang berbeda!
Saya telah menerima banyak umpan balik positif tentang pengalih tema, dan mengimplementasikan mode terang/gelap dan tema kontras tinggi telah menjadi tugas aksesibilitas berulang di beberapa proyek yang saya ikuti, jadi saya pikir sudah waktunya untuk sebuah artikel tentang cara mengimplementasikan pengalih tema seperti ini.
Dalam tutorial ini, kita akan menggunakan:
- HTML
- CSS
- JavaScript (vanila)
Apa yang akan kita bangun
Di akhir tutorial ini, kita akan memiliki contoh dengan empat tema berbeda yang dapat langsung diaktifkan melalui sekelompok tombol sakelar di antarmuka, dan pilihan kita akan diingat melalui localStorage
.
Anda dapat menemukan kode terakhir di repo GitHub theme-switcher saya, dan semua demo yang digunakan dalam tutorial ini dibundel dalam koleksi Theme Switcher di CodePen saya juga.
Gaya variabel dengan CSS.
Mari kita mulai dengan menyiapkan CSS kita untuk mendukung tema.
Kita harus menggunakan variabel CSS (atau properti khusus) untuk membuat perubahan warna di seluruh komponen menjadi lebih mudah.
Katakanlah kita mulai dengan file CSS yang terlihat seperti ini:
body
background: linear-gradient(#A4F3A2, #00CC66);
color: #034435;
.callout
background: #034435;
color: #A4F3A2;
.footer
background: #A4F3A2;
border-top: 2px solid #034435;
Kita dapat menambahkan atribut data khusus pada html
:
<html data-selected-theme="pink">
...
</html>
Dan gunakan itu untuk menimpa warna untuk setiap tema. Jika kita melanjutkan dengan CSS dari atas, tanpa menambahkan variabel, kita harus melakukan sesuatu seperti ini:
/* variables.css */
body
background: linear-gradient(#A4F3A2, #00CC66);
color: #034435;
.callout
background: #034435;
color: #A4F3A2;
.footer
background: #A4F3A2;
border-top: 2px solid #034435;
/* pink.css */
[data-selected-theme="pink"] body
background: linear-gradient(#DFB2F4, #F06EFC);
color: #463546;
[data-selected-theme="pink"] .callout
background: #463546;
color: #DFB2F4;
[data-selected-theme="pink"] .footer
background: #DFB2F4;
border-top: 2px solid #463546;
Untuk contoh tutorial kecil, ini mungkin masih tampak seperti pendekatan yang layak, tetapi akan menjadi sangat sulit untuk dilacak dari waktu ke waktu. Semakin besar situs web atau pustaka komponen, semakin banyak properti yang harus kita ingat untuk ditimpa secara manual untuk setiap tema baru. Jadi masuklah ✨ variabel CSS ✨, yang dapat kita atur :root
seperti ini:
:root
--color-background: #A4F3A2;
--color-text: #034435;
--color-accent: #00CC66;
Kami kemudian dapat menggunakan variabel-variabel itu di tempat lain di CSS.
body
background: linear-gradient(
var(--color-background),
var(--color-accent)
);
color: var(--color-text);
.callout
background: var(--color-text);
color: var(--color-background);
.footer
background: var(--color-background);
border-top: 2px solid var(--color-text);
Ini berarti bahwa alih-alih harus memperbarui gaya setiap elemen satu per satu, kita sekarang dapat membatasi diri untuk hanya menimpa variabel yang didefinisikan dalam :root
:
:root
--color-background: #A4F3A2;
--color-text: #034435;
--color-accent: #00CC66;
[data-selected-theme="pink"]
--color-background: #DFB2F4;
--color-text: #463546;
--color-accent: #F06EFC;
Ini sudah terlihat jauh lebih rapi! 🥳
Kami sekarang dapat dengan relatif cepat meningkatkan jumlah tema yang kami dukung, tanpa harus mengubah apa pun di dalam masing-masing komponen.
:root,
[data-selected-theme="green"]
--color-background: #A4F3A2;
--color-text: #034435;
--color-accent: #00CC66;
[data-selected-theme="blue"]
--color-background: #55dde0;
--color-text: #2B4150;
--color-accent: #00D4E7;
[data-selected-theme="pink"]
--color-background: #DFB2F4;
--color-text: #463546;
--color-accent: #F06EFC;
[data-selected-theme="orange"]
--color-background: #FA7D61;
--color-text: #1E1E24;
--color-accent: #F3601C;
Di sini, kami telah menulis dukungan CSS untuk berbagai tema kami, dan kami dapat beralih di antaranya dengan memperbarui secara manual data-selected-theme
properti di body
halaman ke nama kelas tema kami yang berbeda.
Sekarang kita perlu membuat komponen yang memungkinkan kita mengganti tema langsung dari UI.
Membuat komponen pemilih tema dalam HTML.
Ada beberapa cara yang bisa Anda lakukan untuk menerapkan tema seperti ini. Misalnya, GitHub memiliki tempat di pengaturan yang memungkinkan untuk memilih tema warna dengan menggunakan tombol radio.
Saya memutuskan untuk pergi untuk sekelompok <button>
elemen. Begitulah cara saya mendesainnya secara visual, jadi masuk akal untuk mencocokkan pola itu dalam semantik.
Léonie Watson memiliki artikel bagus yang menjelaskan mengapa visual dan semantik suatu elemen harus cocok, tetapi singkatnya: elemen yang berbeda (tombol, tombol radio, link, dll) memiliki kontrol keyboard dan pembaca layar sendiri, dan kami ingin memastikan bahwa interaksi aktual yang tersedia sesuai dengan harapan pengguna.
Mengkomunikasikan tema yang dipilih.
Sekarang kami memiliki tombol kami, tetapi kami belum memiliki apa pun untuk menunjukkan tema mana yang dipilih. Kami menggunakan warna hijau secara default, jadi kami sudah dapat memilih sebelumnya tombol itu dengan menambahkan aria-pressed="true"
.
<div class="theme-switcher">
<button aria-pressed="true">Green</button>
<button aria-pressed="false">Blue</button>
<button aria-pressed="false">Pink</button>
<button aria-pressed="false">Orange</button>
</div>
Itu aria-pressed
memberi tahu teknologi bantuan apakah tombol dicentang atau tidak. Misalnya, VoiceOver akan membaca tombol yang dipilih di atas sebagai:
Hijau, dipilih, tombol sakelar
Kita bisa menggunakan yang sama aria-pressed
properti di CSS untuk mengatur gaya tombol yang dipilih secara berbeda:
button[aria-pressed="true"]
background: var(--color-text);
color: var(--color-background);
Memperbarui tema yang dipilih dengan JavaScript.
Jadi sekarang tibalah bagian yang menyenangkan: membuat tombol menjadi interaktif menggunakan JavaScript. Saat kita mengaktifkan tombol (menggunakan klik, spasi, atau enter)kami ingin:
- Nama kelas pada isi untuk diperbarui dengan tema yang sesuai.
- Tombolnya
aria-pressed
properti yang akan diaturtrue
. - Semua tombol tema lainnya untuk dimatikan (
aria-pressed=”false”
). - Pilihan untuk disimpan untuk kali berikutnya kita mengunjungi halaman tersebut.
Bereaksi terhadap klik tombol.
Pertama-tama kita harus mendeteksi tombol mana yang telah diklik. Kita dapat melakukannya dengan memilih semua tombol tema pada halaman, lalu mengulanginya dan menambahkan a click
pendengar acara untuk masing-masing.
/* Logs the clicked button */
const handleThemeSelection = (event) =>
console.log('button clicked', event.target);
/* Selects all buttons */
const themeSwitcher = document.querySelector('.theme-switcher');
const buttons = themeSwitcher.querySelectorAll('button');
/* Adds the handleThemeSelection as a click handler to each of the buttons */
buttons.forEach((button) =>
button.addEventListener('click', handleThemeSelection);
);
Karena kami menggunakan <button>
elemen, itu click
acara juga akan dipanggil saat menggunakan space
dan enter
kunci untuk mengaktifkannya.
Menambahkan info tema ke tombol.
Jika kita berinteraksi dengan tombol di halaman kita, kita akan menyadari bahwa kita memang dapat mendeteksi elemen yang dipilih dengan cara ini.
Tapi itu tidak memberi kita banyak yang bisa kita gunakan dalam kode untuk memperbarui tema. Jadi sebelum kita melanjutkan, sekarang adalah saat yang tepat untuk menambahkan beberapa properti khusus ke HTML kita.
<div class="theme-switcher">
<button data-theme="green" aria-pressed="true">Green</button>
<button data-theme="blue" aria-pressed="false">Blue</button>
<button data-theme="pink" aria-pressed="false">Pink</button>
<button data-theme="orange" aria-pressed="false">Orange</button>
</div>
Memperbarui tema.
Sekarang kita benar-benar dapat menargetkan data-theme
nilai dalam penangan klik kami:
const handleThemeSelection = (event) =>
const theme = event.target.getAttribute('data-theme');
console.log(theme);
Dan menggunakannya untuk memperbarui data-selected-theme
properti secara terprogram. Kode berikut akan cukup untuk memperbarui skema warna:
const handleThemeSelection = (event) =>
const theme = event.target.getAttribute('data-theme');
document.documentElement.setAttribute("data-selected-theme", theme);
const themeSwitcher = document.querySelector('.theme-switcher');
const buttons = themeSwitcher.querySelectorAll('button');
buttons.forEach((button) =>
button.addEventListener('click', handleThemeSelection);
);
Jika kita mengklik opsi yang berbeda sekarang, gaya halaman memang diperbarui, tetapi status tombolnya tetap tidak berubah. Bahkan jika kita memilih tema merah muda, opsi hijau default tetap ditampilkan sebagai aktif.
Memperbarui properti tombol.
Kita perlu mencerminkan perubahan ini di grup tombol kita juga. Saat mengklik tombol, kita dapat mengaturnya aria-pressed
atribut untuk true
:
target.setAttribute('aria-pressed', 'true');
Ini akan memilih tombol yang baru diklik, tetapi tetap tidak memperbarui aria-pressed
nilai tema warna mana pun yang dipilih sebelumnya, artinya beberapa tombol dapat dipilih secara bersamaan.
Untuk memperbaikinya, kami ingin mengatur ulang semua aria-pressed
tombol untuk false
. Sebelum memperbarui nilai tombol yang diklik, pertama-tama kita dapat memilih tombol yang masih aktif:
const prevBtn = document.querySelector('[data-theme][aria-pressed="true"]');
Dan kemudian atur aria-pressed
ke false
:
const prevBtn = document.querySelector('[data-theme][aria-pressed="true"]');
prevBtn.setAttribute('aria-pressed', false);
Karena kami menargetkan [aria-pressed="true"]
untuk memberi gaya pada keadaan yang dipilih, kita tidak perlu melakukan apa pun untuk memperbarui gaya.
Menyimpan pilihan.
Pemilih tema kami berfungsi! 🥳
Langkah terakhir adalah mengingat pilihan kita, jadi kita tidak perlu memilih ulang tema setiap kali mengunjungi halaman.
Memperbarui penyimpanan lokal.
Kami dapat menyimpan tema yang dipilih pengguna di penyimpanan lokal menggunakan localStorage.setItem()
berfungsi saat mengklik tombol.
const handleThemeSelection = (event) =>
const theme = event.target.getAttribute('data-theme');
document.documentElement.setAttribute("data-selected-theme", theme);
const prevBtn = document.querySelector('[data-theme][aria-pressed="true"]');
prevBtn.setAttribute('aria-pressed', false);
event.target.setAttribute('aria-pressed', 'true');
localStorage.setItem('selected-theme', theme);
Saat memuat halaman, kami kemudian dapat memeriksa tema mana yang telah disimpan di penyimpanan lokal dengan memanggil:
const savedTheme = localStorage.getItem('selected-theme');
Jika tema telah disimpan, kita perlu:
- Batalkan pilihan tombol yang dipilih default
- Pilih tombol yang cocok dengan tema yang disimpan
- Mengubah
data-selected-theme
ke tema yang disimpan
Untuk menghindari melakukan tindakan yang tidak perlu, kami hanya akan mengeksekusi kode ini bila tema yang disimpan berbeda dari tema default:
const savedTheme = localStorage.getItem('selected-theme');
const defaultTheme = "green";
if (savedTheme && savedTheme !== defaultTheme)
const prevBtn = document.querySelector('[data-theme][aria-pressed="true"]');
prevBtn.setAttribute('aria-pressed', false);
document.querySelector(`[data-theme="$savedTheme"]`)
.setAttribute('aria-pressed', true);
document.documentElement
.setAttribute("data-selected-theme", savedTheme);
Pembersihan kode
Masih ada beberapa kode yang berulang. Cara aria-pressed
dan data-selected-theme
diperbarui setelah memuat halaman dan setelah mengklik tombol kurang lebih sama. Jadi kita bisa memindahkan bagian ini ke fungsinya sendiri.
const applyTheme = (theme) =>
const target = document.querySelector(`[data-theme="$theme"]`);
document.documentElement
.setAttribute("data-selected-theme", theme);
document.querySelector('[data-theme][aria-pressed="true"]')
.setAttribute('aria-pressed', 'false');
target.setAttribute('aria-pressed', 'true');
;
Fungsi yang sama kemudian dapat dipanggil saat mengklik opsi (dari dalam handleThemeSelection
), dan saat memuat halaman.
const handleThemeSelection = (event) =>
const target = event.target;
const isPressed = target.getAttribute('aria-pressed');
/* if clicked theme is different from current theme */
if(isPressed !== "true")
const theme = target.getAttribute('data-theme');
applyTheme(theme);
localStorage.setItem('selected-theme', theme);
const savedTheme = localStorage.getItem('selected-theme');
/* if saved theme is different from current theme */
if(savedTheme && savedTheme !== defaultTheme)
applyTheme(savedTheme);
Hasil akhir
Dan selesai! Kami memiliki pengalih tema dasar, yang berfungsi dengan navigasi keyboard dan pembaca layar!
Sumber daya
Kode untuk tutorial ini tersedia melalui repo GitHub theme-switcher saya, dan semua demo yang digunakan dalam tutorial ini dibundel dalam koleksi Theme Switcher di CodePen saya juga.
Saya ingin melihat hasilnya jika Anda akhirnya menggunakan tutorial saya untuk menambahkan pemilih tema ke situs web Anda 🎨✨
Pengeluaran hk tercepat hari ini berasal dari web togel Data SGP pools https://babacoolbrooklyn.com hasil keluaran hk terkini tiap hari. Dengan Mengenakan rekapan bagan data hk prize, Pasti mempermudah bettor dalam menyaksikan no pengeluaran SGP hari ini. Di mana tiap hasil pengeluaran hk https://chronwatch-america.com/ ini terkini senantiasa kita pembaharuan menjajaki result keluaran hongkong terkini berasal dari hongkongpools.com. Tujuannya sehingga para pecinta judi togel https://covertcreeklodge.com/ di Indonesia dapat dengan mudahnya mengetahui hasil hk hari ini terkini serta sangat kilat.