تداخل خدمة مقارنة الأسعار (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 في المثال السابق من المشروع، يمكنك حذف المجموعة بأكملها بدلاً من البحث في الملفات عن حالات المحدد ذات الصلة.

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

يتوفر التضمين من Chrome 112 ويمكنك أيضًا تجربته في المعاينة الفنية 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 */
}

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

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

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

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

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

المستقبل

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

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

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

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