ستصل الطبقات المتتالية إلى المتصفح

ستتوفّر طبقات التسلسل (قاعدة CSS @layer) في الإصدار 99 من Chromium والإصدار 97 من Firefox والإصدار التجريبي 15.4 من Safari. وتتيح لك هذه الميزة التحكّم بشكل أكثر وضوحًا في ملفات CSS لمنع حدوث تعارضات في خصوصية الأنماط. ويُعدّ ذلك مفيدًا بشكل خاص لقواعد البيانات الكبيرة وأنظمة التصميم وعند إدارة الأنماط التابعة لجهات خارجية في التطبيقات.

إنّ تقسيم ملفات CSS بطريقة واضحة يمنع إلغاء الأنماط غير المتوقّعة ويعزّز بنية CSS بشكل أفضل.

تحديد CSS والتسلسل

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

يلجأ المستخدمون إلى اصطلاحات تسمية CSS، مثل BEM، لمنع إلغاء التحديد عن غير قصد. من خلال منح كل عنصر فئة فئة واحدة، يتم وضع كل العناصر في مستوى التحديد نفسه. ومع ذلك، ليس من الممكن دائمًا الحفاظ على هذه الأنماط المنظَّمة، خاصةً عند العمل مع أنظمة الترميز والتصميم التابعة لجهات خارجية.

تمثيل بصري لطريقة BEM لبطاقة تتضمّن فئات
مثال توضيحي لتسمية BEM من keepinguptodate.com

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

على سبيل المثال، يتمتع المحدّد .post a.link بدرجة تحديد أعلى من .card a. إذا حاولت تصميم رابط داخل بطاقة في إحدى المشاركات، ستلاحظ أنّه سيتم تطبيق أداة الاختيار الأكثر تحديدًا.

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

صورة توضيحية من العرض التجريبي للمشروع لفصل واجهة المستخدم

@layer في العمل

عرض تجريبي يعرض ألوان الروابط مع عمليات الاستيراد
يمكنك الاطّلاع على العرض التوضيحي على Codepen.

يوضّح هذا المثال مدى فعالية الطبقات المتراكبة باستخدام @layer. هناك عدة روابط معروضة: بعضها بدون تطبيق أي أسماء فئات إضافية، وبعضها ينتمي إلى الفئة .link، وبعضها ينتمي إلى الفئة .pink. تضيف CSS بعد ذلك ثلاث طبقات: base وtypography وutilities على النحو التالي:

@layer base {
  a {
    font-weight: 800;
    color: red; /* ignored */
  }

  .link {
    color: blue; /* ignored */
  }
}

@layer typography {
  a {
    color: green; /* styles *all* links */
  }
}

@layer utilities {
  .pink {
    color: hotpink;  /* styles *all* .pink's */
  }
}

في النهاية، تكون جميع الروابط إما خضراء أو وردية. ويرجع ذلك إلى أنّه على الرغم من أنّ .link لها خصوصية أعلى على مستوى المحدّد من a، هناك نمط لون على a في @layer ذات الأولوية الأعلى. تلغي a { color: green } .link { color: blue } عندما تكون القاعدة الخضراء في طبقة بعد القاعدة الزرقاء.

تُعطى الأولوية للطبقة على العنصر الأكثر تحديدًا.

تنظيم الطبقات

يمكنك تنظيم الطبقات مباشرةً على الصفحة، كما هو موضّح أعلاه، أو يمكنك تنظيمها في أعلى الملف.

يتم تحديد ترتيب الطبقات حسب المرة الأولى التي يظهر فيها اسم كل طبقة في الرمز.

وهذا يعني أنّه في حال إضافة ما يلي إلى أعلى الملف، ستظهر جميع الروابط باللون الأحمر، وسيظهر الرابط الذي يحمل الفئة .link باللون الأزرق:

@layer utilities, typography, base;

