تم و حالت تاریکی که یادش میمونه
خلاصهٔ کاملتر
به گفتهٔ نویسنده، خیلی از سایتها دو تا مفهوم جدا رو با هم قاطی میکنن: mode (روشن یا تاریک) و theme (رنگ تأکیدی یا هویت بصری). اگه هردو رو تو یه اتریبیوت بچپونی، آخرش با یه عالمه ترکیب مثل dark-blue و light-orange سروکله میزنی. راهحل اینه که این دوتا رو تو data-mode و data-theme جدا نگه داری تا هم CSS تمیز بمونه هم منطق مستقل.
لایهٔ اول خود HTML و CSS هست. چون کاربر هر بار فقط یه mode و یه theme رو میتونه فعال کنه، این انتخابها ماهیتاً radio button هستن. استفاده از نیتیو داخل و هم سمانتیک درست میده، هم رفتار کیبورد (کلیدهای جهتدار بین گزینهها جابهجا میشن)، و مرورگر خودش track میکنه کدوم checked هست؛ پس نیازی به مدیریت state دستی نیست.
نویسنده کل کار رو بهصورت progressive enhancement تو سه لایه میچینه. لایهٔ اول همون HTML/CSS پایهست که حتی بدون جاوااسکریپت هم کار میکنه. لایهٔ دوم یه اسکریپت کوچیک و بلاککننده تو هست که قبل از رندر صفحه، localStorage رو میخونه و mode و theme ذخیرهشده رو اعمال میکنه تا فلش رنگ اشتباه پیش نیاد. لایهٔ سوم هم جاوااسکریپت deferred هست که کلیکها، sync دکمهها و تغییرات سیستمعامل رو مدیریت میکنه.
برای ذخیرهسازی هم نویسنده localStorage رو انتخاب میکنه و دلیلشو میگه. کوکیها با هر ریکوئست به سرور فرستاده میشن که برای یه ترجیح کاملاً سمتکلاینت هدردادن پهنای باندهه، و IndexedDB برای دیتای ساختارمند و بزرگه که واسه دو تا رشتهٔ کوتاه زیادیه. در مقابل localStorage سینکرون، ساده و همیشهموندگاره و هیچوقت به سرور نمیره.
یکی از ظریفترین بخشها مدیریت حالت system هست. اگه موقع لود، prefers-color-scheme رو resolve کنی و همون light یا dark رو ذخیره کنی، در واقع نیت واقعی کاربر رو دور انداختی؛ اون گفته «دنبال سیستمم برو»، نه «تاریک». راه درست به گفتهٔ نویسنده اینه که خود رشتهٔ "system" رو ذخیره کنی و فقط لحظهٔ اعمال resolveش کنی؛ یه listener روی تغییر تم سیستم هم صفحه رو زنده بهروز میکنه، البته فقط اگه کاربر هنوز تو حالت system مونده باشه.
نویسنده هشدار میده که CSS نباید همزمان هم به data-mode و هم به مدیاکوئری prefers-color-scheme تکیه کنه؛ باید یکی رو انتخاب کنی. اگه قاطیشون کنی به باگی میرسی که صفحه تاریکه ولی toggle میگه روشنه و هیچکس نمیفهمه چرا. رویکرد data-mode اونیه که به کاربر اجازه میده تنظیم سیستمش رو override کنه، که معمولاً کل هدف گذاشتن این toggle همینه.
جالب اینه که نویسنده آخرش اعتراف میکنه این toggle رو از سایت خودش برداشته. کد از ۲۰۲۲ تو ریپازیتوریش مونده بود و موقع لانچ سایت حس یه بار اضافهٔ legacy میداد؛ شاهدی نداشت که واقعاً کسی ازش استفاده میکنه و هزینهٔ نگهداریش بهصرفه نبود. درسی که ازش میگیره اینه که «چون میتونی ترجیحات رو ذخیره کنی، دلیل نمیشه که باید این کارو بکنی» و گاهی احترامگذاشتن به prefers-color-scheme بهتنهایی کافیه.
نکات کلیدی:
- mode و theme رو تو دو اتریبیوت جدا (data-mode و data-theme) نگه دار
- radio buttonهای نیتیو، سمانتیک و دسترسپذیری و انحصار متقابل رو مجانی میدن
- یه اسکریپت بلاککننده و inline تو head فلش رنگ اشتباه رو حذف میکنه
- نیت کاربر ("system") رو ذخیره کن، نه مقدار resolveشده رو
- CSS رو یا به data-mode ببند یا به prefers-color-scheme، نه هردو




