prefers-color-scheme: سلام تاریکی، دوست قدیمی من

بیش از حد اغراق شده یا ضرورت دارد؟ همه چیز را در مورد حالت تاریک و نحوه پشتیبانی از آن به نفع کاربران خود بیاموزید!

مقدمه

حالت تاریک قبل از حالت تاریک

یک کامپیوتر قدیمی مربوط به قبل از دهه ۹۰ میلادی که متن سبز را روی پس‌زمینه سیاه نشان می‌دهد.
پرده سبز ( منبع )

ما با حالت تاریک یک دور کامل را طی کرده‌ایم. در آغاز عصر محاسبات شخصی، حالت تاریک یک انتخاب نبود، بلکه یک واقعیت بود: مانیتورهای کامپیوتر CRT تک رنگ با شلیک پرتوهای الکترونی بر روی یک صفحه فسفرسنت کار می‌کردند و فسفر مورد استفاده در CRT های اولیه سبز بود. از آنجا که متن به رنگ سبز نمایش داده می‌شد و بقیه صفحه سیاه بود، این مدل‌ها اغلب به عنوان صفحه نمایش سبز شناخته می‌شدند.

مانیتوری که نسخه ویندوز ۳.۱ نرم‌افزار مایکروسافت ورد را نمایش می‌دهد.
تیره روی سفید ( منبع )

مانیتورهای رنگی CRT که متعاقباً معرفی شدند، با استفاده از فسفرهای قرمز، سبز و آبی، چندین رنگ را نمایش می‌دادند. آنها با فعال کردن همزمان هر سه فسفر، رنگ سفید را ایجاد می‌کردند. با ظهور نشر رومیزی WYSIWYG پیچیده‌تر، ایده شبیه کردن سند مجازی به یک ورق کاغذ فیزیکی رواج یافت.

مجموعه‌ای از پنجره‌ها که صفحات وب را با پس‌زمینه‌ی تیره روی زمینه‌ی سفید در مرورگر اولیه‌ی WorldWideWeb نشان می‌دهند.
مرورگر وب جهانی ( منبع )

از اینجا بود که طراحی با تم تیره روی سفید شروع شد و این تم به وب اولیه مبتنی بر سند منتقل شد. اولین مرورگر، WorldWideWeb (به یاد داشته باشید، CSS هنوز اختراع نشده بود )، صفحات وب را به این شکل نمایش می‌داد. نکته جالب: دومین مرورگر، Line Mode Browser - یک مرورگر مبتنی بر ترمینال - به رنگ سبز روی زمینه تیره بود. این روزها، صفحات وب و برنامه‌های وب معمولاً با متن تیره روی پس‌زمینه روشن طراحی می‌شوند، یک فرض پایه که در شیوه‌نامه‌های عامل کاربر، از جمله کروم، نیز به صورت سخت‌کد وجود دارد.

استفاده از تلفن همراه در رختخواب

دوران نمایشگرهای CRT مدت‌هاست که به پایان رسیده است. مصرف و تولید محتوا به دستگاه‌های تلفن همراه که از LCD با نور پس زمینه یا صفحه نمایش‌های AMOLED کم‌مصرف استفاده می‌کنند، تغییر یافته است. رایانه‌ها، تبلت‌ها و تلفن‌های هوشمند کوچک‌تر و قابل حمل‌تر، الگوهای استفاده جدیدی را ایجاد کرده‌اند. کارهای تفریحی مانند مرور وب، کدنویسی برای سرگرمی و بازی‌های سطح بالا اغلب بعد از ساعت کاری در محیط‌های کم نور انجام می‌شوند. مردم حتی از دستگاه‌های خود در رختخواب در شب لذت می‌برند. هرچه افراد بیشتر از دستگاه‌های خود در تاریکی استفاده کنند، ایده بازگشت به ریشه‌های نور در تاریکی بیشتر محبوب می‌شود.

چرا حالت تاریک

حالت تاریک به دلایل زیبایی‌شناختی

وقتی از مردم پرسیده می‌شود که چرا حالت تاریک را دوست دارند یا می‌خواهند ، رایج‌ترین پاسخ این است که «برای چشم‌ها راحت‌تر است» و به دنبال آن «زیبا و شیک است». اپل در مستندات توسعه‌دهندگان حالت تاریک خود به صراحت می‌نویسد: «انتخاب فعال کردن ظاهر روشن یا تیره برای اکثر کاربران یک انتخاب زیبایی‌شناختی است و ممکن است به شرایط روشنایی محیط ربطی نداشته باشد.»

نمای نزدیک در سیستم عامل مک ۷ با حالت «سفید روی سیاه» ( منبع )

حالت تاریک به عنوان ابزاری برای دسترسی

