توسيع تعاقب القيمة اللونيّة باستخدام currentColor في CSS


محمد أبرص

إنّ أي مطوّرٍ يَستخدم تقنيات Sass أو LESS، يعلم تمامًا ما هي المُتغيّرات (variables) وكيفيّة استخدامها في صفحات التنسيق CSS، ويَعلم أيضًا فائدتها وما يُمكن أنّ تُقدّم له، في المُقابل، ولمن لا يَستخدِم المُعالج المُسبق (preprocessor)، رُبّما يَسأل: لماذا كل هذه الجلبة حولها، ولماذا يتحدّث الجميع عنها، وفائدتها؟، وعليه سيتناول هذا المقال فائدة المُتغيّرات، والمُتغيّر currentColor بشكل خاصّ. 

ما فائدة المُتغيّرات في CSS؟

تأتي أهميّة المُتغيّرات في CSS في سماحها للمطوّر بكتابة شيفرة (كود) نظيفة، ومُرتّبة وغير مُكرّرة، وذلك عبر تكريس مبدأ “لا تُكرّر نفسك” (Don’t Repeat Yourself)، والمعروف بالاختصار DRY، وتتجلّى أهميتها في إدارة وصيانة المشاريع الكبيرة، والّتي تحتوي على قيم مُكرّرة هنا وهناك.

يُشاع استخدام المُتغيّرات مع سمات الألوان (color themes) والّتي تجعل من إنشاء وإدارة توزّع الألوان في كامل مُستند CSS أسهل وأكثر مرونةً من أي وقتٍ مضى، فعلى سبيل المثال، يتطلّب توزيع الألوان عادةً إلى إعادة استخدام بعض قيم الألوان لخواصٍّ عدّة ومُختلفة في أرجاء ملفّ CSS، وعند الرغبة في تغيير اللّون الرئيسيّ للموقع، فسيُغيّر المُطوّر أو المُصمّم مضطرًا جميع القيم في صفحة التنسيق، ولكن مع استخدام مُتغيّرات CSS، يتمّ تعريف مُتغيّر ولمرّة واحدة، وليكن المُتغيّر يحمل الاسم “primary-color” مثلًا، وإسناد قيمة لونيّة له، ومن ثُمّ استخدام قيمة المُتغيّر في أي مكان في صفحة التنسيق، وعندما يُتطلّب تغيير هذا اللّون في وقتٍ لاحقٍ، فكل ما على المُطوّر فعله هو إسناد القيمة اللونيّة الجديدة إلى المُتغيّر، وعليه ستُحدّث قيمة المُتغيّر في جميع أرجاء صفحة التنسيق أوتوماتيكيًّا.

لم تطرح CSS 2.1 مفهوم المُتغيّرات، (على الرغم من أنّ ذلك ليس دقيقًا تمامًا)، ولكن في عام 2014، قُدّم مفهوم المُتغيّرات في بيانات CSS، وبشكل مُشابه للمُتغيّرات المُقدّمة من المُعالجات المُسبقة (preprocessor)، وعلى ما يبدو أنّها تملك إمكانيات أكبر مما تقدّمه مُتغيّرات المُعالجات المُسبقة المعروفة، حيثُ يُقبَل مُتغيّر CSS كقيمة من قبل جميع خاصيّات CSS.

كما قدّمت CSS بالإضافة إلى المُتغيّرات قيمة مفتاحيّة، والّتي تُعتبر عمليًا أيضًا مُتغيّر وهي:currentColor.

المُتغيّر/الكلمة المفتاحيّة currentColor

تُشبه الكلمة المفتاحيّة currentColor مُتغيّر CSS، ماعدا أنّها تَملك تقييدًا مُهمًّا، فهي تُستخدم فقط كبديل للمُعطى/المُعامل <color>، فإن كانت الخاصيّة لا تقبل قيمة هذا المُعامل، فهي لن تَقبلcurrentColor قيمة لها.

أمثلة على خواصّ تقبل استخدم currentColor كقيمة:

box-shadow: inset 2px 2px 3px currentColor;
background-color: currentColor; 
background-image: linear-gradient(currentColor, transparent);

