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

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

معرفی

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

مانیتور کامپیوتر با صفحه سبز
صفحه سبز ( منبع )

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

پردازش کلمه تیره به سفید
تیره روی سفید ( منبع )

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

صفحه وب تیره روی سفید در مرورگر WorldWideWeb
مرورگر WorldWideWeb ( منبع )

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

گوشی هوشمند هنگام دراز کشیدن در رختخواب استفاده می شود
گوشی هوشمند مورد استفاده در رختخواب (منبع: Unsplash)

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

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

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

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

CloseView در سیستم عامل مک سیستم 7 با
System 7 CloseView ( منبع )

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

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

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

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

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

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

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

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

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

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

پرس و جو رسانه prefers-color-scheme

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

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

  • 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"> درج شده به صورت شرطی در یک خط درونی کوچک با آن مقابله می‌کنم. اسکریپت (نور یک انتخاب دلخواه است، من همچنین می توانستم تاریکی را به عنوان تجربه بازگشتی پیش فرض قرار دهم). برای جلوگیری از فلش محتوای بدون استایل ، محتوای صفحه را تا زمانی که 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 انجام می‌شود. در زیر می توانید گزیده ای از سبک های واقعی را مشاهده کنید، اما برای انتقال ایده کلی کافی است. من دو -⁠-⁠background-color -⁠-⁠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 { … } استفاده می‌کنم. همانطور که آنها در شبه کلاس :root CSS تعریف شده اند - یک انتخابگر که در 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 را در نظر بگیرید، زیرا "زرد" ممکن است در حالت تاریک زرد نباشد یا برعکس. در زیر نمونه ای از چند متغیر دیگر که در مثال خود استفاده می کنم آورده شده است.

/* 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'}.`);
});

از Chromium 93 و Safari 15، می‌توانید رنگ را بر اساس درخواست رسانه با ویژگی media عنصر رنگ تم meta تنظیم کنید. اولین موردی که مطابقت داشته باشد انتخاب خواهد شد. به عنوان مثال، می توانید یک رنگ برای حالت روشن و دیگری برای حالت تاریک داشته باشید. در زمان نوشتن، نمی‌توانید آن‌ها را در مانیفست خود تعریف کنید. به شماره w3c/manifest#975 GitHub مراجعه کنید.

<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 Menu را باز کنید، شروع به تایپ Rendering ، دستور Show Rendering اجرا کنید و سپس گزینه Emulate CSS media feature prefers-color-scheme را تغییر دهید.

تصویری از گزینه «Emulate media CSS prefers-color-scheme» که در برگه Rendering Chrome DevTools قرار دارد.

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

Puppeteer یک کتابخانه Node.js است که یک API سطح بالا برای کنترل Chrome یا Chromium از طریق پروتکل DevTools ارائه می‌کند. با dark-mode-screenshot ، ما یک اسکریپت Puppeteer ارائه می دهیم که به شما امکان می دهد از صفحات خود در حالت تاریک و روشن اسکرین شات بسازید. می‌توانید این اسکریپت را به‌صورت یک‌بار اجرا کنید یا آن را بخشی از مجموعه آزمایشی ادغام پیوسته (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 استفاده می کنم که با تمام تصاویری که svg .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 به‌عنوان مقدار ویژگی‌های SVG fill یا stroke استفاده شود، در عوض مقدار خود را از مقدار ارثی ویژگی رنگ می‌گیرد. حتی بهتر: این برای <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> کار کنید (به جای درونی در stylesheets)، شرایطی وجود دارد که در واقع ممکن است بخواهید با prefers-color-scheme کار کنید. prefers-color-scheme به طور مستقیم در کد 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 Color Adjustment Module Level 1 است. مایلم از لوکاس زبیلوت ، روآن مروود ، چیراگ دسای و راب دادسون برای بررسی کاملشان در مورد این مقاله تشکر کنم. استراتژی بارگذاری زاییده فکر جیک آرچیبالد است. Emilio Cobos Álvarez به من اشاره کرده است که روش تشخیص prefers-color-scheme . نکته با SVGهای ارجاع شده و currentColor از تیموتی هچر ارائه شد. در نهایت، من از بسیاری از شرکت کنندگان ناشناس در مطالعات مختلف کاربران که به شکل دادن به توصیه های این مقاله کمک کرده اند سپاسگزارم. تصویر قهرمان توسط ناتان اندرسون .

،

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

معرفی

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

مانیتور کامپیوتر با صفحه سبز
صفحه سبز ( منبع )

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

پردازش کلمه تیره به سفید
تیره روی سفید ( منبع )

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

صفحه وب تیره روی سفید در مرورگر WorldWideWeb
مرورگر WorldWideWeb ( منبع )

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

گوشی هوشمند هنگام دراز کشیدن در رختخواب استفاده می شود
گوشی هوشمند مورد استفاده در رختخواب (منبع: Unsplash)

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

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

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

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

CloseView در سیستم عامل مک سیستم 7 با
System 7 CloseView ( منبع )

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

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

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

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

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

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

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

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

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

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

پرس و جو رسانه prefers-color-scheme

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

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

  • 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"> درج شده به صورت شرطی در یک خط درونی کوچک با آن مقابله می‌کنم. اسکریپت (نور یک انتخاب دلخواه است، من همچنین می توانستم تاریکی را به عنوان تجربه بازگشتی پیش فرض قرار دهم). برای جلوگیری از فلش محتوای بدون استایل ، محتوای صفحه را تا زمانی که 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 انجام می‌شود. در زیر می توانید گزیده ای از سبک های واقعی را مشاهده کنید، اما برای انتقال ایده کلی کافی است. من دو -⁠-⁠background-color -⁠-⁠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 { … } استفاده می‌کنم. همانطور که آنها در شبه کلاس :root CSS تعریف شده اند - یک انتخابگر که در 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 را در نظر بگیرید، زیرا "زرد" ممکن است در حالت تاریک زرد نباشد یا برعکس. در زیر نمونه ای از چند متغیر دیگر که در مثال خود استفاده می کنم آورده شده است.

/* 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'}.`);
});

از Chromium 93 و Safari 15، می‌توانید رنگ را بر اساس درخواست رسانه با ویژگی media عنصر رنگ تم meta تنظیم کنید. اولین موردی که مطابقت داشته باشد انتخاب خواهد شد. به عنوان مثال، می توانید یک رنگ برای حالت روشن و دیگری برای حالت تاریک داشته باشید. در زمان نوشتن، نمی‌توانید آن‌ها را در مانیفست خود تعریف کنید. به شماره w3c/manifest#975 GitHub مراجعه کنید.

<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 Menu را باز کنید، شروع به تایپ Rendering ، دستور Show Rendering اجرا کنید و سپس گزینه Emulate CSS media feature prefers-color-scheme را تغییر دهید.

تصویری از گزینه «Emulate media CSS prefers-color-scheme» که در برگه Rendering Chrome DevTools قرار دارد.

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

Puppeteer یک کتابخانه Node.js است که یک API سطح بالا برای کنترل Chrome یا Chromium از طریق پروتکل DevTools ارائه می‌کند. با dark-mode-screenshot ، ما یک اسکریپت Puppeteer ارائه می دهیم که به شما امکان می دهد از صفحات خود در حالت تاریک و روشن اسکرین شات بسازید. می‌توانید این اسکریپت را به‌صورت یک‌بار اجرا کنید یا آن را بخشی از مجموعه آزمایشی ادغام پیوسته (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 استفاده می کنم که با تمام تصاویری که svg .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 به‌عنوان مقدار ویژگی‌های SVG fill یا stroke استفاده شود، در عوض مقدار خود را از مقدار ارثی ویژگی رنگ می‌گیرد. حتی بهتر: این برای <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> کار کنید (به جای درونی در stylesheets)، شرایطی وجود دارد که در واقع ممکن است بخواهید با prefers-color-scheme کار کنید. prefers-color-scheme به طور مستقیم در کد 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 Color Adjustment Module Level 1 است. مایلم از لوکاس زبیلوت ، روآن مروود ، چیراگ دسای و راب دادسون برای بررسی کاملشان در مورد این مقاله تشکر کنم. استراتژی بارگذاری زاییده فکر جیک آرچیبالد است. Emilio Cobos Álvarez به من اشاره کرده است که روش تشخیص prefers-color-scheme . نکته با SVGهای ارجاع شده و currentColor از تیموتی هچر ارائه شد. در نهایت، من از بسیاری از شرکت کنندگان ناشناس در مطالعات مختلف کاربران که به شکل دادن به توصیه های این مقاله کمک کرده اند سپاسگزارم. تصویر قهرمان توسط ناتان اندرسون .