محوّل الألوان وفاحص التباين

يحوّل بين HEX و‑RGB و‑HSL و‑OKLCH وأسماء ألوان CSS، ويفحص نسبة التباين وفق WCAG بين لونين.

المقدمة
  • HEX#3b82f6
  • RGBrgb(59, 130, 246)
  • HSLhsl(217, 91.2%, 59.8%)
  • OKLCHoklch(62.31% 0.188 259.81)
  • الاسملا اسم CSS مطابق
الخلفية
  • HEX#ffffff
  • RGBrgb(255, 255, 255)
  • HSLhsl(0, 0%, 100%)
  • OKLCHoklch(100% 0 0)
  • الاسمwhite
التباين
3.68:1نسبة التباين
نص المتن
دون 18pt، أو دون 14pt عريضًا
AAAAA
نص كبير
18pt فأكثر، أو 14pt عريضًا فأكثر
AAAAA
عناصر التحكم والرسوم
الحدود والأيقونات وسائر الأجزاء غير النصية
AA

لنص المتن بهذا الحجم كُتبت عتبة 4.5:1.

النص الكبير يكفيه 3:1

ما الذي تفعله هذه الأداة

مهمتان تتبيّنان دائمًا مهمةً واحدة. لديك لون وتحتاجه بكتابة أخرى — ملف التصميم يقول شيئًا وورقة الأنماط تريد غيره. ولديك لونان وتحتاج أن تعرف هل يُقرأ نص بالأول فوق الثاني. لذا تأخذ هذه الصفحة لونين، وتعرض كلًا منهما بجميع الصيغ دفعةً واحدة، وتقيس التباين بينهما.

كل ذلك يجري داخل متصفحك. ولا يحتاج شيء من لوحة ألوان علامة لم تُطلق بعد أن يسافر إلى خادوم كي يُحوَّل.

الكتابات الخمس

كل واحدة منها يمكن لصقها، وكلها تخرج مجددًا:

  • الست عشرية — ثلاث أو أربع أو ست أو ثماني خانات. والصور القصيرة تضاعف كل خانة، فتعني ‎#f0a قيمة ‎#ff00aa. وتحمل الأربع والثماني قيمة الشفافية في الموضع الأخير.
  • RGB — القنوات الثلاث أعدادًا أو نسبًا مئوية. ويُقبل rgb(59, 130, 246) وكذلك rgb(59 130 246 / 50%)؛ وصورة الفواصل هي ما تكتبه الأداة في المقابل، لأنها لا تزال ما تستعمله أغلب الشيفرة من حولك.
  • HSL — التدرج بالدرجات، ثم التشبع والإضاءة بالنسب المئوية. والتدرجات تلتف، فـ480 و‑120 صالحان ويعنيان 120 و‑240.
  • OKLCH — إضاءة وتشبع وتدرج في فضاء منتظم إدراكيًا. ويجوز كتابة الإضاءة 62.8% أو 0.628.
  • أسماء CSS — جميعها الـ148، ومنها rebeccapurple وكلتا كتابتَي كل رمادي. ولا يظهر الاسم في الخرج إلا عند التطابق التام.

ثمة خصوصية تستحق المعرفة: الست عشرية و‑RGB و‑OKLCH تنجو جميعها من رحلة الذهاب والإياب دون تغيير، أما HSL فلا تمامًا. فهي تُطبع بالدقة التي يقرأها الناس فعلًا — درجات صحيحة وخانة عشرية واحدة للنسبة — وهذه لا تكفي لعنونة ألوان sRGB البالغة 16.7 مليون. حوّل لونًا ست عشريًا إلى HSL وعُد، وقد تتحرك قناة بمقدار واحد. والبديل خرج مثل hsl(217.22, 91.19%, 59.8%)، ولا أحد يرغب في لصقه. والخطأ أدنى بكثير مما تراه العين.

لماذا وُجد OKLCH

يبدو أن HSL يصف الإضاءة، وهو لا يفعل. فرقم الإضاءة فيه خاصية للأرقام لا للضوء. الأصفر الخالص والأزرق الخالص كلاهما بإضاءة 50% في HSL:

#ffff00   hsl 50%   oklch 96.8%   أصفر
#0000ff   hsl 50%   oklch 45.2%   أزرق

