CSS3 والتصميم المتجاوب

الأولوية والتتالي والوراثة

50 دقيقة الدرس 7 من 60

فهم التتالي

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

يقيّم التتالي التصريحات بناءً على أربعة معايير، حسب ترتيب الأولوية:

  1. المصدر والأهمية -- من أين يأتي النمط وهل هو مُعلّم بـ !important.
  2. الأولوية (Specificity) -- مدى دقة المحدد في استهداف العنصر.
  3. ترتيب الظهور -- عندما يكون لقاعدتين نفس الأولوية، تفوز القاعدة التي تظهر لاحقاً.
  4. الوراثة -- بعض الخصائص تنتقل من العناصر الأب إلى العناصر الأبناء.

مصدر أوراق الأنماط

ليست كل أوراق الأنماط متساوية. تستخدم المتصفحات أنماطاً من ثلاثة مصادر مختلفة، ولكل مصدر مستوى سلطة مختلف:

  • ورقة أنماط وكيل المستخدم (User-Agent) -- هذه هي الأنماط الافتراضية المدمجة في المتصفح. على سبيل المثال، تعرض المتصفحات عناصر <h1> بخط كبير وعريض وعناصر <a> باللون الأزرق مع خط سفلي افتراضياً. لكل متصفح افتراضيات مختلفة قليلاً، ولهذا يستخدم المطورون غالباً إعادة تعيين CSS أو أوراق أنماط التطبيع.
  • ورقة أنماط المستخدم -- هذه أنماط يحددها المستخدم، غالباً لأسباب تتعلق بإمكانية الوصول. قد يزيد المستخدم حجم الخط الأساسي أو يفرض ألواناً عالية التباين. نادراً ما تُصادف أوراق أنماط المستخدم في التطوير الحديث لكنها لا تزال موجودة في خوارزمية التتالي.
  • ورقة أنماط المؤلف -- هذه هي الأنماط التي تكتبها كمطور. أوراق الأنماط المرتبطة وكتل <style> المضمنة والأنماط المباشرة تندرج جميعها تحت مصدر المؤلف. أنماط المؤلف تتجاوز أنماط وكيل المستخدم افتراضياً.

في الظروف العادية، ترتيب الأولوية من الأدنى إلى الأعلى هو: وكيل المستخدم، المستخدم، المؤلف. لكن عند استخدام !important، ينعكس هذا الترتيب لتلك التصريحات -- سنغطي ذلك بالتفصيل لاحقاً.

الأولوية: جوهر حل تعارضات CSS

الأولوية هي نظام تسجيل نقاط يحدد أي قاعدة CSS لها الأسبقية عندما تستهدف قواعد متعددة من نفس المصدر نفس العنصر وتعيّن نفس الخاصية. لكل محدد قيمة أولوية يمكن حسابها. القاعدة ذات الأولوية الأعلى تفوز.

تُحسب الأولوية باستخدام أربع فئات، وتُمثّل غالباً كرقم من أربعة أجزاء (a، b، c، d):

  • الأنماط المباشرة (a) -- سمة النمط المباشر على العنصر لها أعلى أولوية. تُسجّل كـ 1,0,0,0 (أو ببساطة 1000 في الحساب المسطح).
  • محددات المعرّف (b) -- كل محدد معرّف (#header، #main-nav) يضيف 0,1,0,0 (أو 100) إلى نقاط الأولوية.
  • محددات الفئة والفئات الزائفة ومحددات السمات (c) -- كل فئة (.active) أو فئة زائفة (:hover، :first-child) أو محدد سمة ([type="text"]) يضيف 0,0,1,0 (أو 10) إلى النقاط.
  • محددات العناصر والعناصر الزائفة (d) -- كل نوع عنصر (div، p، h1) أو عنصر زائف (::before، ::after) يضيف 0,0,0,1 (أو 1) إلى النقاط.
ملاحظة: المحدد العام (*) والمُجمّعات (+، ~، >، المسافة) والفئة الزائفة :where() لها أولوية صفر. الفئتان الزائفتان :not() و :is() لا تضيفان أولوية بذاتهما، لكن وسائطهما تُحتسب.

أمثلة على حساب الأولوية

دعنا نستعرض عدة أمثلة لجعل حساب الأولوية ملموساً. فهم كيفية حساب الأولوية يدوياً سيوفر عليك ساعات من تتبع الأخطاء.

مثال: نقاط الأولوية الأساسية

/* الأولوية: 0,0,0,1 (محدد عنصر واحد) */
p {
    color: black;
}

/* الأولوية: 0,0,1,0 (محدد فئة واحد) */
.intro {
    color: blue;
}

/* الأولوية: 0,1,0,0 (محدد معرّف واحد) */
#main-title {
    color: red;
}

