زمینه‌های روشن/تیره مختص مؤلفه

ویژگی‌های وب: color-scheme light-dark()

اگرچه ویژگی color-scheme معمولاً روی ریشه تنظیم می‌شود، اما می‌توان آن را روی عناصر تکی تنظیم کرد تا آن‌ها را مجبور به استفاده از آرایش رنگی متفاوت از بقیه صفحه کند. این کار می‌تواند برای مؤلفه‌هایی مفید باشد که همیشه باید در آرایش رنگ‌های خاصی مشاهده شوند (مثلاً همیشه در حالت تیره یا روشن).

نمونه‌های موارد استفاده عبارت‌اند از:

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

چه زمانی رنگ‌ها را تغییر دهیم و چه زمانی color-scheme را اجباری کنیم؟

همه عناصری که از نوشتار روشن‌تر روی پس‌زمینه تیره‌تر در حالت روشن یا نوشتار تیره‌تر روی پس‌زمینه روشن‌تر در حالت تیره استفاده می‌کنند به color-scheme متفاوتی نیاز ندارند. برای مثال، دکمه اصلی ممکن است در حالت روشن به‌رنگ آبی با نوشتار سفید ارائه شود، اما این امر color-scheme: dark را تضمین نمی‌کند.

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

هنگام درنظر گرفتن استفاده از color-scheme متفاوت در یک عنصر، از خود بپرسید:

  • آیا میانای کاربر مرورگر داخلی که به‌طور دیگری سفارشی‌سازی نشده است (مثلاً کنترل‌های فرم، نوارهای پیمایش، و غیره) باید از آن آرایش رنگ‌ها استفاده کند یا با آرایش رنگ‌های صفحه سازگار شود؟ -> if the former, don't use color-scheme.
  • آیا رنگ‌های light-dark() باید مانند بقیه صفحه حل شوند یا براساس لغو؟ -> if the former, don't use color-scheme.
  • آیا فرزندان باید در آن color-scheme باشند؟ اگر نه، از color-scheme استفاده نکنید.

پیاده‌سازی پایه

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

وقتی color-scheme در سراسر صفحه اعمال شد و از نشان‌های رنگی حساس به آن استفاده می‌کنید (مثلاً ازطریق light-dark())، می‌توانید به‌راحتی color-scheme را روی مؤلفه‌های خاصی تنظیم کنید تا حالت رنگ را برای آن زیردرخت لغو کنید:

pre, code, .dark {
  color-scheme: dark;
}

توجه داشته باشید که برخی‌از مرورگرها به‌هرحال به‌طور خودکار مؤلفه‌ها را با طرح رنگ متفاوتی تطبیق می‌دهند. برای اجباری کردن آرایش رنگ‌های مشخص‌شده در همه موارد، از only، یعنی color-scheme: only dark; به‌جای color-scheme: dark; استفاده کنید.

درحال تطبیق دادن مقادیر غیررنگی

light-dark() درحال‌حاضر فقط برای رنگ‌ها کار می‌کند.

روال‌های مطلوب

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

مشکلات شناخته‌شده‌ای که باید از آن‌ها مطلع باشید

نکته مهم: توارث رنگ‌های light-dark()

light-dark() در زمان مقدار محاسبه‌شده حل می‌شود. این یعنی هر ویژگی <color> موروثی که روی رنگ light-dark() تنظیم شده باشد، فقط یکی از دو رنگ را به فرزندان خود منتقل می‌کند، نه خود عبارت light-dark() را.

ازجمله:

  • ویژگی‌های رنگ داخلی که به ارث می‌رسند، مانند color، accent-color، fill، stroke، text-shadow، caret-color
  • هرگونه ویژگی سفارشی قابل‌وراثت ثبت‌شده با syntax: <color> و inherits: true
  • هر خصوصیت <color> دیگری که روی inherit تنظیم شده باشد

این یعنی باید:

  • ویژگی‌های سفارشی را که برای نگهداری کدهای طراحی (مثلاً --surface-color) درنظر گرفته شده‌اند به‌عنوان <color> ثبت نکنید. نشان‌ها باید عبارت light-dark() خود را فعال نگه دارند تا فرزندان بتوانند آن‌ها را تحت color-scheme دیگری دوباره حل کنند.
  • هنگام تنظیم color-scheme روی یک عنصر، هرگونه ویژگی <color> موروثی را که ممکن است روی مقادیر light-dark() تنظیم شده باشد (به‌طور مستقیم یا ازطریق نشانه‌های طراحی) دوباره مشخص کنید، حتی اگر به همان نشانه طراحی باشد.
  • از inherit در ویژگی‌های <color> در عناصر با لغو color-scheme استفاده نکنید (استفاده از آن در عناصر فرزند مشکلی ندارد).
  • باید از ویژگی‌های ثبت‌شده <color> برای مورد استفاده مخالف استفاده کنید: وقتی‌که عمداً می‌خواهید از رنگ حل‌شده عنصر والد عکس آنی بگیرید و از حل مجدد آن تحت color-scheme عنصر فرزند جلوگیری کنید. برای مثال، ضبط پس‌زمینه صفحه برای استفاده در جاهای دیگر.
  • اگر لازم است رنگی را پویانمایی کنید، از یک ویژگی <color> ثبت‌شده با @property جداگانه در عنصری که پویانمایی می‌شود استفاده کنید (ثبت برای درون‌یابی رنگ لازم است) — این یک نشانه طراحی نیست، بلکه یک هدف پویانمایی برای هر عنصر است، بنابراین با قانون بالا تداخل ندارد.