كل أحد يرى أن الأصفر أفتح الاثنين، و‑OKLCH يقول ذلك. وليست المسألة أكاديمية: فهذا سبب أن لوحةً بُنيت بتثبيت إضاءة HSL وتدوير التدرج تُخرج مجموعة ألوان تبدو متفاوتة تفاوتًا صارخًا، وأن الحيلة نفسها في OKLCH تُخرج مجموعة تبدو أسرةً واحدة. وهو أيضًا سبب أن لونين متساويي الإضاءة في OKLCH يكون تباينهما عادةً متقاربًا فوق الخلفية نفسها — وهو ما لا يستطيع HSL أن يعد به إطلاقًا.

والرقمان الآخران هما التشبع — أي بخشونة: كم هو ملون، ابتداءً من 0 للرمادي — والتدرج بالدرجات. وخلافًا لتشبع HSL، ليس هذا التشبع نسبةً مئوية من أي شيء، ولذلك تتوقف القيمة القصوى المفيدة على الإضاءة والتدرج معًا.

حين يتعذر عرض لون

يستطيع OKLCH وصف ألوان أكثر مما تنتجه شاشة عادية. اطلب إضاءة 70% بتشبع 0.4 وتكون قد سمّيت أخضر موجودًا من حيث المبدأ وغير موجود في sRGB البتة. والأداة تقصر هذا اللون داخل المدى وتضع عليه علامة «خارج sRGB»، بدل أن تعيد إليك في صمت شيئًا آخر.

ولا يظهر التنبيه إلا حين يغيّر هذا القصر اللون الذي تحصل عليه فعلًا. وهذا التمييز أثقل مما يبدو. فأحمر sRGB يقع تمامًا على حدّ النطاق، ومن ثم فقيمة OKLCH منشورة له، مقربةً إلى أربع خانات عشرية، تقع تقنيًا خارجه بشعرة — نحو جزأين من عشرة آلاف، يقعان على البايت نفسه ولا يُريان. والتنبيه على ذلك كان سيعلّمك تجاهل التنبيه. أما لون من لوحة واسعة النطاق فيخطئ بخطوات كاملة: إذ يطلب blue-500 في Tailwind v4 مقدار 261 من 255 ممكنة في القناة الزرقاء، وعلى شاشة sRGB ليس هو حقًا اللون المطلوب.

التباين وعتباته الثلاث

تقارن نسبة التباين الإضاءة النسبية للونين. وتمتد من 1:1 للونين متطابقين إلى 21:1 للأسود على الأبيض، ولا شيء يتجاوز ذلك. ويضع WCAG 2.1 ثلاث عتبات، وهي غير قابلة للتبادل:

  • 4.5:1 لنص المتن — كل ما دون 18pt، أو دون 14pt عريضًا. وهذه هي التي يقصدها الناس حين يقولون إن لونًا «رسب في التباين».
  • 3:1 للنص الكبير — 18pt فأكثر، أو 14pt عريضًا فأكثر. فالحروف الأكبر تحمل بنفسها قدرًا أكبر من الإشارة، فتنخفض العتبة.
  • 3:1 لعناصر التحكم والرسوم — حدّ حقل الإدخال، وسهم القائمة المنسدلة، وأعمدة الرسم البياني. أُضيفت في WCAG 2.1 وتُغفَل على نطاق واسع، لأن الناس يفحصون نصهم ولا يفحصون الإطار حوله أبدًا.

ويرفع المستوى AAA أولى العتبتين إلى 7:1 والثانية إلى 4.5:1. ويستحق السعي إليه في نص المتن، وبلوغه بلوحة ألوان علامة تجارية صعب حقًا؛ أما AA فهو ما تطلبه اللوائح وعمليات التدقيق.

ومقاسات النقاط في هذه القواعد نقاط CSS لا بكسلات: فـ18pt تساوي 24px، و‑14pt نحو 18.7px بالإعدادات المبدئية. ومن السهل افتراض أن عنوانًا بمقاس 20px يُعد نصًا كبيرًا. وهو ليس كذلك.

الألوان نصف الشفافة

للنص نصف الشفاف فوق خلفية معتمة نسبة تباين محددة تمام التحديد: فالمتصفح يمزج اللونين قبل الرسم، وكذلك تفعل هذه الأداة. والنص الرمادي بعتامة 60% هو ببساطة رمادي أفتح بمجرد أن يحطّ، ويُقاس بما حطّ عليه. أما الأدوات التي تتجاهل قناة الشفافية فتُبلغ عن نسبة اللون الذي كتبته لا اللون الذي يراه أحد، وهو ما يبالغ فيها دائمًا — وفاحص نفاذية يخطئ لصالحك أسوأ من غياب الفاحص أصلًا.

