The CSS Podcast - 003: Specificity
لنفترض أنّك تعمل مع رمز HTML وCSS التاليَين:
<button class="branding">Hello, Specificity!</button>
.branding {
color: blue;
}
button {
color: red;
}
هناك قاعدتان تستهدفان العنصر نفسه هنا. تحتوي كل قاعدة على بيان يريد ضبط لون الزر: يحاول أحدهما تلوين الزر باللون الأحمر ويحاول الآخر تلوين الزر باللون الأزرق. ما هو البيان الذي يتم تطبيقه على العنصر؟
إنّ فهم خوارزمية تحديد CSS هو المفتاح لفهم كيفية اختيار CSS بين العناصر المتنافسة.
إنّ التحديد هو إحدى المراحل المميزة للسلسلة، وقد تم تناوله في الوحدة الأخيرة حول السلسلة.
تسجيل نتيجة الدقة
تحصل كل قاعدة أداة اختيار ضمن مصدر على تقييم. يمكنك اعتبار النوعية كنتيجة إجمالية ويحصل كلّ نوع من أنواع المحدّدات على نقاط نحو تلك النتيجة. يتم اختيار البيانات من القواعد الأكثر تحديدًا.
في مشروع حقيقي، يتمثل التوازن في التأكّد من تطبيق قواعد CSS التي تتوقّع تطبيقها، مع الحفاظ على انخفاض الدرجات بشكل عام لتجنّب التعقيد. يجب أن تكون الدقة عالية بما يكفي فقط، بدلاً من السعي إلى تحقيق أعلى دقة ممكنة. في المستقبل، قد يكون من الضروري تطبيق بعض قواعد CSS الأكثر أهمية. إذا كنت تسعى إلى تحقيق أعلى درجة من التحديد، ستصعِّب هذه المهمة.
الدقة ليست عددًا عشريًا بل ثلاثية
تتكون من ثلاثة مكوّنات: A
وB
وC
.
A
: دقة تشبه دقة المعرّفB
: دقة شبيهة بالفئةC
: تحديد العناصر
ويتم تمثيله غالبًا باستخدام الرمز (A,B,C)
. على سبيل المثال: (1,0,2)
.
ويُستخدَم أيضًا الرمز البديل A-B-C
بشكل شائع.
مقارنة الخصائص
تتم مقارنة التحديدات من خلال مقارنة المكوّنات الثلاثة بالترتيب: تكون التحديد التي تتضمن قيمة أكبر من A أكثر تحديدًا. إذا كانت قيمتَا A متساويتين، تكون التحديد التي تتضمن قيمة أكبر من B أكثر تحديدًا. إذا كانت قيمتَا B متساويتين أيضًا، تكون التحديد التي تتضمن قيمة أكبر من C أكثر تحديدًا. إذا كانت جميع القيم متساوية، تكون التحديدتان متساويتين.
على سبيل المثال، يُعتبر (1,0,0)
أكثر دقة من (0,4,3)
لأنّ قيمة A
في (1,0,0)
(وهي 1
)
أكبر من قيمة A
من (0,4,3)
(وهي 0
).
تؤثر أدوات الاختيار في مدى التحديد.
يبدأ كل جزء في الثلاثية الخاصة بالتحديد بقيمة 0
،
وتكون القيمة التلقائية للتحديد هي (0,0,0)
.
يزيد كل جزء من أداة الاختيار من التحديد الذي يؤدي، استنادًا إلى نوع أداة الاختيار،
إلى زيادة قيمة A
أو B
أو C
.
أداة اختيار جميع أنواع العناصر
لا يضيف المُحدِّد الشامل (*
)
أي تحديد، ويترك قيمته على التحديد الأولي (0,0,0)
.
* {
color: red;
}
محدِّد العنصر أو العنصر النائب
يضيف محدد العنصر (النوع)
أو العنصر الاصطناعي
تحديدًا يشبه العنصر، ما يزيد المكوّن C
بمقدار 1
.
تبلغ القيمة الإجمالية لمعيار التحديد في الأمثلة التالية (0,0,1)
.
أداة اختيار النوع
div {
color: red;
}
أداة اختيار العناصر الزائفة
::selection {
color: red;
}
أداة اختيار فئة أو فئة زائفة أو سمة
تضيف أداة اختيار الفئة أو
الفئة الزائفة أو
السمة تحديدًا شبيهًا بالفئة
يزيد من مكوّن B
بمقدار 1
.
تبلغ نسبة النوعية في الأمثلة التالية (0,1,0)
.
أداة اختيار الفئة
.my-class {
color: red;
}
أداة اختيار الفئة الزائفة
:hover {
color: red;
}
أداة اختيار السمات
[href='#'] {
color: red;
}
أداة اختيار أرقام التعريف
يضيف محدِّد رقم التعريف
تحديدًا مشابهًا لرقم التعريف، ما يزيد مكوّن C
بمقدار 1،
ما دام يتم استخدام محدِّد رقم تعريف (#myID
) وليس محدِّد سمة ([id="myID"]
).
في المثال التالي، تكون الدقّة (1,0,0)
.
#myID {
color: red;
}
أدوات الاختيار الأخرى
تحتوي لغة CSS على العديد من أدوات الاختيار. ولا تضيف بعض هذه الكلمات مزيدًا من التحديد.
على سبيل المثال، لا تضيف الفئة الزائفة :not()
أيّ شيء إلى عملية احتساب النوعية.
ومع ذلك، تتم إضافة المحدّدات التي تم تمريرها كوسيطات إلى عملية احتساب النوعية.
div:not(.my-class) {
color: red;
}
يحتوي هذا العيّنة على نسبة تمييز (0,1,1)
لأنّه يحتوي على محدد نوع واحد (div
) وفئة واحدة داخل :not()
.
التحقّق من فهمك
اختبِر معلوماتك حول احتساب درجة النوعية
ما هي سمة a[href="#"]
؟
(0,0,1)
a
هي (0,0,1)
، ولكن قيمة [href="#"]
هي (0,1,0)
.(0,1,0)
a
هي (0,0,1)
، ولكن قيمة [href="#"]
هي (0,1,0)
.(0,1,1)
a
هي (0,0,1)
وقيمة [href="#"]
هي (0,1,1)
، ما يجعل النوعية الإجمالية هي (0,1,1)
.العوامل التي لا تؤثّر في النوعية
هناك بعض المفاهيم الخاطئة الشائعة حول العوامل التالية التي تؤثّر في التحديد.
سمات النمط المضمّنة
لا يؤثّر ملف CSS الذي يتم تطبيقه مباشرةً على سمة style
لعنصر ما،
في النوعية لأنّه خطوة مختلفة في التسلسل
يتم تقييمها قبل النوعية.
<div style="color: red"></div>
لإلغاء هذا البيان من داخل جدول أسلوب، عليك اللجوء إلى الحصول على بيان الفوز في خطوة سابقة من التسلسل.
على سبيل المثال، يمكنك إضافة !important
إليه،
لكي يصبح جزءًا من مصدر !important
الذي تم إنشاؤه.
!important
بيان
لا يؤثّر الرمز !important
في نهاية تعريف CSS على النوع المميّز
ولكنّه يضع التعريف في مصدر مختلف، وهو !important
من تأليف.
في المثال التالي، لا تكون التحديد الخاص بـ .my-class
ذا صلة بفوز بيان
!important
.
.my-class {
color: red !important;
color: white;
}
عندما يكون !important
لكل بيانَين، تُستخدَم السمة المحدّدة مرة أخرى،
لأنّ خطوة المصدر من التسلسل الهرمي لم تتمكّن من تحديد الفائز بعد.
.branding {
color: blue !important;
}
button {
color: red !important;
}
النوعية في السياق
عند استخدام أداة اختيار معقّدة أو مركبة، يساهم كل جزء من هذه الأداة في زيادة التحديد. إليك مثال على رمز HTML:
<a class="my-class another-class" href="#">A link</a>
يتضمّن هذا الرابط صفَّين دراسيَّين.
تحتوي القاعدة في ملف CSS التالي على درجة تحديد (0,0,1)
:
a {
color: red;
}
إذا كنت تشير إلى إحدى الفئات في أداة الاختيار،
سيكون لها الآن درجة دقة تبلغ (0,1,1)
:
a.my-class {
color: green;
}
أضِف الفئة الأخرى إلى أداة الاختيار،
وأصبح لديها الآن درجة خصوصية تبلغ (0,2,1)
:
a.my-class.another-class {
color: rebeccapurple;
}
أضِف السمة href
إلى أداة الاختيار،
وأصبح لديها الآن درجة دقة تبلغ (0,3,1)
:
a.my-class.another-class[href] {
color: goldenrod;
}
أخيرًا، أضِف فئة زائفة :hover
إلى كل ذلك،
وينتهي أداة الاختيار بنسبة تحديد (0,4,1)
:
a.my-class.another-class[href]:hover {
color: lightgrey;
}
التحقّق من فهمك
اختبِر معلوماتك حول احتساب درجة النوعية
أيّ من أدوات الاختيار التالية لها خصوصية (0,2,1)
؟
article > section
(0,0,2)
.article.card.dark
(0,2,1)
.article:hover a[href]
(0,0,1)
× 2) ومحدِّد سمة (قيمة (0,0,1)
) ومحدِّد فئة (قيمة (0,0,1)
). يمنح ذلك هذا المحدِّد دقة إجمالية تبلغ (0,2,2)
.زيادة النوعية بشكل عملي
لنفترض أنّ لديك بعض تنسيقات CSS التي تبدو على النحو التالي:
.my-button {
background: blue;
}
button[onclick] {
background: grey;
}
باستخدام رمز HTML الذي يبدو على النحو التالي:
<button class="my-button" onclick="alert('hello')">Click me</button>
يحتوي الزر على خلفية رمادية،
لأنّ المحدّد الثاني له درجة تحديد (0,1,1)
.
ويعود السبب في ذلك إلى أنّها تحتوي على أداة اختيار نوع واحدة (button
)،
وهي (0,0,1)
وأداة اختيار سمة واحدة ([onclick]
)، وهي (0,1,0)
.
تساوي القاعدة السابقة .my-button
(0,1,0)
لأنّها تحتوي على أداة اختيار فئة واحدة، وهي أقل تحديدًا من (0,1,1)
.
إذا أردت تحسين هذه القاعدة، يمكنك تكرار أداة اختيار الفئة على النحو التالي:
.my-button.my-button {
background: blue;
}
button[onclick] {
background: grey;
}
سيظهر الزر الآن بخلفية زرقاء،
لأنّ أداة الاختيار الجديدة تحصل على درجة تحديد (0,2,0)
.
في حال تساوي درجة التحديد، يتم الرجوع إلى الخطوة التالية في التسلسل.
لنبقى في مثال الزرّ الآن ولنبدِّل خدمة مقارنة الأسعار إلى ما يلي:
.my-button {
background: blue;
}
[onclick] {
background: grey;
}
يحتوي الزر على خلفية رمادية،
لأنّ كلتا أداتَي الاختيار تتضمّنان درجة تحديد متطابقة تبلغ (0,1,0)
.
في حال تبديل القواعد بترتيب المصدر، سيظهر الزر باللون الأزرق.
[onclick] {
background: grey;
}
.my-button {
background: blue;
}
ويعود السبب في ذلك إلى أنّ كلا أداتَي الاختيار تتضمّنان التحديد نفسه. في هذه الحالة، يعود التسلسل إلى خطوة ترتيب الظهور.