على الرغم من أنّ السمة 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 usecolor-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);
}
المشاكل التي يجب الانتباه إليها عند استخدام color-scheme
- يستجيب متصفّحا Chrome وFirefox لسمة
color-schemeفي إطارات iframe، إذ يعرضان الصفحات المضمّنة بنظام الألوان الصحيح ويعدّلان الاستعلام عن الوسائطprefers-color-schemeفي الصفحة المضمّنة ليعكس سمةcolor-schemeفي سياق التضمين. لا يتيح Safari ذلك، ويحلّprefers-color-schemeفي إعدادات النظام حتى داخل إطارات iframe.- إذا كنت تتحكّم في كل من الصفحة الرئيسية وiframe: يمكنك تمرير نظام الألوان الخاص بالصفحة الرئيسية إلى iframe بشكل صريح، إما من خلال مَعلمة عنوان URL (
?theme=dark) في وقت إنشاء iframe، أو من خلالpostMessage()(الذي يتيح لك أيضًا التفاعل مع التغييرات في وقت التشغيل). في إطار iframe، اضبط فئة على<html>(و/أوcolor-schemeعلى:root) من تلك الإشارة بدلاً من الاعتماد علىprefers-color-scheme. - إذا كنت تتحكّم في الصفحة المضمّنة فقط: لا تتوفّر طريقة موثوقة لرصد
color-schemeسياق التضمين من داخل إطار iframe في Safari. اعرض مَعلمة مظهر صريحة في واجهة برمجة التطبيقات المضمّنة (مثل سلسلة طلب بحث أو بروتوكولpostMessage) ووثِّقها لمستخدمي التضمين.
- إذا كنت تتحكّم في كل من الصفحة الرئيسية وiframe: يمكنك تمرير نظام الألوان الخاص بالصفحة الرئيسية إلى iframe بشكل صريح، إما من خلال مَعلمة عنوان URL (
استراتيجيات احتياطية
الخيارات الاحتياطية وتوافق المتصفّحات مع color-scheme
سمة 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);
}