/* الأولوية: 1,0,0,0 (نمط مباشر) */
/* <p style="color: green;">هذا النص أخضر</p> */

في المثال أعلاه، إذا كانت فقرة تحمل الفئة intro والمعرّف main-title ولها أيضاً نمط مباشر، يفوز النمط المباشر لأنه يملك أعلى أولوية (1,0,0,0). أزل النمط المباشر وسيفوز محدد المعرّف. أزل المعرّف وستفوز الفئة. أزل الفئة وسيُطبّق محدد العنصر.

مثال: المحددات المركبة وأولويتها

/* الأولوية: 0,0,1,1 (فئة واحدة + عنصر واحد) */
p.highlight {
    color: orange;
}

/* الأولوية: 0,0,2,1 (فئتان + عنصر واحد) */
p.highlight.active {
    color: yellow;
}

/* الأولوية: 0,1,1,1 (معرّف واحد + فئة واحدة + عنصر واحد) */
div#content .intro {
    color: purple;
}

/* الأولوية: 0,1,2,2 (معرّف واحد + فئتان + عنصران) */
div#sidebar ul.nav-list .item {
    color: teal;
}

/* الأولوية: 0,0,1,3 (فئة واحدة + ثلاثة عناصر) */
header nav ul.main-menu {
    color: brown;
}

لحساب أولوية div#sidebar ul.nav-list .item: عُد المعرّفات (واحد: #sidebar) للعمود الثاني، عُد الفئات (اثنتان: .nav-list و .item) للعمود الثالث، وعُد محددات العناصر (اثنان: div و ul) للعمود الرابع. النتيجة هي 0,1,2,2.

مثال: الفئات الزائفة ومحددات السمات في الأولوية

/* الأولوية: 0,0,1,1 (فئة زائفة واحدة + عنصر واحد) */
a:hover {
    color: red;
}

/* الأولوية: 0,0,2,1 (فئة زائفة واحدة + محدد سمة واحد + عنصر واحد) */
input[type="email"]:focus {
    border-color: blue;
}

/* الأولوية: 0,0,1,2 (عنصر زائف + فئة واحدة) */
/* ملاحظة: ::before يُحسب كمحدد على مستوى العنصر */
.card::before {
    content: "";
}

/* الأولوية: 0,1,1,1 (معرّف واحد + فئة زائفة واحدة + عنصر واحد) */
#nav a:visited {
    color: gray;
}
نصيحة: عند تتبع مشاكل الأولوية، لا تحتاج لحفظ كل نقاط الأولوية. بدلاً من ذلك، تذكر هذا الترتيب البسيط: الأنماط المباشرة تتغلب على المعرّفات، والمعرّفات تتغلب على الفئات، والفئات تتغلب على العناصر. عندما يكون محددان على نفس المستوى، عُد كم محدداً من ذلك المستوى لدى كل منهما. الذي لديه أكثر يفوز.

تصريح !important