همچنین افرادی هستند که واقعاً به حالت تاریک نیاز دارند و از آن به عنوان یک ابزار دسترسی دیگر استفاده می‌کنند، به عنوان مثال، کاربرانی که کم‌بینا هستند. اولین نمونه از چنین ابزار دسترسی که توانستم پیدا کنم، ویژگی CloseView در System 7 بود که دارای دکمه‌ای برای نمایش سیاه روی سفید و سفید روی سیاه بود. در حالی که System 7 از رنگ پشتیبانی می‌کرد، رابط کاربری پیش‌فرض هنوز سیاه و سفید بود.

این پیاده‌سازی‌های مبتنی بر وارونگی، پس از معرفی رنگ، نقاط ضعف خود را نشان دادند. تحقیقات کاربران توسط Szpiro و همکارانش در مورد چگونگی دسترسی افراد کم‌بینا به دستگاه‌های محاسباتی نشان داد که همه کاربران مصاحبه‌شده از تصاویر وارونه خوششان نمی‌آید، اما بسیاری از آنها متن روشن را روی پس‌زمینه تیره ترجیح می‌دهند. اپل این ترجیح کاربر را با ویژگی‌ای به نام Smart Invert تطبیق می‌دهد که رنگ‌های روی صفحه نمایش را معکوس می‌کند، به جز تصاویر، رسانه‌ها و برخی از برنامه‌هایی که از سبک‌های رنگ تیره استفاده می‌کنند.

نوع خاصی از کم‌بینایی، سندرم بینایی کامپیوتر است که با نام خستگی چشم دیجیتال نیز شناخته می‌شود و به عنوان "ترکیبی از مشکلات چشمی و بینایی مرتبط با استفاده از کامپیوتر (از جمله کامپیوترهای رومیزی، لپ‌تاپ و تبلت) و سایر نمایشگرهای الکترونیکی (مانند تلفن‌های هوشمند و دستگاه‌های مطالعه الکترونیکی)" تعریف می‌شود. پیشنهاد شده است که استفاده از دستگاه‌های الکترونیکی توسط نوجوانان، به ویژه در شب، منجر به افزایش خطر کوتاه شدن مدت خواب، تأخیر طولانی‌تر در شروع خواب و افزایش کمبود خواب می‌شود. علاوه بر این، طبق تحقیقات روزنفیلد، قرار گرفتن در معرض نور آبی به طور گسترده در تنظیم ریتم شبانه‌روزی و چرخه خواب نقش دارد و محیط‌های با نور نامنظم ممکن است منجر به محرومیت از خواب شوند که احتمالاً بر خلق و خو و عملکرد وظایف تأثیر می‌گذارد. برای محدود کردن این اثرات منفی، کاهش نور آبی با تنظیم دمای رنگ صفحه نمایش از طریق ویژگی‌هایی مانند Night Shift در iOS یا Night Light در اندروید می‌تواند کمک کند، همچنین اجتناب از نورهای روشن یا نورهای نامنظم به طور کلی از طریق تم‌های تاریک یا حالت‌های تاریک می‌تواند مفید باشد.

صرفه‌جویی در مصرف انرژی حالت تاریک در صفحات AMOLED

در نهایت، حالت تاریک به دلیل صرفه‌جویی زیاد در مصرف انرژی در صفحه نمایش‌های AMOLED شناخته شده است. مطالعات موردی اندروید که بر روی برنامه‌های محبوب گوگل مانند یوتیوب متمرکز شده‌اند، نشان داده‌اند که صرفه‌جویی در مصرف انرژی می‌تواند تا ۶۰٪ باشد. ویدیوی زیر جزئیات بیشتری در مورد این مطالعات موردی و میزان صرفه‌جویی در مصرف انرژی به ازای هر برنامه ارائه می‌دهد.

فعال کردن حالت تاریک در سیستم عامل

حالا که به این موضوع پرداختیم که چرا حالت تاریک برای بسیاری از کاربران بسیار مهم است، بیایید بررسی کنیم که چگونه می‌توانید از آن پشتیبانی کنید.

تنظیمات حالت تاریک اندروید Q

سیستم عامل‌هایی که از حالت تاریک یا تم تاریک پشتیبانی می‌کنند، معمولاً گزینه‌ای برای فعال کردن آن در جایی از تنظیمات دارند. در macOS X، این گزینه در بخش عمومی تنظیمات سیستم و با نام Appearance ( اسکرین شات ) و در ویندوز 10، در بخش رنگ‌ها و با نام Choose your color ( اسکرین شات ) قرار دارد. برای اندروید Q، می‌توانید آن را در زیر گزینه Display as a Dark Theme ( اسکرین شات ) پیدا کنید و در iOS 13، می‌توانید Appearance را در بخش Display & Brightness تنظیمات ( اسکرین شات ) تغییر دهید.

کوئری رسانه prefers-color-scheme