والخلفية نصف الشفافة حالة أخرى ترفضها الأداة. فما يُرى من خلفها يتوقف على ما تحتها، وليس ذلك سؤالًا يستطيع اللونان في هذه الصفحة الإجابة عنه. حلّ الخلفية إلى اللون الذي تتركب إليه فعلًا وقس ذلك.

ما لا تخبرك به النسبة

النسبة المجتازة أرضية لا حكم نهائي. وثلاثة أمور لا تغطيها:

  • عمى الألوان. الأحمر والأخضر المتساويان في الإضاءة نسبتهما قريبة من 1:1 ولا يميزهما أحد — لكن لونين قد يجتازان النسبة ويظلان الشيء الوحيد الفاصل بين حالتين، وهذا يفشل مع كل من لا يفرق بينهما. فلا تحمّل المعنى للتدرج وحده أبدًا.
  • الخطوط الرفيعة. لا تعرف الصيغة شيئًا عن سماكة الحرف. فوزن شعري عند 4.5:1 قد يكون أشق قراءةً من وزن عادي عند 4:1.
  • الصيغة نفسها. من المعروف أن تباين WCAG 2 غير منصف للنص الفاتح على خلفية داكنة، إذ يبلغ عن نسب تبدو أعلى مما تُقرأ. و‑APCA، المصاغة لـ WCAG 3، تنمذج ذلك على نحو أفضل — لكنها ليست معيارية، ولا يقبلها أي تدقيق بعد، وعرض درجتين متناقضتين لم يكن لينفع أحدًا. ولهذا نوقشت هنا ولم تُطبع أعلاه.

ملاحظة تنفيذية لمن يقارن النتائج بشيفرته: تستعمل صيغة الإضاءة عتبة 0.03928، وهي تختلف اختلافًا طفيفًا عن 0.04045 في تعريف sRGB الحالي. ويستشهد WCAG بالقيمة الأقدم، فهي المستعملة هنا. والالتزام بالمواصفة أثقل وزنًا من الاتساق الداخلي، والفارق لا يحوّل اجتيازًا إلى رسوب أبدًا.

الأسئلة الشائعة

لماذا يتغير لوني الست عشري بعد التحويل إلى HSL والعودة؟
لأن HSL يُطبع بدقة يستطيع الناس قراءتها وإعادة كتابتها، وهي لا تكفي لتسمية كل لون في sRGB. ويتحرك خطوة واحدة على الأكثر في القناة، وذلك غير مرئي. أما الست عشرية و‑RGB و‑OKLCH فتعود بالضبط، فاستعمل إحداها إن احتجت وسيطًا بلا فقد.
ما معنى «خارج sRGB»؟
قيمة OKLCH التي أدخلتها تسمي لونًا لا تستطيع شاشتك إنتاجه، فقُصر إلى أقرب لون تستطيعه. والقيم المأخوذة من لوحات واسعة النطاق مثل Tailwind v4 تفعل ذلك بانتظام. ولا يظهر التنبيه إلا حين يغيّر القصر اللون المعروض، فالقيمة المقربة التي تظل تقع على البايت نفسه لا تثيره.
نصي يجتاز AA. هل هو نفاذ؟
إنه يتخطى عتبة بعينها. والنسبة لا تقول شيئًا عما إذا كان اللون هو الشيء الوحيد المميز بين حالتين، ولا عن سماكة الحرف، ولا عن كيف يُقرأ الاقتران لمن ضعف بصره. فاعتبر الاجتياز بداية الفحص لا نهايته.
لماذا لا يُعد عنواني بمقاس 20px نصًا كبيرًا؟
القاعدة مكتوبة بالنقاط لا بالبكسلات: 18pt تساوي 24px، و‑14pt عريضًا نحو 18.7px. فالعنوان العادي بمقاس 20px يقع دون الخط ويُقاس مقابل 4.5:1 كأي نص متن آخر.
هل أستطيع فحص التباين لخلفية نصف شفافة؟
ليس من لونين فحسب: فالجواب يتوقف على ما خلفها، والصفحة لا تعلمه. احسب اللون الذي تتركب إليه الخلفية وأدخله. أما المقدمة نصف الشفافة فتعمل وتُعالَج معالجةً صحيحة: إذ تُركَّب فوق الخلفية قبل القياس، تمامًا كما يرسمها المتصفح.
هل تُرسَل لوحة ألواني إلى أي مكان؟
لا. التحليل والتحويل وحساب التباين تجري كلها في متصفحك؛ ولا يغادر جهازك شيء مما تكتبه.