اول اینکه چیزی میخوایم بسازیم شبیه به تصویر زیر هست. وقتی کاربر دکمه را فشار دارد رنگ نوشته ها و پس زمینه به حالت شب تغییر کنه. البته نمیخوایم زیاد پیچیده اش کنیم.
ما سه حالت خوایم داشت:
- حالت device که تم رو بر اساس تنظیمات مرورگر یا دستگاه کاربر انتخاب میکند.
- حالت light که بدون توجه به تنظیمات دستگاه کاربر حالت روشن را اعمال میکند.
- حالت dark که بدون توجه به تنظیمات دستگاه کاربر حالت تم تیره را فعال میکند.
ایجاد فایل html صفحه وب
اول از همه فایل index.html را ایجاد میکنیم و تگهای مورد نیاز خودم را به آن اضافه میکنم :
<!DOCTYPE html>
<html lang="en" data-theme="device">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document Title</title>
</head>
<body>
<div id="flex-div">
<h1>Theme Color</h1>
<div>
<button id="device-btn" onclick="setTheme('device')">Device</button>
<button id="light-btn" onclick="setTheme('light')">Light</button>
<button id="dark-btn" onclick="setTheme('dark')">Dark</button>
</div>
</div>
</body>
</html>
تم انتخابی کاربر را بوسیله اتریبیوت data-theme ذخیره میکنیم:
<html lang="en" data-theme="device">
استایلهای صفحه وب
برای اینکه صفحه ما قابل تحمل شود فایل style.css خود را به آن اضافه میکنیم. ما ابتدا نیاز داریم که با متغییرها یا variable در css آشنا باشیم. خیلی راحت میتوان به شیوه زیر متغیر تعریف کرد.
:root{
--varname:#0A0A0A;
}
مثلا برای رنگ 0A0A0A یک متغیر بنام varname تعریف کردیم و اکنون میتوانیم در فایلهای css خود از آن استفاده کنیم. مثلا اگر جایی میخواهیم رنگ نوشته را 0A0A0A بگذاریم بجای کد رنگ از متغیر آن استفاده میکنیم.
p {
color: var(--varname);
}
یک متغیر تعریف و از آن استفاده کردیم. ما میتوانیم برای هر تگ دلخواه یک متغیر تعریف کنیم و این متغیر در تمام فرزندان آن تگ قابل استفاده است. مثلا اگر برای تگ body یک متغیر مثل کد زیر تعریف کنیم برای تمام فرزندان تگ body قابل استفاده است.
body {
--color: #0000CC;
}
h1 {
color: var(--color);
}
اکنون تگ h1 رنگ موجود در متغیر color را دریافت میکند.
میریم به سراغ فایل style.css و کار خودمان! ما سه حالت داریم یا device یا light و dark! برای هرکدام از حالات متغیرهای css خود را تعریف میکنیم:
/* حالت پیشفرض و تم روشن */
:root {
--backgroundColor: #F1F1F1;
--textColor: #3A3A3A;
}
/* تم تیره */
[data-theme="dark"] {
--backgroundColor: #2C2C2C;
--textColor: #E622B5;
}
/* وقتی تم دستگاه تیره بود و تم انتخابی کاربر هم بر اساس دستگاه بود */
@media (prefers-color-scheme: dark) {
[data-theme="device"] {
--backgroundColor: #2C2C2C;
--textColor: #E622B5;
}
}
دقت کنید که مقدار تم انتخابی از این قسمت میآید:
<html lang="en" data-theme="device">
پس از تعریف مقادیر برای حالات مختلف، کافی است از آنها برای المنتهای html خود استفاده کنیم!
/* المنت بادی یا هر المنت دیگری ... */
body {
background-color: var(--backgroundColor);
color: var(--textColor);
transition: .3s all;
}
استفاده از ویژگی transition هم میتوانیم به تغییر رنگها در هنگام فعال یا غیر فعالسازی حال dark mode حالت انیمیشنگونه ببخشیم.
اضافه کردن جاوااسکریپت
دکمههای خود را به این شکل تعریف کردهایم:
<button id="device-btn" onclick="setTheme('device')">Device</button>
<button id="light-btn" onclick="setTheme('light')">Light</button>
<button id="dark-btn" onclick="setTheme('dark')">Dark</button>
با کلیک بر روی هر دکمه تابع setTheme صدا زده میشود و تم مورد نظر اعمال میشود. اکنون به سراغ تعریف این تابع میرویم:
function setTheme(theme){
document.documentElement.dataset.theme = theme;
}
این تابع مقدار اتریبیوت data-theme المنت را تغییر میدهد!
ذخیره تم در مرورگر
پس از هربار رفرش مقدار تم انتخابی ریست خواهد شد. برای حل این مشکل فقط کافیست تم انتخابی رو در localStorage مرورگر ذخیره کنیم و با هر بار لود صفحه آنرا بخوانیم و اعمال کنیم:
// خواندن تم از استوریج هنگام پس از لود صفحه
const theme = localStorage.getItem('theme');
if(theme){
setTheme(theme);
}
function setTheme(theme){
document.documentElement.dataset.theme = theme;
// ذخیره تم انتخابی
localStorage.setItem('theme',theme);
}
اکنون نتیجه به این صورت میشود:
ذخیره تم در کوکی
در کوکی نیز میتوانیم تم خود را ذخیره کنیم:
function getCookie(name) {
const value = `; ${document.cookie}`;
const parts = value.split(`; ${name}=`);
if (parts.length === 2) return parts.pop().split(';').shift();
return null;
}
function setCookie(name, value) {
let expires = "";
const date = new Date();
date.setTime(date.getTime() + (365 * 24 * 60 * 60 * 1000)); // ذخیره برای یکسال
expires = "; expires=" + date.toUTCString();
document.cookie = name + "=" + value + expires + "; path=/";
}
function setTheme(theme) {
document.documentElement.dataset.theme = theme;
setCookie('theme', theme);
}
مزیت ذخیره در کوکی این است که در بکند نیز به مقدار آن دسترسی خواهیم داشت:
<html data-theme="<?php echo isset($_COOKIE['theme']) ? $_COOKIE['theme'] : 'device' ?>">