قبل از اینکه شروع کنم، یک نکته‌ی تئوری دیگر هم بگویم. مدیا کوئری‌ها به نویسندگان اجازه می‌دهند مقادیر یا ویژگی‌های عامل کاربر یا دستگاه نمایش را مستقل از سندی که رندر می‌شود، آزمایش و جستجو کنند. آن‌ها در قانون @media در CSS برای اعمال مشروط سبک‌ها به یک سند و در زمینه‌ها و زبان‌های مختلف دیگر، مانند HTML و جاوا اسکریپت، استفاده می‌شوند. مدیا کوئری‌های سطح ۵، ویژگی‌های رسانه‌ای به اصطلاح ترجیحی کاربر را معرفی می‌کنند، یعنی راهی برای سایت‌ها تا روش ترجیحی کاربر برای نمایش محتوا را تشخیص دهند.

ویژگی prefers-color-scheme media برای تشخیص اینکه آیا کاربر درخواست استفاده از تم رنگی روشن یا تیره را برای صفحه داده است، استفاده می‌شود. این ویژگی با مقادیر زیر کار می‌کند:

  • light : نشان می‌دهد که کاربر به سیستم اطلاع داده است که صفحه‌ای با تم روشن (متن تیره روی پس‌زمینه روشن) را ترجیح می‌دهد.
  • dark : نشان می‌دهد که کاربر به سیستم اطلاع داده است که صفحه‌ای با تم تیره (متن روشن روی پس‌زمینه تیره) را ترجیح می‌دهد.

پشتیبانی از حالت تاریک

فهمیدن اینکه آیا مرورگر از حالت تاریک پشتیبانی می‌کند یا خیر

از آنجایی که حالت تاریک از طریق یک کوئری رسانه‌ای گزارش می‌شود، می‌توانید به راحتی با بررسی اینکه آیا کوئری رسانه‌ای prefers-color-scheme اصلاً مطابقت دارد یا خیر، بررسی کنید که آیا مرورگر فعلی از حالت تاریک پشتیبانی می‌کند یا خیر. توجه داشته باشید که من هیچ مقداری را وارد نمی‌کنم، بلکه صرفاً بررسی می‌کنم که آیا کوئری رسانه‌ای به تنهایی مطابقت دارد یا خیر.

if (window.matchMedia('(prefers-color-scheme)').media !== 'not all') {
  console.log('🎉 Dark mode is supported');
}

در زمان نگارش این مطلب، prefers-color-scheme هم در دسکتاپ و هم در موبایل (در صورت وجود) توسط کروم و اج از نسخه ۷۶، فایرفاکس از نسخه ۶۷ و سافاری از نسخه ۱۲.۱ در macOS و از نسخه ۱۳ در iOS پشتیبانی می‌شود. برای سایر مرورگرها، می‌توانید سند « آیا می‌توانم از جداول پشتیبانی استفاده کنم» را بررسی کنید.

اطلاع از تنظیمات برگزیده کاربر در زمان درخواست

سربرگ راهنمای کلاینت Sec-CH-Prefers-Color-Scheme به سایت‌ها اجازه می‌دهد تا تنظیمات رنگ‌بندی کاربر را به صورت اختیاری در زمان درخواست دریافت کنند و به سرورها اجازه می‌دهد CSS صحیح را درون‌خطی کنند و بنابراین از نمایش ناگهانی تم رنگی نادرست جلوگیری شود.

حالت تاریک در عمل

بیایید بالاخره ببینیم پشتیبانی از حالت تاریک در عمل چگونه است. درست مانند Highlander ، در حالت تاریک فقط می‌توان یکی را انتخاب کرد : تاریک یا روشن، اما هرگز نمی‌توان هر دو را با هم داشت! چرا این را مطرح می‌کنم؟ چون این واقعیت باید روی استراتژی بارگذاری تأثیر بگذارد. لطفاً کاربران را مجبور نکنید که CSS را در مسیر رندر بحرانی که برای حالتی است که در حال حاضر از آن استفاده نمی‌کنند، دانلود کنند. برای بهینه‌سازی سرعت بارگذاری، CSS خود را برای برنامه نمونه که توصیه‌های زیر را در عمل نشان می‌دهد، به سه بخش تقسیم کرده‌ام تا CSS غیر بحرانی را به تعویق بیندازم :

  • style.css که شامل قوانین عمومی است که به صورت جهانی در سایت استفاده می‌شوند.
  • dark.css که فقط شامل قوانین مورد نیاز برای حالت تاریک است.
  • light.css که فقط شامل قوانین مورد نیاز برای حالت روشن است.

استراتژی بارگیری

