EduFlow
إتقان CSS الحديثة
⁦0%⁩

الوحدة 1 · الـ Cascade كما هو فعلًا

كيف يختار المتصفّح القاعدة الفائزة

14 دقراءة 4 د

الدرس في لمحة

اشرح الترتيب الذي يحسم به المتصفّح التصريحات المتنافسة، لتتوقّع القاعدة الفائزة قبل أن تفتح DevTools.

  1. 1الصفحة التي ستبنيها
  2. 2الـ cascade خطوة بخطوة
  3. 3حين لا يفوز أحد

لا فيديو هنا، بل الشيء الحقيقي: درس مكتوب وأمثلة قابلة للتشغيل واختبار وتدريب.

كل خطأ في CSS يجعلك تقول «لكنني كتبت هذه القاعدة!» له السبب الجذري نفسه: أكثر من تصريح (declaration) أراد الخاصية نفسها على العنصر نفسه، فاختار المتصفّح غير الذي اخترته أنت. المتصفّح لا يتصرّف عشوائيًا؛ إنه ينفّذ خوارزمية ترتيب ثابتة اسمها الـ cascade (التتالي)، وحين تستطيع تشغيلها في رأسك تتوقّف CSS عن أن تبدو لعبة «اضرب الخُلد» التي لا تنتهي.

هذه الدورة تعلّمك CSS من جهة المتصفّح. ستتعلّم ما تفعله كل ميزة حديثة، وستتعلّم أيضًا لماذا يتصرّف المتصفّح بهذه الطريقة، لأن هذا بالضبط ما يتيح لك توقّع النتيجة قبل أن تعيد تحميل الصفحة.

الصفحة التي ستبنيها

على طول الدورة ستحسّن صفحة حقيقية واحدة: جدول Waypoint Conf 2026، وهو مؤتمر للواجهات الأمامية يمتد يومين. فيها رأس صفحة ثابت (sticky)، وشريط فلاتر بمربّعات اختيار للمسارات، وبطاقات للجلسات (الوقت والعنوان والمتحدّث والقاعة وشارة المسار)، وشبكة للمتحدّثين بصورهم، ووضع داكن. تبدأ الصفحة بـ CSS بسيطة ومكسورة قليلًا، وفي النهاية تستخدم الـ layers والـ container queries وألوان oklch() والـ view transitions ومعمارية يستطيع فريق من خمسة أشخاص أن يتشاركها.

هذا أول تعارض ستقابله فيها:

HTML
<article class="session" id="keynote">
  <h2 class="session-title">Keynote: The Platform Is the Framework</h2>