علامة !important هي طريقة لتجاوز جميع قواعد الأولوية العادية. عندما تضيف !important إلى تصريح، ينتقل ذلك التصريح إلى طبقة خاصة عالية الأولوية تتغلب على كل شيء ما عدا تصريحات !important الأخرى.

مثال: استخدام !important

/* تصريح عادي -- الأولوية 0,1,0,0 */
#header {
    background-color: white;
}

/* هذا يفوز رغم أن الأولوية أقل (0,0,1,0) */
/* لأن !important يتجاوز الأولوية العادية */
.dark-theme {
    background-color: black !important;
}

/* لتجاوز !important، تحتاج !important آخر
   بأولوية مساوية أو أعلى */
#header.dark-theme {
    background-color: #1a1a1a !important;
}

عندما تتنافس عدة تصريحات !important، تنطبق قواعد الأولوية العادية فيما بينها. هذا يخلق مشكلة تصاعد -- بمجرد أن تبدأ باستخدام !important، غالباً ما تحتاج المزيد من تصريحات !important لتجاوز الأولى، مما يؤدي إلى CSS غير قابل للصيانة.

تحذير: تجنب استخدام !important في أوراق الأنماط العادية. إنه يكسر تدفق التتالي الطبيعي ويجعل تتبع الأخطاء أصعب بكثير. الاستخدامات المشروعة لـ !important نادرة وتشمل: فئات المرافق في أطر عمل CSS (مثل .hidden { display: none !important; })، وتجاوز أنماط الأدوات الخارجية التي لا يمكنك تعديلها مباشرة، والتتبع المؤقت أثناء التطوير (أزله دائماً بعد ذلك). إذا وجدت نفسك تلجأ إلى !important، فهذا يعني غالباً أن بنية محدداتك تحتاج إلى إعادة هيكلة.

ترتيب الظهور

عندما يكون لتصريحين نفس المصدر ونفس الأهمية (كلاهما عادي أو كلاهما !important) ونفس الأولوية، يلجأ التتالي إلى ترتيب الظهور. التصريح الذي يظهر لاحقاً في الكود المصدري يفوز.

مثال: ترتيب الظهور يحل التعادل

/* كلاهما لهما الأولوية 0,0,1,0 */
.message {
    color: blue;
}

/* هذا يفوز لأنه يظهر لاحقاً */
.message {
    color: green;
}

/* نفس المبدأ ينطبق عبر أوراق الأنماط.
   إذا تم ربط styles.css قبل theme.css في HTML،
   فإن تصريحات theme.css تفوز عند تساوي الأولوية. */

/* في رأس HTML: */
/* <link rel="stylesheet" href="styles.css"> */
/* <link rel="stylesheet" href="theme.css"> */

لهذا السبب يتم تحميل إعادة تعيين CSS وأوراق أنماط التطبيع دائماً أولاً -- أنماطك المخصصة تأتي بعد ذلك وتتجاوز عمليات إعادة التعيين طبيعياً عندما تتساوى الأولوية. هذا المبدأ هو أيضاً السبب في أنه يجب عليك هيكلة أوراق الأنماط بعناية: الأنماط الأساسية وإعادة التعيين أولاً، ثم أنماط التخطيط، ثم أنماط المكونات، وأخيراً أنماط المرافق أو التجاوز. كل طبقة تُبنى على السابقة، والقواعد اللاحقة تأخذ الأسبقية طبيعياً عندما تتساوى الأولوية.

كيف تعمل خوارزمية التتالي الكاملة خطوة بخطوة