دو مورد آخر، light.css و dark.css ، به صورت مشروط با یک کوئری <link media> بارگذاری می‌شوند. در ابتدا، همه مرورگرها از prefers-color-scheme (که با استفاده از الگوی بالا قابل تشخیص است) پشتیبانی نمی‌کنند، که من با بارگذاری پویای فایل پیش‌فرض light.css از طریق یک عنصر <link rel="stylesheet"> که به صورت مشروط در یک اسکریپت درون‌خطی کوچک درج شده است، با آن برخورد می‌کنم (روشنایی یک انتخاب دلخواه است، من همچنین می‌توانستم dark را به عنوان تجربه جایگزین پیش‌فرض قرار دهم). برای جلوگیری از نمایش ناگهانی محتوای بدون استایل ، محتوای صفحه را تا زمان بارگذاری light.css پنهان می‌کنم.

<script>
  // If `prefers-color-scheme` is not supported, fall back to light mode.
  // In this case, light.css will be downloaded with `highest` priority.
  if (window.matchMedia('(prefers-color-scheme: dark)').media === 'not all') {
    document.documentElement.style.display = 'none';
    document.head.insertAdjacentHTML(
      'beforeend',
      '<link rel="stylesheet" href="/light.css" onload="document.documentElement.style.display = \'\'">',
    );
  }
</script>
<!--
  Conditionally either load the light or the dark stylesheet. The matching file
  will be downloaded with `highest`, the non-matching file with `lowest`
  priority. If the browser doesn't support `prefers-color-scheme`, the media
  query is unknown and the files are downloaded with `lowest` priority (but
  above I already force `highest` priority for my default light experience).
-->
<link rel="stylesheet" href="/dark.css" media="(prefers-color-scheme: dark)" />
<link
  rel="stylesheet"
  href="/light.css"
  media="(prefers-color-scheme: light)"
/>
<!-- The main stylesheet -->
<link rel="stylesheet" href="/style.css" />

معماری استایل‌شیت

من حداکثر استفاده را از متغیرهای CSS می‌کنم، این به style.css عمومی من اجازه می‌دهد که خب، عمومی باشد، و تمام سفارشی‌سازی حالت روشن یا تاریک در دو فایل دیگر dark.css و light.css اتفاق می‌افتد. در زیر می‌توانید گزیده‌ای از استایل‌های واقعی را ببینید، اما برای انتقال ایده کلی کافی است. من دو متغیر تعریف می‌کنم، -⁠-⁠color و -⁠-⁠background-color که اساساً یک تم پایه تاریک روی روشن و روشن روی تاریک ایجاد می‌کنند.

/* light.css: 👉 dark-on-light */
:root {
  --color: rgb(5, 5, 5);
  --background-color: rgb(250, 250, 250);
}
/* dark.css: 👉 light-on-dark */
:root {
  --color: rgb(250, 250, 250);
  --background-color: rgb(5, 5, 5);
}

در فایل style.css خودم، از این متغیرها در body { … } استفاده می‌کنم. از آنجایی که آنها روی شبه کلاس CSS : :root تعریف شده‌اند - یک انتخابگر که در HTML عنصر <html> را نشان می‌دهد و با انتخابگر html یکسان است، با این تفاوت که سطح خصوصیت آن بالاتر است - آنها به صورت آبشاری به پایین تعریف می‌شوند، که به من در تعریف متغیرهای CSS سراسری کمک می‌کند.

/* style.css */
:root {
  color-scheme: light dark;
}

body {
  color: var(--color);
  background-color: var(--background-color);
}

در نمونه کد بالا، احتمالاً متوجه یک ویژگی color-scheme با مقدار light dark که با فاصله از هم جدا شده است، شده‌اید.

این به مرورگر می‌گوید که برنامه من از کدام تم‌های رنگی پشتیبانی می‌کند و به آن اجازه می‌دهد انواع خاصی از شیوه‌نامه عامل کاربر را فعال کند، که برای مثال برای مرورگر مفید است تا فیلدهای فرم را با پس‌زمینه تیره و متن روشن رندر کند، نوارهای پیمایش را تنظیم کند یا یک رنگ برجسته متناسب با تم را فعال کند. جزئیات دقیق color-scheme در ماژول تنظیم رنگ CSS سطح 1 مشخص شده است.

پس هر چیز دیگری فقط به تعریف متغیرهای CSS برای چیزهایی که در سایت من مهم هستند، بستگی دارد. سازماندهی معنایی استایل‌ها هنگام کار با حالت تاریک بسیار مفید است. برای مثال، به جای -⁠-⁠highlight-yellow ، نام متغیر -⁠-⁠accent-color را در نظر بگیرید، زیرا ممکن است "yellow" در حالت تاریک زرد نباشد یا برعکس. در زیر مثالی از متغیرهای بیشتری که در مثال خود استفاده می‌کنم، آورده شده است.