</article>
CSS
#keynote h2 { color: #6d28d9; }
.session .session-title { color: #1f2937; }

القاعدة الثانية تأتي لاحقًا، لذا يتوقّع كثيرون أن يكون العنوان رماديًا داكنًا. لكنه بنفسجي. ولتفهم السبب تحتاج إلى معرفة ترتيب الفرز.

الـ cascade خطوة بخطوة

حين تستهدف عدّة تصريحات الخاصية نفسها على العنصر نفسه، يرتّبها المتصفّح وفق المعايير التالية بالترتيب، ويتوقّف عند أول معيار يفرّق بينها:

خمس خطوات متراصّة: المصدر والأهمية، النمط المضمّن، طبقات الـ cascade، الـ specificity، ترتيب الظهور. يمرّ سهم نزولًا عبرها، وأول خطوة تفرّق بين تصريحين تحسم الفائز. 1. المصدر والأهمية 2. السمة style المضمّنة 3. طبقات الـ cascade (@layer) 4. الـ Specificity 5. ترتيب الظهور تعادل؟ انزل خطوة
يقارن الـ cascade التصريحات معيارًا بعد معيار ويتوقّف عند أول اختلاف
  1. المصدر والأهمية. تأتي التصريحات من ملف الأنماط الافتراضي في المتصفّح (user-agent)، أو من المستخدم (إعدادات إمكانية الوصول والإضافات)، أو منك أنت (author). قواعدك العادية تتغلّب على افتراضيات المتصفّح. و!important تقلب الترتيب، فتتغلّب قاعدة المستخدم المهمّة على قاعدتك. وهذا مقصود: من يحتاج إلى نص كبير يجب أن يستطيع تجاوز تصميمك.
  2. الأنماط المضمّنة. السمة style="…" على العنصر تتغلّب على أيّ selector في ملف الأنماط. (في المواصفة خطوة أخرى قبل هذه مباشرةً تخصّ عزل الـ Shadow DOM، ولا تهمّك إلا حين تبني web components.)
  3. طبقات الـ cascade. القواعد في الـ @layer المُعلَنة لاحقًا تتغلّب على القواعد في الطبقات الأسبق، بغضّ النظر عن الـ specificity. ستستخدم هذا في درس طبقات الـ Cascade باستخدام @layer.
  4. الـ Specificity (درجة التحديد). مدى دقّة الـ selector في استهداف العنصر. الـ IDs تتغلّب على الـ classes، والـ classes تتغلّب على أنواع العناصر.
  5. ترتيب الظهور. إن تعادل كل ما سبق، يفوز التصريح الذي يظهر أخيرًا.

لنعد إلى الـ keynote: كلتا القاعدتين من أنماطك العادية، ولا إحداهما مضمّنة، ولا إحداهما داخل layer. إذن الخطوة 4 هي التي تحسم. #keynote h2 يحتوي على ID، و.session .session-title لا يحتوي إلا على classes، وID واحد يتفوّق على أيّ عدد من الـ classes. البنفسجي يفوز، والترتيب لا يُستشار أصلًا.

حين لا يفوز أحد

أحيانًا لا يستهدف أيّ تصريح خاصيةً ما على الإطلاق. لكن المتصفّح يحتاج إلى قيمة رغم ذلك، فيلجأ إلى الافتراضي: الخصائص الموروثة مثل color وfont-family وline-height تنسخ قيمة العنصر الأب، والخصائص غير الموروثة مثل border وpadding وbackground-color تأخذ قيمتها الابتدائية. لهذا فإن ضبط font-family على body ينسّق الصفحة كلها، بينما ضبط padding على body يضيف حشوة إلى الـ body وحده.

الدرس التالي يفكّك الخطوة 4: كيف تُحسب الـ specificity، ولماذا يستطيع ID واحد أن يخرّب مكتبة components كاملة، وكيف يتيح لك :is() و:where() أن تختار بدقّة الوزن الذي يحمله الـ selector.

أهم النقاط

  • يرتّب الـ cascade التصريحات المتنافسة حسب المصدر والأهمية، ثم الأنماط المضمّنة (inline)، ثم الـ layers، ثم الـ specificity، وبعد ذلك فقط حسب ترتيب الظهور في الكود.
  • ترتيب الظهور هو آخر وسيلة لكسر التعادل لا أوّلها، لذا فإن نقل القاعدة إلى أسفل الملف يصلح أخطاء أقل بكثير مما يتوقّعه الناس.
  • حين لا يستهدف أيّ تصريح خاصيةً ما، يلجأ المتصفّح إلى الوراثة في الخصائص الموروثة، وإلى القيمة الابتدائية في بقية الخصائص.
  • !important تعكس ترتيب المصادر: قاعدة المستخدم المهمّة تتغلّب على قاعدة المطوّر المهمّة.

قراءات إضافية

تحقّق من فهمك

3 أسئلة

السؤال 1 من 3

قاعدتان في ملف الأنماط نفسه تستهدفان العنصر <h2 class="session-title"> نفسه. أيّ لون سيأخذ؟

CSS
.session-title { color: teal; }
h2 { color: crimson; }
السؤال 2 من 3

فقرة داخل .card ليس لها قاعدة color خاصة بها، و.card تضبط color: navy. ما اللون الذي تأخذه الفقرة؟

السؤال 3 من 3

ما الخطوة التي يفحصها المتصفّح أولًا حين يتنافس تصريحان؟