تداخل خدمة مقارنة الأسعار (CSS)

إحدى الميزات المفضلة للمعالجات التمهيدية لـ CSS تم دمجها الآن في اللغة: قواعد النمط المتداخلة.

آدم أرجيل
آدم أرجيل

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

قبل
.nesting {
  color: hotpink;
}

.nesting > .is {
  color: rebeccapurple;
}

.nesting > .is > .awesome {
  color: deeppink;
}

بعد الدمج، يمكن متابعة أدوات الاختيار وتجميع قواعد النمط ذات الصلة بها ضمنها.

بعد
.nesting {
  color: hotpink;

  > .is {
    color: rebeccapurple;

    > .awesome {
      color: deeppink;
    }
  }
}

يمكنك تجربة هذا الإجراء في المتصفّح.

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

يمكن أن يساعد الدمج في ما يلي: - المؤسسة - تقليل حجم الملف - إعادة البناء

يتوفّر التداخل من الإصدار 112 من Chrome ويمكن أيضًا تجربة الإصدار 162 من المعاينة التقنية في Safari.

بدء استخدام دمج CSS

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

شبكة ملونة من الدوائر والمثلثات والمربعات الصغيرة والكبيرة.

يوجد داخل وضع الحماية الدوائر والمثلثات والمربعات. بعضها صغير أو متوسط أو كبير. والبعض الآخر باللون الأزرق أو الوردي أو الأرجواني. كل منها داخل العنصر الذي يحتوي على .demo. في ما يلي معاينة لعناصر HTML التي ستستهدفها.

<div class="demo">
  <div class="sm triangle pink"></div>
  <div class="sm triangle blue"></div>
  <div class="square blue"></div>
  <div class="sm square pink"></div>
  <div class="sm square blue"></div>
  <div class="circle pink"></div>
  …
</div>

أمثلة التداخل

يتيح لك تداخل CSS تحديد أنماط لأحد العناصر ضمن سياق أداة اختيار أخرى.

.parent {
  color: blue;

  .child {
    color: red;
  }
}

في هذا المثال، يتم دمج أداة اختيار الفئة .child في أداة اختيار الفئة .parent. وهذا يعني أنّ أداة اختيار .child المدمَجة سيتم تطبيقها فقط على العناصر الثانوية للعناصر التي تتضمّن فئة .parent.

بدلاً من ذلك، يمكن كتابة هذا المثال باستخدام الرمز & للإشارة بشكل صريح إلى المكان الذي يجب وضع الفئة الرئيسية فيه.

.parent {
  color: blue;

  & .child {
    color: red;
  }
}

هذان المثالان متكافئان من الناحية الوظيفية وسيصبح سبب حصولك على الخيارات أكثر وضوحًا مع استكشاف أمثلة أكثر تقدمًا في هذه المقالة.

تحديد الدوائر

بالنسبة لهذا المثال الأول، تتمثل المهمة في إضافة أنماط للتلاشي والتعتيم للدوائر فقط داخل العرض التوضيحي.

بدون إمكانية التداخل، توفّر خدمة CSS حاليًا ما يلي:

.demo .circle {
  opacity: .25;
  filter: blur(25px);
}

مع التداخل، هناك طريقتان صالحتان:

/* & is explicitly placed in front of .circle */
.demo {
  & .circle {
    opacity: .25;
    filter: blur(25px);
  }
}

أو

/* & + " " space is added for you */
.demo {
  .circle {
    opacity: .25;
    filter: blur(25px);
  }
}

النتيجة، تم تمويه جميع العناصر داخل .demo ضمن الفئة .circle وتصبح غير مرئية تقريبًا:

لم تعد شبكة الأشكال الملونة تحتوي على دوائر، بل أصبحت باهتة جدًا في الخلفية.
تجربة عرض توضيحي

تحديد أي مثلثات ومربعات

تتطلّب هذه المهمة اختيار عدة عناصر مدمَجة، تُسمّى أيضًا أداة اختيار المجموعة.

بدون ميزة التداخل، تتوفر خدمة CSS حاليًا بطريقتين:

.demo .triangle,
.demo .square {
  opacity: .25;
  filter: blur(25px);
}

أو يمكنك استخدام :is()

/* grouped with :is() */
.demo :is(.triangle, .square) {
  opacity: .25;
  filter: blur(25px);
}

مع التداخل، إليك طريقتين صالحتين:

.demo {
  & .triangle,
  & .square {
    opacity: .25;
    filter: blur(25px);
  }
}

أو

.demo {
  .triangle, .square {
    opacity: .25;
    filter: blur(25px);
  }
}

النتيجة، تبقى عناصر .circle فقط داخل .demo:

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

تحديد المثلّثات والدوائر الكبيرة

تتطلب هذه المهمة أداة اختيار مُركّبة، حيث يجب أن تحتوي العناصر على الفئتَين من أجل اختيارها.

بدون إمكانية التداخل، توفّر خدمة CSS حاليًا ما يلي:

.demo .lg.triangle,
.demo .lg.square {
  opacity: .25;
  filter: blur(25px);
}

أو

.demo .lg:is(.triangle, .circle) {
  opacity: .25;
  filter: blur(25px);
}

مع التداخل، إليك طريقتين صالحتين:

.demo {
  .lg.triangle,
  .lg.circle {
    opacity: .25;
    filter: blur(25px);
  }
}

أو

.demo {
  .lg {
    &.triangle,
    &.circle {
      opacity: .25;
      filter: blur(25px);
    }
  }
}

النتيجة، تكون كل المثلثات والدوائر الكبيرة مخفية داخل .demo:

تحتوي الشبكة الملونة على أشكال صغيرة ومتوسطة فقط مرئية.
تجربة عرض توضيحي
نصيحة احترافية بشأن أدوات الاختيار المُركّبة والدمج

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

.demo {
  .lg {
    .triangle,
    .circle {
      opacity: .25;
      filter: blur(25px);
    }
  }
}

وعلى الرغم من أنّها طريقة صالحة للدمج، لن تتطابق النتائج مع العناصر التي قد تتوقعها. السبب هو أنّه بدون تحديد & للناتج المطلوب لـ .lg.triangle, .lg.circle مجمّعًا، ستكون النتيجة الفعلية هي .lg .triangle, .lg .circle، وهي أدوات اختيار تابعة.

تحديد جميع الأشكال باستثناء الأشكال الوردية

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

بدون إمكانية التداخل، توفّر خدمة CSS حاليًا ما يلي:

.demo :not(.pink) {
  opacity: .25;
  filter: blur(25px);
}

مع التداخل، إليك طريقتين صالحتين:

.demo {
  :not(.pink) {
    opacity: .25;
    filter: blur(25px);
  }
}

أو

.demo {
  & :not(.pink) {
    opacity: .25;
    filter: blur(25px);
  }
}

النتيجة، يتم إخفاء جميع الأشكال غير الوردية داخل .demo:

أصبحت الشبكة الملونة الآن أحادية اللون، وتعرض فقط الأشكال الوردية.
تجربة عرض توضيحي
الدقة والمرونة باستخدام &

لنفترض أنّك تريد استهداف .demo باستخدام أداة الاختيار :not(). & مطلوبة لإجراء ذلك:

.demo {
  &:not() {
    ...
  }
}

يؤدي هذا إلى تركيب .demo و:not() إلى .demo:not()، على عكس المثال السابق الذي كان يحتاج إلى .demo :not(). يكون هذا التذكير مهمًا جدًا عند الرغبة في دمج تفاعل :hover.

.demo {
  &:hover {
    /* .demo:hover */
  }

  :hover {
    /* .demo :hover */
  }
}

المزيد من أمثلة التداخل

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

في ما يلي بعض الأمثلة التي سنتناولها باختصار ميزة تداخل CSS، وذلك لمساعدتك على فهم اتساع الإمكانات التي توفّرها هذه الميزة.

تضمين @media

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

لتسهيل البنية، إذا كان استعلام الوسائط المدمج يعدِّل الأنماط لسياق المحدِّد الحالي فقط، يمكن استخدام بناء جملة مبسَّط.

.card {
  font-size: 1rem;

  @media (width >= 1024px) {
    font-size: 1.25rem;
  }
}

يمكن أيضًا استخدام السمة & بشكل صريح:

.card {
  font-size: 1rem;

  @media (width >= 1024px) {
    &.large {
      font-size: 1.25rem;
    }
  }
}

يوضّح هذا المثال البنية الموسّعة باستخدام &، مع استهداف بطاقات .large أيضًا لتوضيح أنّ ميزات التداخل الإضافية تواصل عملها.

مزيد من المعلومات حول دمج @rules

التضمين في أي مكان

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

.card {
  .featured & {
    /* .featured .card */
  }
}

يمثّل الرمز & مرجعًا لكائن أداة اختيار (وليس سلسلة) ويمكن وضعه في أي مكان في أداة اختيار مدمَجة. يمكن وضعها عدة مرات:

.card {
  .featured & & & {
    /* .featured .card .card .card */
  }
}

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

أمثلة التداخل غير الصالحة

هناك عدد قليل من سيناريوهات بناء الجملة المتداخلة غير الصالحة والتي قد تفاجئك إذا كنت تستخدم المعالجات التمهيدية.

الدمج والتسلسل

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

.card {
  &--header {
    /* is not equal to ".card--header" */
  }
}

ويمكن العثور على شرح أكثر تفصيلاً في المواصفات.

مثال على التداخل الصعب

التضمين ضمن قوائم أداة الاختيار و:is()

ضع في الاعتبار كتلة CSS المتداخلة التالية:

.one, #two {
  .three {
    /* some styles */
  }
}

هذا هو المثال الأول الذي يبدأ بقائمة أداة اختيار ثم يستمر في تضمين المزيد. انتهت الأمثلة السابقة فقط بقائمة أدوات اختيار. ليس هناك أي شيء غير صالح في مثال التداخل هذا، ولكن هناك تفاصيل تنفيذ قد تكون صعبة بشأن التداخل داخل قوائم المحددات، لا سيما تلك التي تتضمن محدد أرقام التعريف.

لكي يعمل التداخل، سيتم دمج أي قائمة محددات لا تتضمن أكبر قدر من التداخل مع :is() بواسطة المتصفح. ويحافظ هذا الالتفاف على تجميع قائمة أداة الاختيار داخل أي سياقات مؤلفة. يتمثل التأثير الجانبي لهذه التجميع، :is(.one, #two)، في اعتماد خصوصية أعلى نتيجة ضمن أدوات الاختيار داخل الأقواس. هذه هي الطريقة التي يعمل بها :is() دائمًا، ولكن قد يكون ذلك مفاجأة عند استخدام البنية المتداخلة لأنها ليست بالضبط ما تمت كتابته. ملخّص الحيلة: يمكن أن يؤدي التداخل مع أرقام التعريف وقوائم أدوات الاختيار إلى استخدام أدوات اختيار عالية الدقة.

لتلخيص المثال الصعب بوضوح، سيتم تطبيق كتلة التداخل السابقة على المستند على النحو التالي:

:is(.one, #two) .three {
  /* some styles */
}

انتبِه أو علِّم مستخدمي القائمة تحذيرهم عند التداخل داخل قائمة محدّد تستخدم محدّد الهوية، حيث ستكون خصوصية كل التداخل داخل قائمة المحددات عالية.

الخلط بين التداخل والإعلانات

ضع في الاعتبار كتلة CSS المتداخلة التالية:

.card {
  color: green;
  & { color: blue; }
  color: red;
}

سيكون لون عناصر .card هو blue.

يتم رفع أي تصريحات ذات نمط مختلط إلى الأعلى، كما لو كانت قد تمت كتابتها قبل حدوث أي تداخل. ويمكن الاطّلاع على مزيد من التفاصيل في المواصفات.

هناك طرق حوله. يلتف ما يلي بأنماط الألوان الثلاثة في &، والذي يحافظ على الترتيب التتاليي كما قصده المؤلف. سيكون لون عناصر .card باللون الأحمر.

.card {
  color: green;
  & { color: blue; }
  & { color: red; }
}

في الواقع، من المستحسن لف أي أنماط تتبع التداخل مع &.

.card {
  color: green;

  @media (prefers-color-scheme: dark) {
    color: lightgreen;
  }

  & {
    aspect-ratio: 4/3;
  }
}

اكتشاف الميزات

هناك طريقتان رائعتان لاكتشاف تداخل CSS: استخدام التداخل أو استخدام @supports للتحقق من إمكانية تحليل أداة الاختيار المتداخلة.

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

استخدام التداخل:

html {
  .has-nesting {
    display: block;
  }

  .no-nesting {
    display: none;
  }
}

باستخدام @supports:

@supports (selector(&)) {
  /* nesting parsing available */
}

لدى زميلي براموس برنامج Codepen رائع يعرض هذه الاستراتيجية.

تصحيح الأخطاء باستخدام "أدوات مطوري البرامج في Chrome"

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

لقطة شاشة لبنية التداخل في &quot;أدوات مطوري البرامج في Chrome&quot;

يخطط Chrome 113 للحصول على دعم إضافي لتداخل CSS. واظب على متابعتنا.

المستقبل

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

يشكّل الدمج تحسينًا كبيرًا للغة CSS. وله تداعيات متعلقة بالكتابة على كل جانب معماري في CSS تقريبًا. يجب استكشاف هذا التأثير الكبير وفهمه بعمق قبل تحديد الإصدار 2 بشكل فعال.

وأخيرًا، إليك عرض توضيحي يستخدم @scope والدمج و@layer معًا. الأمر كله مثير للغاية!

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