إن الاختلاف الآخر بين المُتغيّر currentColor وبين المُتغيّرات المعروفة، يَكمن في عدم المقدرة على إسناد قيمةٍ له بنفس طريقة إسناد القيم للمُتغيّرات كما جرت العادة، فإن قيمة currentColor يتمّ تحديدها بالقيمة المحسوبة لخاصيّة اللّون الّتي حاليًا تُستخدم/تُطبّق على العنصر، وهذا يعني أنّ قيمة currentColor تساوي قيمة خاصيّة اللّون الحاليّ، ومن هنا جاء الاسم currentColor (اللّون الحاليّ).

يُظهر المثال السابق كيف تُعيّن/تَضبط الكلمة المفتاحيّة currentColor لون ظل الصندوق (box shadow) إلى أيّما كانت قيمة اللّون المعيّنة للعنصر div، وفي حال عدم ضبط أي لون له (الوسم div)، فسيتمّ استخدام اللّون المَوروث من أسلاف الـ div، وعند عدم امتلاك أيًا من هذه الأسلاف قيمة لونيّة، فإن مُعظم المُتصفّات ستُعين اللّون الأسود كقيمة بديلة.

بعبارةٍ أُخرى، إن الكلمة المفتاحيّة تُستخدم لجعل خواصّ عنصر، أو العناصر الأبناء لعنصر، تَرث اللّون المُعيّن من قِبل المُعطى <color>، ولذلك فإنّها تتصرّف كما تفعل القيمة inherit في السّماح بوراثة قيمة اللّون والّتي ما كان له أنّ يُورّث إلى العنصر الابن بدونها.

يعني هذا أيضًا أن الخاصيّات الّتي تَرث بالأصل قيمة color، لن تكون الكلمة المفتاحيّة currentColor بتلك الفائدة بالنسبة لها.

الخاصّيّات والعناصر الّتي ترِث قيمة color بشكل افتراضي

عندما يَملك عنصر قيمة لونيّة، سواءً كانت مُعيّنةً بشكل صريح أو وراثةً، فإن بعض العناصر الأماميّة (foreground) –وهي عكس خلفيّة (background) ويُقصد بها لون النصّ الظاهر للعيان- لهذا العنصر والّتي تقبل القيمة <color> ستَرث قيمة اللون بشكل افتراضيّ.

فعلى سبيل المثال، إن حدود (borders) عنصر هي جزء من أماميّة (foreground) هذا العنصر، ولذلك حتّى مع عدم تحديد لون للحدود، فإنها ستأخذ نفس القيمة اللونيّة للخاصيّة color، وإن لم يَملك العنصر إي لونٍ فإن مُعظم المُتصفّحات عادةً ما ستستخدم اللون الأسود.

ستكون لون الحدود زرقاء في المثال التّالي:

.parent {
    color: blue;
}

.child {
    border: 5px solid; /* لم يتمّ تعيين قيمة لونيّة للحدود */
}

العناصر الّتي تَرث قيمة color هي:

  • نصيّة العنصر، والّتي تُعنى بها خاصيّة color.
  • إطار النصّ (text outline).
  • حدود العنصر (element border)
  • ظل الصندوق (box shadow)
  • نصّ الصورة البديل (alt)، وهو النصّ الّذي يُعرض عند عدم عرض الصورة لسببٍ ما.
  • علامات التنقيط/الكرات الصغيرة الخاصّة بالقائمة (list item bullet) وحدودها (borders).
  • حدود المسطرة الأفقيّة (hr) في بعض المُتصفّحات، مثل المُتصفّح كروم، ومع الانتباه أنّه لن يتأثّر لون المسطرة عند عدم وجود حدود.

عدم إسناد قيمة لونيّة لهذه العناصر (السابقة) بشكل صريح، سيجعلها يرثون قيمة color المحسوبة.

يظهر المثال التّالي عمليًّا كيف تتأثر العناصر السابقة باللّون المُسند لجذع الصفحة (body)، وعليه فإن تغيير لون جذع الصفحة سيُغيّر من لون هذه العناصر جميعًا:

body {
    color: rgb(255, 20, 20);
    background-color: white;
    height: 100vh;
    padding: 2em;
}

hr {
    border: 3px solid;
}

div {
    padding: 1em;
    width: 200px;
    height: 150px;
    border: 5px solid;  
    box-shadow: 5px 5px 5px;
}

p {
    background-color: currentColor;
    padding: .5em;
    width: 80%;
    margin: 1em auto;
}

li {
    border: 1px solid
}

strong {
    outline: 2px solid;
}

