الوحدة 3 · متجاوب ومتين
الألوان الحديثة: oklch() وcolor-mix()
19 دقراءة 4 دبيئة تجريب الكود
الدرس في لمحة
عرّف الألوان بـ oklch() لتكون الإضاءة متوقّعة، واشتقّ الدرجات الفاتحة بـ color-mix()، وابنِ حالات المرور والتعطيل من لون أساسي واحد بصيغة الألوان النسبية.
لا فيديو هنا، بل الشيء الحقيقي: درس مكتوب وأمثلة قابلة للتشغيل واختبار وتدريب.
اختيرت ألوان المسارات الأربعة في Waypoint واحدًا تلو الآخر في أداة تصميم، كأكواد hex. بدا وردي Design صاخبًا، وأخضر Accessibility باهتًا، ونجح النص الأبيض في الشارات في اختبار التباين على مسارين وفشل على الآخرَين. وحين احتاج الفريق إلى درجة فاتحة لخلفية شارة كل مسار، ولّد أحدهم ثمانية أكواد hex أخرى بالعين. ثم جاءت حالات المرور. عشرون لونًا، بلا نظام، ولا أحد يستطيع أن يقول لماذا #0891b2 هو اللون الصحيح.
ألوان CSS الحديثة تتيح لك تعريف لون أساسي واحد لكل مسار، واشتقاق كل ما عداه بقواعد.
لماذا oklch()
hex وrgb() وhsl() كلها تصف الألوان في فضاء sRGB، المنظّم حول طريقة إطلاق الشاشات للضوء، لا طريقة رؤية العين له. و«الإضاءة» في HSL أسوأ المذنبين: hsl(60 100% 50%) (الأصفر) وhsl(240 100% 50%) (الأزرق) يدّعيان الإضاءة نفسها، لكن الأصفر مبهر والأزرق داكن. وأيّ لوحة ألوان تُبنى بتدوير درجة اللون في HSL تنتهي بتباين متفاوت بشدّة.
oklch() مبنية على نموذج OKLab، المصمّم لتتبع الأرقامُ الإدراكَ:
- L، الإضاءة، من 0 (الأسود) إلى 1 أو 100% (الأبيض)، والـ L المتساوية تبدو بالإضاءة نفسها عبر درجات اللون.
- C، التشبّع اللوني (chroma)، من 0 (الرمادي) إلى نحو 0.37 لأكثر الألوان حيوية التي تستطيع الشاشات عرضها.
- H، زاوية درجة اللون بالدرجات: حول 30 أحمر، و140 أخضر، و250 أزرق، و350 وردي.
:root {
--track-design: oklch(62% 0.19 350);
--track-perf: oklch(62% 0.19 220);
--track-a11y: oklch(62% 0.19 150);
--track-platform: oklch(62% 0.19 280);
}إضاءة واحدة، وتشبّع واحد، وأربع درجات لون. أصبحت المسارات تحمل وزنًا بصريًا متساويًا، وإن نجح النص الأبيض في اختبار التباين على أحدها فسيكون على مسافة قصيرة جدًا من النجاح على الأربعة. ما زلت تتحقّق من التباين (نماذج الإدراك ليست معادلات تباين)، لكنك تبدأ من نقطة قريبة بدل التخمين.
الدرجات الفاتحة والداكنة بـ color-mix()
تمزج color-mix() لونين في فضاء ألوان تختاره:
.badge {
background: color-mix(in oklch, var(--track) 15%, white);
color: color-mix(in oklch, var(--track) 70%, black);
}
.session-card.is-cancelled {
background: color-mix(in oklch, var(--track), transparent 85%);
}النسبة المئوية تخصّ اللون الذي تليه؛ واللون الآخر يأخذ الباقي. لذا فإن var(--track) 15%, white أبيض في معظمه مع لمحة من لون المسار: خلفية شارة. والمزج مع transparent يُنتج نسخة شبه شفافة، دون الحاجة إلى token منفصل للشفافية.
فضاء الألوان يغيّر النتيجة. مزج الأزرق والأصفر in srgb يمرّ برمادي موحل؛ أما in oklch فتنتقل درجة اللون حول العجلة وتبقى حيوية. ولدرجات الواجهة الفاتحة تعطي oklch أو oklab أكثر الخطوات انتظامًا. وcolor-mix() ضمن Baseline 2023.
الألوان النسبية: عدّل قناة واحدة
صيغة الألوان النسبية تفكّ اللون الأساسي إلى قنواته، وتتيح لك تغيير أيٍّ منها، ثم تعيد تركيبه:
.session-card {
--track: var(--track-design);
border-inline-start: 6px solid var(--track);
&:hover,
&.is-active {
border-color: oklch(from var(--track) calc(l - 0.15) c h);
}
&.is-past {
border-color: oklch(from var(--track) l 0.03 h); /* nearly grey, same hue */
}
& .badge-soft {
background: oklch(from var(--track) l c h / 20%); /* same color, 20% alpha */
}
}بعد from var(--track) تحمل الكلمات المفتاحية l وc وh قنوات اللون الأساسي كأرقام، وتستطيع استخدامها في calc(). لاحظ أن l هنا رقم من 0 إلى 1، لذا فطرح 0.15 يُغمق اللون 15 نقطة. وكل حالة مشتقّة تتبع الآن اللون الأساسي تلقائيًا: أضف مسارًا خامسًا، وستوجد أشكال المرور والماضي والدرجة الناعمة الخاصة به لحظة تعريف لونه الأساسي.
الألوان النسبية ضمن Baseline 2024، في Chrome وEdge وFirefox وSafari. وإن كان عليك دعم متصفّحات أقدم، فلا تعتمد على تصريح احتياطي ثابت تكتبه قبلها: هذه القيم تحتوي على var()، فيقبلها المتصفّح القديم وقت التحليل، ثم يقع في فخّ «غير صالح في وقت حساب القيمة» الذي رأيته في درس الـ Custom Properties و@property، فيضيع البديل أيضًا. بدلًا من ذلك غلّف الحالات المشتقّة بـ @supports (color: oklch(from red l c h)) { … }، فتحتفظ المتصفّحات القديمة بالقاعدة الأساسية.
دورك الآن
لبطاقة التمرين قيم hex مكتوبة يدويًا لدرجة الشارة الفاتحة وللحدّ في الحالة النشطة. استبدلها بدرجة فاتحة بـ color-mix() وحالة نشطة بلون نسبي، وأضف مسار Performance يطابق مسار Design في الإضاءة والتشبّع. تقرأ الفحوصات قنوات OKLCH المحسوبة. وبعدها ستنقل لوحة الألوان هذه إلى الوضع الداكن باستخدام color-scheme وlight-dark().
أهم النقاط
oklch(L C H)تفصل الإضاءة المُدرَكة (lightness) عن التشبّع اللوني (chroma) وعن درجة اللون (hue)، فيبدو لونان لهما L نفسها بالإضاءة نفسها، وهذا ما لا تستطيع HSL أن تعد به.- لوحة ألوان بإضاءة وتشبّع ثابتين ودرجات لون متغيّرة تعطي كل فئة الوزن البصري نفسه وتباينًا متقاربًا.
color-mix(in oklch, var(--track) 15%, white)تصنع درجة فاتحة من أيّ لون أساسي، وفضاء الألوان الذي تمزج فيه يغيّر النتيجة.- صيغة الألوان النسبية، مثل
oklch(from var(--track) calc(l - 0.15) c h)، تشتقّ لون الحالة بتعديل قناة واحدة من اللون الأساسي.