عندما يواجه المتصفح تعارضاً بين تصريحي CSS يستهدفان نفس الخاصية على نفس العنصر، يحل التعارض بالمرور عبر هذه الخطوات بالترتيب. أول خطوة تنتج فائزاً واضحاً تنهي العملية:

  1. الخطوة 1: مقارنة المصادر والأهمية. يتحقق المتصفح من مصدر كل تصريح (وكيل المستخدم أو المستخدم أو المؤلف) وما إذا كان أي منهما مُعلّماً بـ !important. أنماط المؤلف العادية تتغلب على أنماط المستخدم العادية التي تتغلب على أنماط وكيل المستخدم العادية. لكن !important تعكس هذا الترتيب: أنماط وكيل المستخدم المهمة تتغلب على أنماط المستخدم المهمة التي تتغلب على أنماط المؤلف المهمة. إذا كان التصريحان من نفس المصدر ولهما نفس مستوى الأهمية، انتقل إلى الخطوة 2.
  2. الخطوة 2: مقارنة الأولوية. يحسب المتصفح أولوية كل محدد باستخدام نظام (a، b، c، d) الموصوف أعلاه. التصريح ذو قيمة الأولوية الأعلى يفوز. إذا تساوت الأولويتان، انتقل إلى الخطوة 3.
  3. الخطوة 3: مقارنة ترتيب الظهور. التصريح الذي يظهر لاحقاً في ترتيب المصدر يفوز. هذا يشمل ترتيب أوراق الأنماط المرتبطة في <head> الخاص بـ HTML، والموقع داخل ورقة أنماط واحدة، وما إذا كان النمط في ملف خارجي أو كتلة <style> أو سمة نمط مباشر.

فهم هذه الخوارزمية بالكامل يعني أنه يمكنك التنبؤ بالضبط بأي نمط سيُطبق في أي موقف. هذا ما يميز المطورين الذين "يخمنون ويتحققون" مع CSS عن أولئك الذين يكتبون الأنماط بثقة.

مزالق الأولوية الشائعة وكيفية تجنبها

حتى المطورون ذوو الخبرة يقعون في فخاخ الأولوية. إليك أكثر المشاكل شيوعاً وحلولها:

المزلق 1: الإفراط في تأهيل المحددات. كتابة div#header بدلاً من #header فقط تضيف أولوية غير ضرورية. المعرّف فريد بالفعل -- إضافة نوع العنصر أمامه تجعل التجاوز لاحقاً أصعب دون تصعيد الأولوية أكثر. نفس الشيء ينطبق على a.nav-link عندما يكفي .nav-link وحده.

المزلق 2: التداخل العميق. كتابة محددات مثل .header .nav .nav-list .nav-item .nav-link تنشئ أولوية 0,0,5,0 بينما فئة واحدة مثل .nav-link (0,0,1,0) تستهدف نفس العنصر. التداخل العميق يجعل CSS هشاً وصعب التجاوز. كل فئة إضافية في السلسلة ترفع الحاجز لأي قاعدة مستقبلية تحتاج لتجاوزها.

المزلق 3: استخدام المعرّفات للتنسيق. محددات المعرّف لها أولوية 100، وهي عشرة أضعاف محدد الفئة. محدد معرّف واحد يتغلب على أي مجموعة من محددات الفئات (حتى 10 فئات). هذا يجعل الأنماط المبنية على المعرّفات صعبة التجاوز جداً دون اللجوء لمزيد من المعرّفات أو !important. أفضل الممارسات هي حجز المعرّفات لربط JavaScript واستخدام الفئات حصرياً للتنسيق.

المزلق 4: الأنماط المباشرة من JavaScript. عندما يضيف JavaScript أنماطاً عبر element.style.property = value، ينشئ أنماطاً مباشرة بأولوية 1000. لا يمكن تجاوزها إلا بأنماط مباشرة أخرى أو بـ !important في ورقة أنماط. إذا كنت بحاجة لتنسيق العناصر ديناميكياً، فكر في تبديل فئات CSS باستخدام JavaScript بدلاً من تعيين أنماط مباشرة.

الوراثة: تمرير الأنماط عبر شجرة DOM

