المساعدة في اختيار بنية لتداخل CSS

تحتاج إلى مساعدتنا في تحديد أي من الصيغتَين المتنافستَين يجب أن تصبح مرشحة للاعتماد في المواصفة.

Adam Argyle
Adam Argyle
Miriam Suzanne
Miriam Suzanne

تداخل CSS هو إضافة بنية لتسهيل إضافة CSS داخل قاعدة قواعد. إذا كنت قد استخدمت SCSS أو Less أو Stylus، بالتأكيد صادفت بعض النكهات من ذلك:

.nesting {
  color: hotpink;

  > .is {
    color: rebeccapurple;

    > .awesome {
      color: deeppink;
    }
  }
}

وبعد تجميعه إلى ملف CSS عادي بواسطة المعالج المُسبَق، يتحول إلىملف CSS عادي على النحو التالي:

.nesting {
  color: hotpink;
}

.nesting > .is {
  color: rebeccapurple;
}

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

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

لماذا لا يمكن أن يكون مثال التداخل الدقيق المعروض أعلاه هو بنية تداخل CSS؟

هناك بضعة أسباب تمنع استخدام بنية التعلّق الأكثر شيوعًا كما هي:

  1. التحليل غير الواضح
    يمكن لبعض المحدّدات المُدمجة أن تبدو تمامًا مثل السمات وأدوات المعالجة المُسبَقة التي يمكنها حلّها وإدارتها في وقت التصميم. لن تتوفّر لمحرّكات المتصفّحات الميزات نفسها، ويجب عدم تفسير أدوات الاختيار بشكل فضفاض.

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

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

نظرة عامة على ما تتم المقارنة بينه

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

الخيار 1: ‎@nest

هذه هي البنية المحدّدة حاليًا في CSS Nesting 1. ويقدّم هذا العنصر طريقة ملائمة لتداخل إضافة الأنماط من خلال بدء عناصر اختيار متداخلة جديدة باستخدام &. ويقدّم أيضًا @nest كطريقة لوضع سياق & في أيّ مكان داخل أداة اختيار جديدة، مثل عندما لا تكون بصدد إلحاق مواضيع فقط. إنّ هذا الإجراء مرن وبسيط، ولكن عليك تذكُّر @nest أو & حسب حالة الاستخدام.

الخيار 2: @nest محظور

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

الخيار 3: الأقواس

لتجنّب استخدام بنية نحوية مزدوجة أو مزيد من الازدحام في @nest الاقتراحات، اقترحت ميريام سوزان وإليكا إتمام بنية نحوية بديلة تعتمد بدلاً من ذلك على الأقواس المتعرجة الإضافية. يضمن ذلك وضوحًا في البنية، باستخدام حرفَين إضافيَين فقط، وبدون استخدام قواعد at-rules جديدة. ويسمح أيضًا بتجميع القواعد المُدمَجة حسب نوع الدمج المطلوب، وذلك لتسهيل استخدام محدِّدات متعدّدة مُدمَجة بالطريقة نفسها.

المثال 1: التداخل المباشر

‎@nest

.foo {
  color: #111;

  & .bar {
    color: #eee;
  }
}

@nest always

.foo {
  color: #111;

  @nest & .bar {
    color: #eee;
  }
}

الأقواس

.foo {
  color: #111;

  {
    & .bar {
      color: #eee;
    }
  }
}

خدمة مقارنة الأسعار (CSS) المكافئة

.foo {
  color: #111;
}

.foo .bar {
  color: #eee;
}

المثال 2: التداخل المركب

‎@nest

.foo {
  color: blue;

  &.bar {
    color: red;
  }
}

@nest always

.foo {
  color: blue;

  @nest &.bar {
    color: red;
  }
}

الأقواس

.foo {
  color: blue;

  {
    &.bar {
      color: red;
    }
  }
}

خدمة مقارنة الأسعار (CSS) المكافئة

.foo {
  color: blue;
}

.foo.bar {
  color: red;
}

المثال 3: قوائم وعمليات دمج بين المحدّدات

‎@nest

.foo, .bar {
  color: blue;

  & + .baz,
  &.qux {
    color: red;
  }
}

@nest always

.foo, .bar {
  color: blue;

  @nest & + .baz,
  &.qux {
    color: red;
  }
}

الأقواس

.foo, .bar {
  color: blue;

  {
    & + .baz,
    &.qux {
      color: red;
    }
  }
}

خدمة مقارنة الأسعار (CSS) المكافئة

.foo, .bar {
  color: blue;
}

:is(.foo, .bar) + .baz,
:is(.foo, .bar).qux {
  color: red;
}

المثال 4: مستويات متعدّدة

‎@nest

figure {
  margin: 0;

  & > figcaption {
    background: lightgray;

    & > p {
      font-size: .9rem;
    }
  }
}

@nest always

figure {
  margin: 0;

  @nest & > figcaption {
    background: lightgray;

    @nest & > p {
      font-size: .9rem;
    }
  }
}

الأقواس

figure {
  margin: 0;

  {
    & > figcaption {
      background: lightgray;

      {
        & > p {
          font-size: .9rem;
        }
      }
    }
  }
}

خدمة مقارنة الأسعار (CSS) المكافئة

figure {
  margin: 0;
}

figure > figcaption {
  background: hsl(0 0% 0% / 50%);
}