/* dark.css */
:root {
  --color: rgb(250, 250, 250);
  --background-color: rgb(5, 5, 5);
  --link-color: rgb(0, 188, 212);
  --main-headline-color: rgb(233, 30, 99);
  --accent-background-color: rgb(0, 188, 212);
  --accent-color: rgb(5, 5, 5);
}
/* light.css */
:root {
  --color: rgb(5, 5, 5);
  --background-color: rgb(250, 250, 250);
  --link-color: rgb(0, 0, 238);
  --main-headline-color: rgb(0, 0, 192);
  --accent-background-color: rgb(0, 0, 238);
  --accent-color: rgb(250, 250, 250);
}

مثال کامل

در Glitch embed زیر، می‌توانید مثال کاملی را مشاهده کنید که مفاهیم بالا را به صورت عملی نمایش می‌دهد. حالت تاریک را در تنظیمات سیستم عامل خود فعال کنید و ببینید صفحه چگونه واکنش نشان می‌دهد.

تأثیر بارگذاری

وقتی با این مثال کار می‌کنید، می‌توانید ببینید که چرا من فایل‌های dark.css و light.css را از طریق کوئری‌های رسانه‌ای بارگذاری می‌کنم. حالت تاریک را فعال کنید و صفحه را مجدداً بارگذاری کنید: فایل‌های استایل‌شیت خاص که در حال حاضر با هم مطابقت ندارند، همچنان بارگذاری می‌شوند، اما با کمترین اولویت، به طوری که هرگز با منابعی که در حال حاضر سایت به آنها نیاز دارد، رقابت نکنند.

نمودار بارگذاری شبکه که نشان می‌دهد چگونه در حالت روشن، CSS حالت تاریک با کمترین اولویت بارگذاری می‌شود.
سایت در حالت روشن، CSS حالت تاریک را با کمترین اولویت بارگذاری می‌کند.
نمودار بارگذاری شبکه که نشان می‌دهد چگونه در حالت تاریک، CSS حالت روشن با کمترین اولویت بارگذاری می‌شود.
سایت در حالت تاریک، CSS حالت روشن را با کمترین اولویت بارگذاری می‌کند.
نمودار بارگذاری شبکه که نشان می‌دهد چگونه در حالت روشن پیش‌فرض، CSS حالت تاریک با کمترین اولویت بارگذاری می‌شود.
سایتی که در حالت پیش‌فرض روشن در مرورگری که prefers-color-scheme پشتیبانی نمی‌کند، قرار دارد، CSS حالت تاریک را با کمترین اولویت بارگذاری می‌کند.

واکنش به تغییرات حالت تاریک

مانند هر تغییر پرس‌وجوی رسانه‌ای دیگر، تغییرات حالت تاریک را می‌توان از طریق جاوا اسکریپت اعمال کرد. برای مثال، می‌توانید از این برای تغییر پویای فاویکون یک صفحه یا تغییر <meta name="theme-color"> که رنگ نوار URL را در کروم تعیین می‌کند، استفاده کنید. مثال کامل بالا این را در عمل نشان می‌دهد، برای دیدن تغییرات رنگ تم و فاویکون، نسخه آزمایشی را در یک برگه جداگانه باز کنید.

const darkModeMediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
darkModeMediaQuery.addEventListener('change', (e) => {
  const darkModeOn = e.matches;
  console.log(`Dark mode is ${darkModeOn ? '🌒 on' : '☀️ off'}.`);
});

از کرومیوم ۹۳ و سافاری ۱۵، می‌توانید رنگ را بر اساس یک کوئری رسانه‌ای با ویژگی media عنصر رنگ تم meta تنظیم کنید. اولین رنگی که مطابقت داشته باشد انتخاب می‌شود. به عنوان مثال، می‌توانید یک رنگ برای حالت روشن و رنگ دیگری برای حالت تاریک داشته باشید. در زمان نوشتن، نمی‌توانید این رنگ‌ها را در مانیفست خود تعریف کنید. به w3c/manifest#975 GitHub issue مراجعه کنید.

<meta
  name="theme-color"
  media="(prefers-color-scheme: light)"
  content="white"
/>
<meta name="theme-color" media="(prefers-color-scheme: dark)" content="black" />

اشکال‌زدایی و آزمایش حالت تاریک

شبیه‌سازی prefers-color-scheme در DevTools

تغییر کل طرح رنگ سیستم عامل می‌تواند خیلی سریع آزاردهنده شود، بنابراین Chrome DevTools اکنون به شما امکان می‌دهد طرح رنگ مورد نظر کاربر را به گونه‌ای تقلید کنید که فقط بر تب قابل مشاهده فعلی تأثیر بگذارد. منوی Command را باز کنید، Rendering را تایپ کنید، دستور Show Rendering را اجرا کنید و سپس گزینه prefers-color-scheme مربوط به Emulate CSS media feature را تغییر دهید.

تصویری از گزینه «Emulate CSS media feature prefers-color-scheme» که در تب Rendering ابزار توسعه‌دهندگان کروم قرار دارد.

اسکرین‌شات با Puppeteer prefers-color-scheme