الوراثة هي آلية تنتقل فيها بعض خصائص CSS تلقائياً من العنصر الأب إلى عناصره الأبناء عند تطبيقها عليه. هذه آلية منفصلة عن التتالي لكنها تعمل بجانبه. تمنعك الوراثة من الاضطرار لتعيين نفس الخاصية على كل عنصر -- يمكنك تعيين font-family على <body> وسترث جميع عناصر النص بداخله ذلك الخط.

الخصائص الموروثة مقابل غير الموروثة

ليست كل خصائص CSS ترث افتراضياً. القاعدة العامة هي: الخصائص المتعلقة بـ النص والطباعة تميل إلى الوراثة، بينما الخصائص المتعلقة بـ التخطيط ونموذج الصندوق لا ترث. إليك الخصائص الرئيسية في كل فئة:

الخصائص التي ترث افتراضياً:

  • color
  • font-family، font-size، font-weight، font-style
  • line-height، letter-spacing، word-spacing
  • text-align، text-indent، text-transform
  • visibility
  • cursor
  • list-style، list-style-type، list-style-position
  • direction

الخصائص التي لا ترث افتراضياً:

  • margin، padding، border
  • width، height، min-width، max-width
  • display
  • background وجميع خصائص الخلفية
  • position، top، right، bottom، left
  • float، clear
  • overflow
  • z-index
  • box-shadow، opacity
ملاحظة: فكر في الأمر بهذه الطريقة: لو ورث كل عنصر ابن border أو padding من أبيه، لبدت صفحتك فوضوية. لهذا لا ترث خصائص نموذج الصندوق. لكن لو اضطررت لتعيين color و font-family على كل فقرة وعنصر قائمة و span، لكانت كتابة CSS مملة للغاية. لهذا ترث خصائص الطباعة.

التحكم في الوراثة باستخدام الكلمات المفتاحية الخاصة

توفر CSS عدة كلمات مفتاحية خاصة تتيح لك التحكم صراحة في سلوك الوراثة لأي خاصية. هذه الكلمات المفتاحية قيم صالحة لكل خاصية CSS.

الكلمة المفتاحية inherit

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

مثال: فرض الوراثة باستخدام inherit

.parent {
    border: 2px solid #333;
    padding: 20px;
    color: darkblue;
}

/* الحدود لا ترث افتراضياً،
   لكن يمكننا فرض ذلك */
.child {
    border: inherit; /* الآن تطابق حدود الأب */
    padding: inherit; /* الآن تطابق حشوة الأب */
}

/* استخدام عملي: جعل الروابط ترث لون النص */
a {
    color: inherit; /* لون الرابط يطابق النص المحيط */
    text-decoration: underline;
}

الكلمة المفتاحية initial

الكلمة المفتاحية initial تعيد تعيين الخاصية إلى قيمتها الافتراضية كما هي محددة في مواصفات CSS -- وليس النمط الافتراضي للمتصفح لذلك العنصر، بل القيمة الأولية المطلقة المحددة في المواصفات. على سبيل المثال، القيمة الأولية لـ display هي inline (حتى لعناصر مثل <div> التي تنسقها المتصفحات كـ block).

مثال: استخدام initial لإعادة تعيين الخصائص

/* المتصفح يعطي h1 حجم خط كبير وعريض،
   لكن القيمة الأولية في المواصفات لـ font-size هي "medium" */
h1 {
    font-size: initial; /* يعاد التعيين إلى افتراضي المواصفات، وليس حجم h1 في المتصفح */
}

/* المتصفح يعطي div عرض display: block،
   لكن القيمة الأولية في المواصفات لـ display هي "inline" */
div.inline-box {
    display: initial; /* يصبح inline وليس block! */
}
تحذير: كن حذراً مع initial. إنها تعيد التعيين إلى القيمة الأولية في مواصفات CSS، وهي ليست نفس النمط الافتراضي للمتصفح لذلك العنصر. إذا أردت إعادة تعيين عنصر إلى الطريقة التي ينسقه بها المتصفح عادةً، استخدم revert بدلاً من ذلك.

