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

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

Adam Argyle
Adam Argyle

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

قبل
.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 nesting يظهر مربّع أخضر ضمن هذا السؤال للإشارة إلى أنّ المشكلة تتيح الردّ.

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

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

  .no-nesting {
    display: none;
  }
}

استخدام @supports:

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

يملك زميلي براموس برنامجًا رائعًا للترميز يظهر فيه هذه الاستراتيجية.

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

إنّ الإمكانات الحالية في DevTools لاستخدام ميزة "التداخل" محدودة. في الوقت الحالي، ستلاحظ أنّه يتم تمثيل النمط في لوحة "الأنماط" على النحو المتوقّع، ولكن لا يمكن تتبُّع التداخل وسياق المحدّد الكامل. لدينا تصميمات وخطط لنجعل هذه العملية شفافة وواضحة.

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

من المخطّط أن يتضمّن الإصدار 113 من Chrome ميزات إضافية تتيح إدراج CSS. تابعونا لمعرفة أي جديد عنها.

المستقبل

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

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

في الختام، إليك عرض توضيحي يستخدِم @scope والتداخل و@layer معًا. كل شيء مثير للغاية!

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