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;
}
أداة اختيار أرقام التعريف
يضيف محدِّد رقم التعريف
تحديدًا مشابهًا لرقم التعريف، ما يزيد مكوّن A
بمقدار 1،
ما دام يتم استخدام محدِّد رقم تعريف (#myID
) وليس محدِّد سمة ([id="myID"]
).
في المثال التالي، تكون الدقّة (1,0,0)
.
#myID {
color: red;
}
أدوات الاختيار الأخرى
تحتوي لغة CSS على العديد من أدوات الاختيار. ولا تضيف بعض هذه الكلمات مزيدًا من التحديد.
على سبيل المثال، لا تضيف الفئة الزائفة :not()
أيّ شيء إلى عملية احتساب النوعية.
ومع ذلك، تتم إضافة المحدّدات التي تم تمريرها كوسيطات إلى عملية احتساب النوعية.
div:not(.my-class) {
color: red;
}
لا تُضيف الفئة الزائفة [:is()](https://developer.mozilla.org/en-US/docs/Web/CSS/:is)
نفسها أيضًا إلى عملية احتساب النوعية. مثل :not()
، يأخذ
دقة الوسيطة الأكثر تحديدًا.
:is(h1, h2, h3) {
color: blue;
}
تبلغ نسبة دقة هذه العينة (0,0,1)
لأنّها تحتوي على نوع واحد فقط من
العناصر المحدّدة (type
).
مع إضافة id
، تزيد الدقّة إلى (1,0,0)
.
:is(h1, h2, h3, #my-heading) {
color: blue;
}
تكون الفئة الزائفة [:where()](https://developer.mozilla.org/docs/Web/CSS/:where)
مختلفة. بغض النظر عن النوعية المحدّدة لأيّ من وسيطاتها، تكون لها دائمًا
نوعية (0,0,0)
.
:where(h1, h2, h3, #my-heading) {
color: blue;
}
تتيح لك الأنماط ذات النوعية المنخفضة التي يتم تطبيقها باستخدام :where()
إلغاء هذه
الأنماط باستخدام أدوات اختيار أساسية في جدول الأنماط لاحقًا:
:where(#my-content) {
color: red;
}
p {
color: blue;
}
على الرغم من أنّ :where()
يحتوي على id
في قائمة الوسيطات، إلا أنّه لا يزال لديه
خصوصية (0, 0, 0)
فقط، لذا تلغي أداة الاختيار الأساسية p
ذلك وسيكون النص
blue
.
التحقّق من فهمك
اختبِر معلوماتك حول احتساب درجة النوعية
ما هي سمة 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,0)
، ما يجعل النوعية الإجمالية هي (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)
.
في حال تساوي درجة التحديد، يتم الرجوع إلى الخطوة التالية في التسلسل.
لنواصل استخدام مثال الزرّ، إليك تنسيق CSS الجديد:
.my-button {
background: blue;
}
[onclick] {
background: grey;
}
يحتوي الزر على خلفية رمادية،
لأنّ كلتا أداتَي الاختيار تتضمّنان درجة تحديد متطابقة تبلغ (0,1,0)
.
في حال تبديل القواعد بترتيب المصدر، سيظهر الزر باللون الأزرق.
[onclick] {
background: grey;
}
.my-button {
background: blue;
}
ويعود السبب في ذلك إلى أنّ كلا أداتَي الاختيار تتضمّنان التحديد نفسه. في هذه الحالة، يعود التسلسل إلى خطوة ترتيب الظهور.