color-inheritacne.thumb.png.bf14cb1d7fa7

السؤال الّذي قد يُسأل الآن، إنّ كانت أغلب العناصر أو الخاصّيّات ترث قيمة color، إذًا ما فائدة currentColor؟

توسيع وراثة اللّون باستخدام currentColor

يوجد بعض الحالات الّتي يكون فيها جلب قيمة color واستخدامها أمرًا مُفيدًا للغاية، يتبيّن ذلك في استخدام currentColor مع الحالات الّتي لا تُطبق الوراثة، وهي التدرجات اللّونيّة (gradients)، فصور التدرجات في CSS، إن كانت التدرّجات الخطيّة أو التدرّجات النصف قطريّة، لا ترث قيم الألوان، ولكن باستخدام currentColor يُصبح بالإمكان استخدام التدرّج الخطّي كصورة خلفيّة:

background-image: linear-gradient(to bottom, currentColor, #fff);

تمّ أخذ هذا المبدأ إلى أبعد من ذلك، حيثُ تمّ عمل شيء يُشبه التحريك (animation) لخاصيّة color، فعندما تتغيّر قيمة الخاصيّة color، فإن جميع العناصر ستتأثّر وتُغيّر من لونها:

مثال حيّ: http://codepen.io/scottkellum/pen/Fhxql

يُظهر المثال السابق بحق قوة هذه الميّزة الّتي تُقدّمها CSS، وخاصّةً في جزئيّة التحريك.

ظهر مؤخرًا المزيد من الأمثلة التطبيقيّة لهذه الميّزة، وهو ما سيتمّ التركيز عليه في بقيّة المقال.

استخدامات currentColor العمليّة

تَكمن الفكرة الرّئيسيّة خلف currentColor في توسيع تسلسل أو تعاقب اللّون، وهو أمرٌ يستفاد منه في العديد من الحالات.

استخدام currentColor في قَوْلَبة عناصر واجهة المُستخدِم (UI)

يُمكن استخدام currentColor في حالات تطبيقيّة عديدة، فعلى سبيل المثال يُمكن استخدامcurrentColor مع عناصر واجهة المُستخدِم لتنسيق صفحة ويب كاملة (أو تطبيق ويب كامل) مُباشرةً باستخدام المُتصفّح.

يُظهر المثال التّالي عمليًا، وباستخدام أدوات المطوّرين (devtools) الخاصّة بالمُتصفّح ومنها من منتقي الألوان، كيف أنّ تغيير قيمة خاصيّة color، سيُغيّر من ألوان جميع عناصر واجهة المُستخدِم وذلك باستخدام المُتغيّر currentColor.

currentColor-components-compressor.thumb

استخدام currentColor في قَوْلَبة وتنسيق SVG

إنّ الرسوم المُتجهة القابلة للتوسّع (Scalable Vector Graphics) رائعة بلا شك، ولكنّها مع ذلك تأتي مع بعض القصور، عند استخدامها بطرقٍ مُعيّنة، مثلًا عند إعادة استخدام أجزاء من SVG باستخدام العنصر <use>.

يُستفاد من العنصر <use> في إعادة استخدام أجزاء من SVG في أي مكان يُرغب في أنّ تظهر به هذه الأجزاء على الصفحة، ما يتمّ عمليًا عند استخدام عنصر SVG هو إنشاء نسخة حيّة من ذلك العنصر، فالأمر مُشابه لفكرة نسخ ولصق العناصر في أي مُحرّر رسومي، ما عدا أنّ هذه النسخة هي نسخة حيّة، أي أنّ خصائصها ستتغيّر عند تَغيّر النسخة الأصل.

يُستخدَم العنصر <use> بشكل كبير عند إنشاء SVG sprites، فيُمكن استخدام SVG يحتوي على جميع الرموز الصوريّة (الأيقونات) والّتي ستستخدم كـ sprite، ومن ثُمّ إدراج الأيقونات على حدى من ذلك الـ sprite وفي أي مكان على الصفحة، باستخدام <use>، ويُمكن الاستزادة حول هذا الموضوع عبر قراءة: طريقة إنشاء الـ sprites.

عند استخدام العنصر، فإن نسخة من محتواه ستُنسخ إلى shadow DOM، وهذا يعني أنّ هذا المُحتوى لا يُمكن اختياره وتنسيقه باستخدام CSS كما يتمّ عادةً عبر اختيار و تنسيق عناصر SVG، أو حتّى عناصر HTML متمثلةً بالـ DOM الاعتيادي، هذا أحد الأسباب الّتي تجعل من تنسيق أيقونات SVG المُنشئة بهذه الطريقة ذو إمكانيات وقدرات محدودة.

إن استخدام currentColor يَسمح بتخطّي هذه المحدوديّة، عن طريق السماح للّون المُعيّن في CSS بالتسرّب إلى محتويات SVG المُستعمل، وذلك بضبط currentColor كقيمة للخواصّ المُراد من قيمة اللّون أنّ تتسرّب إليها:

<svg class="home-icon">
    <use xlink:href="#home"></use>
</svg>
وعلى فرض أنّ الأيقونة #home مُعرّفة كما في التّالي:

<symbol id="home">
    <rect id="bottom" fill="currentColor" ... />
    <polygon id="roof" ... />
</symbol>

أصبح من المُمكن الآن تطبيق التنسيقات على الأيقونة وجعل اللون fill يتعاقب نزولًا إلى #roof(والذي لا يَملك الخصلة fill) وتوريث قيمة color إلى #bottom:

.home-icon {
    fill: red;
    color: white;
}

سيتعاقب اللّون المملوء نزولًا من <svg> إلى <use>، وبعد ذلك إلى #roof، وستُستخدم قيمةcolor كقيمة لـ #bottom، وذلك فقط بسبب استخدام currentColor.

يُستفاد من هذا الأسلوب عند الحاجة إلى إنشاء أيقونات عديدة، كلٍ منها ذو لونٍ مُختلف، فكل ما يجب عمله في هذه الحالة هو تغيير قيمة color و fill في ملفّ CSS، وهو ما يَستعرضه المثال الحيّ التّالي:

مثال حيّhttp://codepen.io/FWeinb/pen/rGBsC

يُمكن استخدام currentColor على عناصر عدّة داخل SVG، ولكن هذا يَسمح فقط بتغيير لونين داخل SVG.

وإن كانت الرغبة هي الحصول على تحكم أكبر على الألوان وتعيين المزيد من قيم الألوان لتتسرّب إلىSVG، فعندها يجب توفّر المزيد من المتغيّرات، وهنا بالضَّبط تأتي قيمة متغيّرات CSS المقدّمة في البيان (specification) الخاصّ بها، يُمكن القراءة أكثر عن هذا الأمر من خلال موضوع بعنوان: تخصيص أيقونات SVG باستخدام متغيّرات CSS

الخاتمة

تمّ التوضيح في المثال السابق كيفيّة استخدام currentColor في أماكن عدّة، ومن ثمّ تغيير الألوان المُراد تغييرها في مكان واحد فقط، ليُطبّق هذا التعديل على هذه الأماكن المُختلفة، بدلًا من إنشاء عدّة حالات من نفس اللّون ومن ثُمّ تغييرها جميعها عند الحاجة، وهذا من شأنه أنّ يُساعد المطوّر على كتابة ملفّ تنسيق CSS قصير ونظيف، وتقديم نوعًا من الآليّة في الإعداد، خاصّةً في حالات مثل عناصر ومكوّنات واجهة المُستخدِم UI.

يَمتلك المطوّر أو المُصمم مع مُتغيّرات CSS القدرة على تعريف مجموعة من المُتغيّرات واستخدامها في حالات عديدة ومُختلفة، طالما أنّ المُتغيّرات الجديدة ستكون قيم صالحة مع أي خاصيّة من خواصّ CSS، وليس فقط تلك الّتي تقبل قيم المُعطى/المُعامل <color>، فالتعامل مع أيقونات SVG بالتأكيد سيُصبح أسهل، وكذلك الأمر مع صون المشاريع الكبيرة في إعدادها الأولي، وعند تنقيحها.

ترجمة –وبتصرّف- للمقال Extending the Color Cascade with the CSS currentColor Variable لصاحبته سارة سويدان





تفاعل الأعضاء


لا توجد أيّة تعليقات بعد



يجب أن تكون عضوًا لدينا لتتمكّن من التعليق

انشاء حساب جديد

يستغرق التسجيل بضع ثوان فقط


سجّل حسابًا جديدًا

تسجيل الدخول

تملك حسابا مسجّلا بالفعل؟


سجّل دخولك الآن