الكلمة المفتاحية unset

الكلمة المفتاحية unset تعمل كـ inherit أو initial حسب الخاصية. إذا كانت الخاصية ترث طبيعياً (مثل color)، تتصرف unset مثل inherit. إذا كانت الخاصية لا ترث طبيعياً (مثل border)، تتصرف unset مثل initial.

مثال: الكلمة المفتاحية unset عملياً

.parent {
    color: navy;
    border: 3px solid red;
}

.child {
    color: unset;  /* color ترث، لذا هذا = inherit = navy */
    border: unset; /* border لا ترث، لذا هذا = initial = none */
}

/* نمط مفيد: إعادة تعيين جميع الأنماط على عنصر */
.reset-element {
    all: unset; /* يعيد تعيين كل خاصية بناءً على ما إذا كانت ترث أم لا */
}

الكلمة المفتاحية revert

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

مثال: العودة إلى افتراضيات المتصفح

/* لنفترض أن CSS الخاص بك أزال تنسيق القائمة */
ul {
    list-style: none;
    padding: 0;
    margin: 0;
}

/* لكن لقائمة محددة، تريد استعادة افتراضيات المتصفح */
ul.browser-default {
    list-style: revert;  /* تستعيد النقاط */
    padding: revert;     /* تستعيد حشوة المتصفح */
    margin: revert;      /* تستعيد هامش المتصفح */
}

/* revert ممتازة لإعادة تعيين مكونات محددة
   دون معرفة القيم الافتراضية الدقيقة للمتصفح */
.widget h2 {
    font-size: revert; /* حجم h2 الافتراضي في المتصفح */
    margin: revert;    /* هامش h2 الافتراضي في المتصفح */
}

خاصية all المختصرة

خاصية all هي اختصار يعيد تعيين كل خاصية CSS على العنصر (ما عدا direction و unicode-bidi). تقبل الكلمات المفتاحية inherit و initial و unset و revert. هذا مفيد للغاية لإنشاء مكونات معزولة أو إعادة تعيين أنماط الأدوات الخارجية.

مثال: استخدام خاصية all

/* إعادة تعيين كل شيء تماماً إلى افتراضيات المتصفح */
.isolated-component {
    all: revert;
}

/* إزالة جميع الأنماط الموروثة والافتراضية */
.clean-slate {
    all: unset;
}

/* فرض وراثة جميع الخصائص من الأب */
.mirror-parent {
    all: inherit;
}

تتبع مشاكل الأولوية عملياً

مشاكل الأولوية هي من أكثر أخطاء CSS شيوعاً. إليك منهجية منظمة لتشخيصها وإصلاحها:

  1. افتح أدوات المطور -- انقر بزر الفأرة الأيمن على العنصر واختر "فحص". لوحة الأنماط تعرض جميع القواعد التي تستهدف العنصر، مرتبة حسب الأولوية. القواعد المتجاوزة عليها خط يتوسطها.
  2. اقرأ الأنماط المشطوبة -- هذه هي التصريحات التي خسرت معركة الأولوية. أدوات المطور تظهر لك بالضبط أي قاعدة تفوز.
  3. احسب الأولوية -- عُد المعرّفات والفئات والعناصر في كل من المحدد الفائز والخاسر. الفائز يجب أن يكون لديه عدد أعلى.
  4. أصلح بأقل التغييرات -- بدلاً من إضافة !important، حاول إعادة هيكلة محدداتك. أضف فئة لزيادة الأولوية أو أزل محدداً أبوياً مفرط التحديد يسبب المشاكل.
نصيحة: منهجيات CSS الحديثة مثل BEM (كتلة-عنصر-معدّل) تحافظ عمداً على أولوية مسطحة باستخدام محددات فئة مفردة فقط. هذا يتجنب حروب الأولوية تماماً. اسم فئة مثل .card__title--highlighted محدد بأعراف التسمية وليس بتداخل المحددات. فكر في تبني منهجية تسمية للمشاريع الأكبر لمنع مشاكل الأولوية من البداية.