مثال:

:root {
    --accent-color: light-dark(blue, skyblue);
    --surface-color: light-dark(white, #222);
    --text-color: light-dark(#111, white);

    color-scheme: light dark;
    accent-color: var(--accent-color);
    color: var(--text-color);
}

body {
    /* --surface-color dynamically switches despite being inherited because --surface-color is not registered */
    background: var(--surface-color);
}

pre, code {
    color-scheme: dark;
    background: var(--surface-color);

    /* Without this, accent-color would be blue, not skyblue! */
    accent-color: var(--accent-color);

    /* Without this, text-color would be #111, not white! */
    color: var(--text-color);
}

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

  • Chrome و Firefox از color-scheme برای iframeها پیروی می‌کنند: آن‌ها صفحه‌های جاسازی‌شده را با آرایش رنگ‌های صحیح ارائه می‌دهند و پرسمان رسانه prefers-color-scheme صفحه جاسازی‌شده را طوری تنظیم می‌کنند که color-scheme بافت جاسازی را منعکس کند. Safari این کار را نمی‌کند و prefers-color-scheme را به تنظیمات سیستم حتی در iframeها ارجاع می‌دهد.
    • اگر هم والد و هم iframe را کنترل می‌کنید: طرح‌واره رنگ والد را به‌طور صریح به iframe منتقل کنید — ازطریق پارامتر URL (?theme=dark) در زمان ساخت iframe، یا ازطریق postMessage() (که به شما امکان می‌دهد به تغییرات زمان اجرا نیز واکنش نشان دهید). در iframe، به‌جای تکیه بر prefers-color-scheme، کلاسی را در <html> (و/یا color-scheme در :root) از آن سیگنال تنظیم کنید.
    • اگر فقط صفحه جاسازی‌شده را کنترل می‌کنید: هیچ راه قابل‌اعتمادی برای شناسایی color-scheme بافت جاسازی از داخل iframe در Safari وجود ندارد. پارامتر زمینه صریحی را در میانای برنامه‌سازی کاربردی جاسازی‌شده‌تان (مثلاً رشته پُرسمان یا پروتکل postMessage) نشان دهید و آن را برای جاسازکنندگان مستند کنید.

راهبردهای جایگزین

پشتیبانی مرورگر و جایگزین‌ها برای طرح رنگ

خصوصیت color-scheme ارتقای پیش‌رو است. مرورگرهایی که از آن پشتیبانی نمی‌کنند این ویژگی را نادیده می‌گیرند و از واسط کاربر حالت روشن پیش‌فرض خود استفاده می‌کنند.

برای سازگار شدن با اولویت‌های کاربر در مرورگرهای قدیمی‌تر، از پُرسمان‌های رسانه‌ای prefers-color-scheme استفاده کنید تا وقتی حالت تیره ترجیح داده می‌شود رنگ‌های متفاوتی ارائه شود.

  • از پرسمان رسانه برای روشن کردن ویژگی‌های سفارشی در :root یا html استفاده کنید
  • از به‌کار بردن پرسمان رسانه در مؤلفه‌های تکی خودداری کنید، مگراینکه مؤلفه به نوع بسیار خاصی از سفارشی‌سازی حالت تاریک فراتر از رنگ‌ها نیاز داشته باشد.
:root {
  /* Define brand colors for each mode */
  --color-brand-light: #0056b3;
  --color-brand-dark: #00e5ff;
  --color-brand: var(--color-brand-light);

  /* MANDATORY: Fallback for browsers without light-dark support */
  @media (prefers-color-scheme: dark) {
    --color-brand: var(--color-brand-dark);
  }

  /* Ignored in older browsers */
  color-scheme: light dark;
}

button.primary {
    background-color: var(--color-brand);
}

پشتیبانی مرورگر و بازگشت‌ها برای light-dark()‎

برای مرورگرهایی که از color-scheme پشتیبانی می‌کنند اما هنوز از light-dark() پشتیبانی نمی‌کنند، نسخه‌های روشن و تیره رنگ‌ها باید ابتدا به‌عنوان ویژگی‌های سفارشی تعریف شوند و از پُرسمان رسانه‌ای prefers-color-scheme باید برای تنظیم رنگ‌ها برای حالت مربوطه استفاده شود، مانند مثال زیر:

:root {
  /* Define browser UI accent color for each mode */
  --brand-accent-light: #0056b3;
  --brand-accent-dark: #00e5ff;
  --accent-color: var(--brand-accent-light);

  /* MANDATORY: Fallback for browsers without light-dark support */
  @media (prefers-color-scheme: dark) {
    --accent-color: var(--brand-accent-dark);
  }

  /* OPTIONAL: use light-dark() for more control of built-in UI colors */
  @supports (color: light-dark(white, black)) {
    --accent-color: light-dark(var(--brand-accent-light), var(--brand-accent-dark));
  }

  /* MANDATORY: Automatically adapt native UI to user system preferences */
  color-scheme: light dark;

  /* Example inherited color property */
  accent-color: var(--accent-color);
}

pre, code {
  color-scheme: dark;

  /* **Mandatory**: any inherited color properties must be set again, even if to the same design tokens */
  accent-color: var(--accent-color);
}