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

ستتوفر طبقات التتالي (قاعدة @layer CSS) في الإصدار التجريبي 99 من Chromium وFirefox 97 وSafari 15.4 التجريبي. تتيح هذه الإعدادات التحكّم بشكل أكثر وضوحًا في ملفات 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 base,
       theme,
       layouts,
       components,
       utilities;

والآن، لن يكون الترتيب الذي @import به أنماطك مهمًا لترتيب الطبقات، لأنه قد تم إنشاؤه بالفعل في أول مثيل لاسم الطبقة. وهذا أمرٌ لا داعي للقلق بشأنه. لا يزال بإمكانك تعيين الملفات المستوردة إلى طبقات معينة، ولكن قد تم إنشاء الترتيب بالفعل.

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

الطبقات والشلال

لنعد خطوة إلى الوراء ونرى أين يتم استخدام الطبقات من حيث صلتها بالشلال الأوسع:

رسم بالتتالي

ويكون ترتيب الأسبقية على النحو التالي:

  • وكيل المستخدم العادي (الأولوية الأدنى)
  • مستخدم محلي @layer
  • مستخدم محلي عادي
  • المؤلف @Layers
  • المؤلف العادي
  • الكاتب مهم
  • المؤلف @layer !important
  • مستخدم محلي !مهم
  • وكيل المستخدم !important** (الأولوية القصوى)

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

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

يمكن أيضًا دمج الطبقات في الطبقات الأخرى. المثال التالي مأخوذ من شرح Cacade Layers من "ميريام سوزان":

@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 خصوصيتها. يوضح الرسم التخطيطي أعلاه هذا كمرجع: للمؤلف @layers أسبقية أقل من المؤلف العادي والذي له أولوية أقل من المؤلف !important الذي له أسبقية أقل من المؤلف @layers !مهم.

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

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

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

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

القاعدة الخامسة: انتبِه إلى طبيعة الخصوصية

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

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

لذلك إذا كنت تكتب فئات خدمات، فقم دائمًا بتضمينها كطبقة ترتيب أعلى من المكونات التي تنوي تجاوزها. قد تعتقد: "أضفت للتو صف .pink هذا لتغيير اللون ولا يتم تطبيقه".

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

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