Puppeteer یک کتابخانه Node.js است که یک API سطح بالا برای کنترل Chrome یا Chromium از طریق پروتکل DevTools ارائه می‌دهد. با dark-mode-screenshot ، ما یک اسکریپت Puppeteer ارائه می‌دهیم که به شما امکان می‌دهد از صفحات خود در هر دو حالت تاریک و روشن اسکرین‌شات بگیرید. می‌توانید این اسکریپت را به صورت یک‌باره اجرا کنید یا آن را به بخشی از مجموعه تست Continuous Integration (CI) خود تبدیل کنید.

npx dark-mode-screenshot --url https://googlechromelabs.github.io/dark-mode-toggle/demo/ --output screenshot --fullPage --pause 750

بهترین شیوه‌های حالت تاریک

از سفید خالص پرهیز کنید

نکته‌ی کوچکی که شاید متوجه شده باشید این است که من از سفید خالص استفاده نمی‌کنم. در عوض، برای جلوگیری از درخشش و پخش شدن در برابر محتوای تیره‌ی اطراف، سفید کمی تیره‌تر انتخاب می‌کنم. چیزی شبیه به rgb(250, 250, 250) خوب جواب می‌دهد.

رنگ‌آمیزی مجدد و تیره کردن تصاویر عکاسی

اگر دو تصویر زیر را با هم مقایسه کنید، متوجه خواهید شد که نه تنها تم اصلی از حالت تاریک روی روشن به حالت روشن روی تاریک تغییر کرده است، بلکه تصویر اصلی نیز کمی متفاوت به نظر می‌رسد. تحقیقات کاربری من نشان داده است که اکثر افراد مورد بررسی، تصاویر با جنب و جوش و درخشندگی کمتر را هنگام فعال بودن حالت تاریک ترجیح می‌دهند. من به این حالت ، رنگ‌آمیزی مجدد می‌گویم.

تصویر قهرمان در حالت تاریک کمی تیره شده است.
تصویر قهرمان معمولی در حالت روشن.

رنگ‌آمیزی مجدد تصاویر را می‌توان از طریق یک فیلتر CSS روی تصاویرم انجام داد. من از یک انتخابگر CSS استفاده می‌کنم که با تمام تصاویری که در URL خود .svg ندارند، مطابقت دارد. ایده این است که می‌توانم به گرافیک‌های برداری (آیکون‌ها) یک روش رنگ‌آمیزی مجدد متفاوت نسبت به تصاویرم (عکس‌ها) بدهم، که در پاراگراف بعدی بیشتر در مورد این موضوع صحبت خواهیم کرد. توجه داشته باشید که چگونه دوباره از یک متغیر CSS استفاده می‌کنم، بنابراین می‌توانم بعداً فیلتر خود را به صورت انعطاف‌پذیر تغییر دهم.

از آنجایی که رنگ‌آمیزی مجدد فقط در حالت تاریک مورد نیاز است، یعنی زمانی که dark.css فعال است، هیچ قانون متناظری در light.css وجود ندارد.

/* dark.css */
--image-filter: grayscale(50%);

img:not([src*='.svg']) {
  filter: var(--image-filter);
}

سفارشی‌سازی شدت رنگ‌آمیزی مجدد حالت تاریک با جاوا اسکریپت

همه افراد یکسان نیستند و نیازهای متفاوتی به حالت تاریک دارند. با پایبندی به روش رنگ‌آمیزی مجدد که در بالا توضیح داده شد، می‌توانم به راحتی شدت مقیاس خاکستری را به یک ترجیح کاربری تبدیل کنم که می‌توانم از طریق جاوا اسکریپت آن را تغییر دهم و با تنظیم مقدار 0% ، می‌توانم رنگ‌آمیزی مجدد را نیز به طور کامل غیرفعال کنم. توجه داشته باشید که document.documentElement ارجاعی به عنصر ریشه سند ارائه می‌دهد، یعنی همان عنصری که می‌توانم با شبه کلاس :root CSS به آن ارجاع دهم.

const filter = 'grayscale(70%)';
document.documentElement.style.setProperty('--image-filter', value);

گرافیک‌ها و آیکون‌های برداری را معکوس کنید

برای گرافیک‌های برداری - که در مورد من به عنوان آیکون‌هایی استفاده می‌شوند که از طریق عناصر <img> به آنها ارجاع می‌دهم - از روش رنگ‌آمیزی مجدد متفاوتی استفاده می‌کنم. در حالی که تحقیقات نشان داده است که مردم وارونگی را برای عکس‌ها دوست ندارند، این روش برای اکثر آیکون‌ها بسیار خوب عمل می‌کند. باز هم از متغیرهای CSS برای تعیین میزان وارونگی در حالت معمولی و در حالت :hover استفاده می‌کنم.

آیکون‌ها و متن سفید روی پس‌زمینه مشکی.
آیکون‌ها در حالت تاریک وارونه می‌شوند.
آیکون‌ها و متن مشکی روی پس‌زمینه سفید.
آیکون‌های معمولی در حالت روشن.

توجه داشته باشید که چگونه دوباره فقط آیکون‌ها را در dark.css معکوس می‌کنم اما در light.css این کار را نمی‌کنم، و چگونه :hover در هر دو مورد شدت معکوس متفاوتی می‌گیرد تا آیکون کمی تیره‌تر یا کمی روشن‌تر به نظر برسد، بسته به حالتی که کاربر انتخاب کرده است.

/* dark.css */
--icon-filter: invert(100%);
--icon-filter_hover: invert(40%);

img[src*='.svg'] {
  filter: var(--icon-filter);
}
/* light.css */
--icon-filter_hover: invert(60%);
/* style.css */
img[src*='.svg']:hover {
  filter: var(--icon-filter_hover);
}

استفاده از currentColor برای SVG های درون خطی

برای تصاویر SVG درون‌خطی ، به جای استفاده از فیلترهای وارونگی ، می‌توانید از کلمه کلیدی currentColor CSS که نشان‌دهنده مقدار ویژگی color یک عنصر است، استفاده کنید. این به شما امکان می‌دهد از مقدار color روی ویژگی‌هایی که به طور پیش‌فرض آن را دریافت نمی‌کنند، استفاده کنید. به طور مناسب، اگر currentColor به عنوان مقدار ویژگی‌های fill یا stroke SVG استفاده شود، در عوض مقدار خود را از مقدار ارثی ویژگی رنگ می‌گیرد. حتی بهتر: این روش برای <svg><use href="…"></svg> نیز کار می‌کند، بنابراین می‌توانید منابع جداگانه‌ای داشته باشید و currentColor همچنان در متن اعمال می‌شود. لطفاً توجه داشته باشید که این روش فقط برای SVGهای درون‌خطی یا <use href="…"> کار می‌کند، اما برای SVGهایی که به عنوان src یک تصویر یا به نحوی از طریق CSS ارجاع داده می‌شوند، کار نمی‌کند. می‌توانید این روش را در نسخه آزمایشی زیر مشاهده کنید.

<!-- Some inline SVG -->
<svg xmlns="http://www.w3.org/2000/svg"
    stroke="currentColor"
>
  […]
</svg>

انتقال روان بین حالت‌ها

تغییر از حالت تاریک به حالت روشن یا برعکس، به لطف این واقعیت که هم color و هم background-color از ویژگی‌های CSS قابل انیمیشن هستند، می‌تواند روان‌تر شود. ایجاد انیمیشن به آسانی تعریف دو transition برای این دو ویژگی است. مثال زیر ایده کلی را نشان می‌دهد، می‌توانید آن را به صورت زنده در نسخه آزمایشی تجربه کنید.

body {
  --duration: 0.5s;
  --timing: ease;

  color: var(--color);
  background-color: var(--background-color);

  transition: color var(--duration) var(--timing), background-color var(
        --duration
      ) var(--timing);
}

کارگردانی هنری با حالت تاریک

اگرچه به دلایل کلی عملکرد بارگذاری، توصیه می‌کنم منحصراً با prefers-color-scheme در ویژگی media عناصر <link> کار کنید (به جای inline در stylesheets)، موقعیت‌هایی وجود دارد که در واقع ممکن است بخواهید با prefers-color-scheme مستقیماً inline در کد HTML خود کار کنید. جهت هنری چنین موقعیتی است. در وب، جهت هنری با ظاهر بصری کلی یک صفحه و نحوه ارتباط بصری، تحریک احساسات، تضاد ویژگی‌ها و جذابیت‌های روانشناختی برای مخاطب هدف سروکار دارد.

در حالت تاریک، این به قضاوت طراح بستگی دارد که تصمیم بگیرد بهترین تصویر در یک حالت خاص چیست و آیا رنگ‌آمیزی مجدد تصاویر ممکن است به اندازه کافی خوب نباشد یا خیر . اگر از عنصر <picture> استفاده شود، <source> تصویری که قرار است نمایش داده شود می‌تواند به ویژگی media وابسته شود. در مثال زیر، نیمکره غربی را برای حالت تاریک و نیمکره شرقی را برای حالت روشن یا زمانی که هیچ ترجیحی داده نشده است نشان می‌دهم و در سایر موارد به طور پیش‌فرض نیمکره شرقی را در نظر می‌گیرم. البته این صرفاً برای اهداف نمایشی است. برای مشاهده تفاوت، حالت تاریک را در دستگاه خود فعال کنید.

<picture>
  <source srcset="western.webp" media="(prefers-color-scheme: dark)" />
  <source srcset="eastern.webp" media="(prefers-color-scheme: light)" />
  <img src="eastern.webp" />