الأولوية في العالم الحقيقي: مثال تطبيقي

دعنا نستعرض سيناريو واقعياً. تخيل أنك تبني مكون تنقل. تكتب قاعدة نظيفة قائمة على الفئات لروابط التنقل. لكن لاحقاً، يضيف زميل في الفريق قاعدة أكثر تحديداً داخل محدد معرّف أبوي. أنماطك تتوقف فجأة عن العمل ولا تستطيع معرفة السبب. إليك كيف قد يبدو الكود:

مثال: تعارض أولوية واقعي

/* نمط المكون النظيف الخاص بك -- الأولوية 0,0,1,0 */
.nav-link {
    color: #333;
    text-decoration: none;
    padding: 8px 16px;
}

/* قاعدة زميلك في ملف مختلف -- الأولوية 0,1,1,1 */
#site-header nav .nav-link {
    color: blue;
    text-decoration: underline;
}

/* نمطك يخسر لأن 0,1,1,1 > 0,0,1,0 */
/* للإصلاح بدون !important، لديك عدة خيارات: */

/* الخيار أ: مطابقة الأولوية بإضافة سياق */
#site-header .nav-link {
    color: #333;
    text-decoration: none;
}

/* الخيار ب (أفضل): إعادة هيكلة قاعدة الزميل
   لاستخدام فئات فقط، فتكون القاعدتان على نفس المستوى */

/* الخيار ج (الأفضل): الاتفاق على اتفاقية فريق مثل BEM
   حيث تستخدم جميع المحددات فئات مفردة */

هذا السيناريو يوضح لماذا تستفيد الفرق من منهجيات CSS ومراجعة الكود. تعارضات الأولوية نادراً ما تكون حول من هو "المحق" -- إنها حول إنشاء أنماط متسقة يتبعها الفريق بأكمله. عندما يكتب الجميع محددات مسطحة قائمة على الفئات، تختفي تعارضات الأولوية بشكل أساسي.

تمرين 1: تحدي حساب الأولوية

احسب أولوية كل من المحددات التالية ورتبها من الأدنى إلى الأعلى أولوية. اكتب قيمة الأولوية الرباعية (a,b,c,d) لكل واحد:

  1. div p span
  2. .container .content p
  3. #main .content p
  4. nav ul li a:hover
  5. #sidebar .widget h3.title
  6. body #content div.article p.intro::first-line

بعد الحساب، أنشئ صفحة HTML بها فقرة واحدة لها معرّف وفئتان وموضوعة داخل عدة عناصر. اكتب ست قواعد CSS مختلفة تستهدف تلك الفقرة بألوان مختلفة. تحقق في متصفحك من أن القاعدة ذات الأولوية الأعلى تفوز.

تمرين 2: ممارسة الوراثة والكلمات المفتاحية

أنشئ صفحة HTML ببنية متداخلة: عنصر <div> أب يحتوي على <section> يحتوي على <p> بداخله <span>. طبّق color و border و font-family و padding و background-color على الـ <div> الخارجي. ثم لاحظ أي الخصائص ترثها العناصر المتداخلة. بعد ذلك، استخدم الكلمة المفتاحية inherit على <section> لفرض وراثة border و padding. استخدم initial على <p> لإعادة تعيين color و font-family. أخيراً، استخدم unset على <span> لجميع الخصائص الخمس ولاحظ ما إذا كانت كل خاصية ترث أم تعود إلى قيمتها الأولية. وثّق ملاحظاتك بإضافة تعليقات إلى CSS الخاص بك تشرح سلوك كل كلمة مفتاحية.

ES
Edrees Salih
منذ 15 ساعة

We are still cooking the magic in the way!