figure > figcaption > p {
  font-size: .9rem;
}

المثال 5: تداخل العنصر الرئيسي أو تغيير الموضوع

‎@nest

.foo {
  color: red;

  @nest .parent & {
    color: blue;
  }
}

@nest always

.foo {
  color: red;

  @nest .parent & {
    color: blue;
  }
}

الأقواس

.foo {
  color: red;

  {
    .parent & {
      color: blue;
    }
  }
}

خدمة مقارنة الأسعار (CSS) المكافئة

.foo {
  color: red;
}

.parent .foo {
  color: blue;
}

المثال 6: مزج التداخل المباشر والرئيسي

‎@nest

.foo {
  color: blue;

  @nest .bar & {
    color: red;

    &.baz {
      color: green;
    }
  }
}

@nest always

.foo {
  color: blue;

  @nest .bar & {
    color: red;

    @nest &.baz {
      color: green;
    }
  }
}

الأقواس

.foo {
  color: blue;

  {
    .bar & {
      color: red;

      {
        &.baz {
          color: green;
        }
      }
    }
  }
}

خدمة مقارنة الأسعار (CSS) المكافئة

.foo {
  color: blue;
}

.bar .foo {
  color: red;
}

.bar .foo.baz {
  color: green;
}

المثال 7: تداخل طلبات البحث عن الوسائط

‎@nest

.foo {
  display: grid;

  @media (width => 30em) {
    grid-auto-flow: column;
  }
}

أو بشكل صريح / موسّع

.foo {
  display: grid;

  @media (width => 30em) {
    & {
      grid-auto-flow: column;
    }
  }
}

@nest always (is always explicit)

.foo {
  display: grid;

  @media (width => 30em) {
    @nest & {
      grid-auto-flow: column;
    }
  }
}

الأقواس

.foo {
  display: grid;

  @media (width => 30em) {
    grid-auto-flow: column;
  }
}

أو بشكل صريح / موسّع

.foo {
  display: grid;

  @media (width => 30em) {
    & {
      grid-auto-flow: column;
    }
  }
}

خدمة مقارنة الأسعار (CSS) المكافئة

.foo {
  display: grid;
}

@media (width => 30em) {
  .foo {
    grid-auto-flow: column;
  }
}

المثال 8: تداخل المجموعات

‎@nest

fieldset {
  border-radius: 10px;

  &:focus-within {
    border-color: hotpink;
  }

  & > legend {
    font-size: .9em;
  }

  & > div {
    & + div {
      margin-block-start: 2ch;
    }

    & > label {
      line-height: 1.5;
    }
  }
}

@nest always

fieldset {
  border-radius: 10px;

  @nest &:focus-within {
    border-color: hotpink;
  }

  @nest & > legend {
    font-size: .9em;
  }

  @nest & > div {
    @nest & + div {
      margin-block-start: 2ch;
    }

    @nest & > label {
      line-height: 1.5;
    }
  }
}

الأقواس

fieldset {
  border-radius: 10px;

  {
    &:focus-within {
      border-color: hotpink;
    }
  }

  > {
    legend {
      font-size: .9em;
    }

    div {
      + div {
        margin-block-start: 2ch;
      }

      > label {
        line-height: 1.5;
      }
    }}
  }
}

خدمة مقارنة الأسعار (CSS) المكافئة

fieldset {
  border-radius: 10px;
}

fieldset:focus-within {
  border-color: hotpink;
}

fieldset > legend {
  font-size: .9em;
}

fieldset > div + div {
  margin-block-start: 2ch;
}

fieldset > div > label {
  line-height: 1.5;
}

المثال 9: مجموعة تعشيب معقّدة "حوض المطبخ"

‎@nest

dialog {
  border: none;

  &::backdrop {
    backdrop-filter: blur(25px);
  }

  & > form {
    display: grid;

    & > :is(header, footer) {
      align-items: flex-start;
    }
  }

  @nest html:has(&[open]) {
    overflow: hidden;
  }
}

@nest always

dialog {
  border: none;

  @nest &::backdrop {
    backdrop-filter: blur(25px);
  }

  @nest & > form {
    display: grid;

    @nest & > :is(header, footer) {
      align-items: flex-start;
    }
  }

  @nest html:has(&[open]) {
    overflow: hidden;
  }
}

الأقواس

dialog {
  border: none;

  {
    &::backdrop {
      backdrop-filter: blur(25px);
    }

    & > form {
      display: grid;

      {
        & > :is(header, footer) {
          align-items: flex-start;
        }
      }
    }
  }

  {
    html:has(&[open]) {
      overflow: hidden;
    }
  }
}

خدمة مقارنة الأسعار (CSS) المكافئة

dialog {
  border: none;
}

dialog::backdrop {
  backdrop-filter: blur(25px);
}

dialog > form {
  display: grid;
}

dialog > form > :is(header, footer) {
  align-items: flex-start;
}

html:has(dialog[open]) {
  overflow: hidden;
}

حان وقت التصويت

نأمل أن تكون هذه مقارنة عادلة ومجموعة نماذج من خيارات نحو التي نُقيّمها. يُرجى مراجعتها بعناية وإعلامنا بالطريقة التي تفضّلها أدناه. نشكرك على مساعدتنا في تطوير بنية CSS لتكون بنية ننجح في استخدامها ونحبها.

المشاركة في الاستطلاع