</picture>

حالت تاریک، اما گزینه انصراف را اضافه کنید

همانطور که در بخش «چرا حالت تاریک» در بالا ذکر شد، حالت تاریک برای اکثر کاربران یک انتخاب زیبایی‌شناختی است. در نتیجه، برخی از کاربران ممکن است واقعاً دوست داشته باشند رابط کاربری سیستم عامل خود را در حالت تاریک داشته باشند، اما همچنان ترجیح می‌دهند صفحات وب خود را به روشی که به آن عادت دارند ببینند. یک الگوی عالی این است که در ابتدا به سیگنالی که مرورگر از طریق prefers-color-scheme ارسال می‌کند، پایبند باشید، اما سپس به صورت اختیاری به کاربران اجازه دهید تنظیمات سطح سیستم خود را نادیده بگیرند.

عنصر سفارشی <dark-mode-toggle>

البته می‌توانید خودتان کد مربوط به این کار را ایجاد کنید، اما می‌توانید از یک عنصر سفارشی آماده (کامپوننت وب) که من درست برای این منظور ایجاد کرده‌ام نیز استفاده کنید. این عنصر <dark-mode-toggle> نام دارد و یک دکمه (حالت تاریک: روشن/خاموش) یا یک تغییر دهنده تم (تم: روشن/تاریک) به صفحه شما اضافه می‌کند که می‌توانید آن را کاملاً سفارشی کنید. دموی زیر این عنصر را در عمل نشان می‌دهد (و من آن را 🤫 به طور مخفیانه در تمام مثال‌های دیگر بالا نیز قرار داده‌ام).

<dark-mode-toggle
  legend="Theme Switcher"
  appearance="switch"
  dark="Dark"
  light="Light"
  remember="Remember this"
></dark-mode-toggle>
<dark-mode-toggle> در حالت روشن.
<dark-mode-toggle> در حالت تاریک.

در دموی زیر، روی کنترل‌های حالت تاریک در گوشه بالا سمت راست کلیک کنید یا ضربه بزنید. اگر کادر انتخاب را در کنترل سوم و چهارم علامت بزنید، خواهید دید که چگونه انتخاب حالت شما حتی هنگام بارگذاری مجدد صفحه به خاطر سپرده می‌شود. این به بازدیدکنندگان شما اجازه می‌دهد سیستم عامل خود را در حالت تاریک نگه دارند، اما از سایت شما در حالت روشن لذت ببرند یا برعکس.

نتیجه‌گیری

کار کردن با حالت تاریک و پشتیبانی از آن سرگرم‌کننده است و راه‌های جدیدی برای طراحی باز می‌کند. برای برخی از بازدیدکنندگان شما، این می‌تواند تفاوت بین عدم توانایی در مدیریت سایت شما و تبدیل شدن به یک کاربر راضی باشد. برخی مشکلات وجود دارد و قطعاً آزمایش دقیق لازم است، اما حالت تاریک قطعاً فرصت بسیار خوبی برای شماست تا نشان دهید که به همه کاربران خود اهمیت می‌دهید. بهترین شیوه‌های ذکر شده در این پست و کمک‌کننده‌هایی مانند عنصر سفارشی <dark-mode-toggle> باید شما را در توانایی خود برای ایجاد یک تجربه حالت تاریک شگفت‌انگیز مطمئن کند. در توییتر به من اطلاع دهید که چه چیزی ایجاد می‌کنید و آیا این پست مفید بوده است یا خیر یا پیشنهاداتی برای بهبود آن دارید. از خواندن شما متشکرم! 🌒

منابع برای کوئری رسانه prefers-color-scheme :

منابع مربوط به متا تگ color-scheme و ویژگی CSS:

پیوندهای حالت تاریک عمومی:

مقالات پژوهشی پیشینه برای این پست:

تقدیرنامه‌ها

ویژگی رسانه prefers-color-scheme ، ویژگی CSS مربوط به color-scheme و متا تگ مربوطه، کار پیاده‌سازی 👏 Rune Lillesveen است. Rune همچنین یکی از ویراستاران ماژول تنظیم رنگ CSS سطح ۱ است. 🙏 می‌خواهم از Lukasz Zbylut ، Rowan Merewood ، Chirag Desai و Rob Dodson برای بررسی‌های کاملشان از این مقاله تشکر کنم. استراتژی بارگذاری، زاییده افکار Jake Archibald است. Emilio Cobos Álvarez روش صحیح تشخیص prefers-color-scheme را به من نشان داده است. نکته مربوط به SVG های ارجاع شده و currentColor از Timothy Hatcher آمده است. در نهایت، از بسیاری از شرکت‌کنندگان ناشناس در مطالعات مختلف کاربری که به شکل‌گیری توصیه‌های این مقاله کمک کرده‌اند، سپاسگزارم.