ويعود السبب في ذلك إلى أنّه تم الآن عكس ترتيب الطبقات، ما يؤدي إلى وضع الخدمات أولاً والقاعدة في النهاية. وبالتالي، ستكون قواعد الأنماط في طبقة base دائمًا أكثر تحديدًا من قواعد الأنماط في طبقة الطباعة. لن تعود الروابط خضراء، بل ستكون حمراء أو زرقاء.

لقطة شاشة لمشروع Codepen
يمكنك الاطّلاع على العرض التوضيحي على Codepen.

تنظيم عمليات الاستيراد

هناك طريقة أخرى لاستخدام @layer وهي استخدام ملفات الاستيراد. يمكنك إجراء ذلك مباشرةً عند استيراد الأنماط، باستخدام دالة layer() كما هو موضّح في المثال التالي:

/* Base */
@import '../styles/base/normalize.css' layer(base); /* normalize or rest file */
@import '../styles/base/base.css' layer(base); /* body and base styles */
@import '../styles/base/theme.css' layer(theme); /* theme variables */
@import '../styles/base/typography.css' layer(theme); /* theme typography */
@import '../styles/base/utilities.css' layer(utilities); /* base utilities */

/* Layouts */
@import '../styles/components/post.css' layer(layouts); /* post layout */

/* Components */
@import '../styles/components/cards.css' layer(components); /* imports card */
@import '../styles/components/footer.css' layer(components); /* footer component */

يحتوي مقتطف الرمز أعلاه على ثلاث طبقات: base وlayouts وcomponents. ملفات المعالجة العادية والمظهر وأسلوب الخط في base، مع ملف post في layouts، وcards وfooter في components عند استيراد الملف، يتم إنشاء الطبقات باستخدام دالة layer. يمكن أيضًا تنظيم الطبقات في أعلى الملف، مع تحديدها قبل أي عمليات استيراد:

@layer base,
       theme,
       layouts,
       components,
       utilities;

الآن، لن يهمّ ترتيب @import أنماطك بالنسبة إلى ترتيب الطبقة، لأنّه سبق أن تم تحديده في أول نسخة من اسم الطبقة. لا داعي للقلق بعد الآن. سيظل بإمكانك ضبط الملفات المستورَدة على طبقات معيّنة، ولكنّ الترتيب قد تم تحديده مسبقًا.

لقطة شاشة من مشروع Codepen
استكشِف المشروع على Codepen.

الطبقات والعرض المتراكب

لنلقِ نظرة على مكان استخدام الطبقات في ما يتعلّق بالتسلسل الهرمي الأوسع نطاقًا:

صورة توضيحية للعرض المتراكب

ترتيب الأولوية هو على النحو التالي:

  • وكيل المستخدم العادي (أدنى أولوية)
  • مستخدم محلي @layer
  • المستخدم المحلي العادي
  • مؤلف ‎ @layers
  • المؤلف العادي
  • Author !important
  • Author @layer !important
  • مستخدم محلي !important
  • User Agent ‎!important** (أعلى أولوية)

قد تلاحظ هنا أنّ أنماط @layer !important مقلوبة. بدلاً من أن تكون أقل تحديدًا من الأنماط غير الطبقية (العادية)، يكون لها الأولوية الأعلى. ويرجع ذلك إلى طريقة عمل !important في التسلسل: فهو يوقف التسلسل العادي في أوراق الأنماط ويعكس التحديد العادي على مستوى الطبقة (الأولوية).

الطبقات المتداخلة

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

@layer default {
  p { max-width: 70ch; }
}

@layer framework {
  @layer default {
    p { margin-block: 0.75em; }
  }

  p { margin-bottom: 1em; }
}

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

@layer framework.default {
  p { margin-block: 0.75em }
}

الطبقات الناتجة وترتيب الطبقات هي:

  • التلقائية
  • framework.default
  • framework غير مُعدَّة
  • غير مُعدَّة

أمور يجب الانتباه إليها

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

القاعدة 1: لا تستخدِم @layer لتحديد النطاق

لا تؤدي الطبقات المتراكبة إلى حلّ مشكلة النطاق. إذا كان لديك ملف CSS يتضمّن @layer، مثل card.css، وأردت تطبيق نمط على جميع الروابط ضمن البطاقة، لا تكتب أنماطًا مثل:

a {
  
}

سيؤدي ذلك إلى تطبيق هذا الإجراء على جميع علامات a في ملفك. لا يزال من المهم تحديد نطاق أنماطك بشكل صحيح:

.card a {
  
}

القاعدة 2: يتم ترتيب طبقات التسلسل خلف صفحات CSS غير المُقسّمة إلى طبقات

يُرجى العلم أنّ ملف CSS المتعدّد الطبقات لن يحلّ محل ملف CSS غير المتعدّد الطبقات. لقد اتّخذنا هذا القرار عن قصد لتسهيل إدخال الطبقات بطريقة أكثر ملاءمةً للعمل مع قاعدة البيانات الحالية. على سبيل المثال، يُعدّ استخدام ملف reset.css نقطة بداية وحالة استخدام جيدةَين للطبقات المتراكبة.

القاعدة 3: !important تعكس مدى تحديد التسلسل

على الرغم من أنّ الأنماط المتعدّدة الطبقات أقل تحديدًا من الأنماط غير المتعدّدة الطبقات بشكل عام، فإنّ استخدام !important يعكس ذلك. في الطبقة، تكون البيانات التي تستخدم القاعدة !important أكثر تحديدًا من الأنماط غير المُدرَجة في طبقة.

في هذه الحالة، تعكس أنماط !important خصوصيتها. يوضّح المخطّط البياني أعلاه ذلك كمرجع: يكون لـ author @layers الأولوية أقل من author normal، ويكون لـ author normal الأولوية أقل من author !important، ويكون لـ author @layer !important الأولوية أقل من ذلك.

إذا كانت لديك طبقات متعددة، ستحظى الطبقة الأولى التي تحتوي على !important بالأولوية وستصبح النمط الأكثر تحديدًا.!important

القاعدة 4: فهم نقاط الحقن

بما أنّ ترتيب الطبقات يتم تحديده في المرة الأولى التي يظهر فيها اسم كل طبقة في الرمز البرمجي، يمكن تجاهل بيان @layer إذا تم وضعه بعد استيراد layer() وضبطه أو بعد بيان @layer مختلف. على عكس CSS، حيث يتم تطبيق قاعدة النمط في أسفل الصفحة على الطبقات المتسلسلة، يتم تحديد الترتيب في المرة الأولى.

ويمكن أن يكون ذلك في قائمة أو في كتلة طبقة أو في عملية استيراد. إذا وضعت @layer بعد قائمة استيراد تحتوي على layer()، لن يحدث أي شيء. سيؤدي وضعها في أعلى الملف إلى ضبط ترتيب الطبقات ومساعدتك في الاطّلاع بوضوح على الطبقات ضمن البنية.

القاعدة رقم 5: الانتباه إلى مدى التحديد

باستخدام الطبقات المتراكبة، سيحلّ أداة اختيار أقل تحديدًا (مثل a) محلّ أداة اختيار أكثر تحديدًا (مثل .link) إذا كانت أداة الاختيار الأقل تحديدًا موجودة في طبقة أكثر تحديدًا. ننصحك باتّباع الخطوات التالية:

ستلغي السمة a في layer(components) السمة .pink في layer(utilities) في الحالات التالية: إذا تم تحديد @layer utilities, components. على الرغم من أنّ هذا الإجراء جزء من واجهة برمجة التطبيقات، إلا أنّه قد يكون مربكًا ومخيبطًا إذا لم تكن تتوقعه.

لذلك، إذا كنت تكتب فئات أدوات، أدرِجها دائمًا كطبقة من ترتيب أعلى من المكونات التي تريد إلغاءها. قد تعتقد أنّك أضفت للتو فئة .pink لتغيير اللون ولكنّه لا يتم تطبيقه.

مزيد من المعلومات عن الطبقات المتراكبة

يمكنك أيضًا الاطّلاع على هذه المراجع لمعرفة المزيد عن الطبقات المتراكبة: