تداخل خدمة مقارنة الأسعار (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 Nesting

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

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

داخل الصندوق الرمّل، هناك دوائر ومثلثات ومربّعات. وبعضها صغير أو متوسط أو كبير. أما الألوان الأخرى، فهي الأزرق أو الوردي أو الأرجواني. وجميعها داخل العنصر .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 */
}

يعرض زميلي براموس رمزًا رائعًا في Codepen يوضّح هذه الاستراتيجية.

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

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

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

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

المستقبل

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

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

في الختام، إليك عرض توضيحي يستخدِم @scope والتداخل و@layer معًا. هذا أمر مشوّق للغاية.

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