:has() دراسات حالة

Swetha Gopalakrishnan
Swetha Gopalakrishnan
Saurabh Rajpal
Saurabh Rajpal

لم تتوفّر في CSS طريقة لاختيار عنصر رئيسي مباشرةً استنادًا إلى عناصره الفرعية. وقد كان هذا الطلب من بين أهم الطلبات التي قدّمها المطوّرون على مدار سنوات عديدة. يحلّ محدّد :has() هذه المشكلة، وهو متاح الآن في جميع المتصفحات الرئيسية. قبل :has()، كان عليك غالبًا ربط أدوات اختيار طويلة أو إضافة فئات لعناصر الربط الخاصة بالتصميم. الآن، يمكنك وضع تنسيق استنادًا إلى علاقة العنصر بأحفاده. يمكنك الاطّلاع على مزيد من المعلومات حول أداة الاختيار :has() في CSS Wrapped 2023 و5 مقتطفات CSS يجب أن يعرفها كل مطوّر واجهة أمامية.

على الرغم من أنّ هذا العنصر المحدّد يبدو صغيرًا، إلا أنّه يمكن أن يتيح عددًا كبيرًا من حالات الاستخدام. توضّح هذه المقالة بعض حالات الاستخدام التي حقّقت شركات التجارة الإلكترونية استفادة منها باستخدام أداة الاختيار :has().

:has() هي جزء من البيانات الأساسية التي أصبحت متاحة مؤخرًا.

توافق المتصفّح

  • Chrome: 105
  • ‫Edge: 105
  • ‫Firefox: 121
  • Safari: 15.4

المصدر

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

Policybazaar

باستخدام أداة الاختيار :has()، تمكّنا من إيقاف عملية التحقّق المُستندة إلى JavaScript لاختيار المستخدم واستبدالها بحلّ CSS يعمل بسلاسة ويقدّم التجربة نفسها التي كانت متاحة من قبل.—أمان سوني، رئيس فريق التكنولوجيا، Policybazaar

طبَّق فريق الاستثمار في Policybazaar أداة الاختيار :has() بذكاء لتقديم إشارة مرئية واضحة للمستخدمين الذين يقارنون الخطط. تعرض الصورة التالية نوعَين من الخطط ضمن واجهة مستخدم المقارنة (الخط الأصفر والأزرق). لا يمكن مقارنة كل خطة سوى بنوعها الخاص. باستخدام :has()، عندما يختار المستخدِم نوعًا واحدًا من الخطط، لا يمكن اختيار نوع الخطة الآخر.

تنفيذ :has() لتصميم العنصر الرئيسي وعناصره الفرعية لإنشاء وظيفة اختيار مرتبطة بالفئة

الرمز

يمنحك :has() إمكانية تصميم العناصر الرئيسية وعناصرها الفرعية. يتحقّق الرمز التالي مما إذا كانت الحاوية الرئيسية تحتوي على فئة .disabled-group. إذا حدث ذلك، ستصبح البطاقة غير متاحة، ولن يستجيب الزر "إضافة" للنقرات، وذلك من خلال ضبط القيمة pointer-events على none.

.plan-group-container:has(.disabled-group) {
  opacity: 0.5;
  filter: grayscale(100%);
}

.plan-group-container:has(.disabled-section) .button {
  pointer-events: none;
  border-color: #B5B5B5;
  color: var(--text-primary-38-color);
  background: var(--input-border-color);
}

نفَّذ فريق الصحة في Policybazaar حالة استخدام مختلفة قليلاً. يتضمّن التطبيق اختبارًا مضمّنًا للمستخدم ويستخدم :has() للتحقّق من حالة مربّع الاختيار الخاص بالسؤال لمعرفة ما إذا تم الإجابة عن السؤال. وإذا كان الأمر كذلك، يتم تطبيق صورة متحركة للانتقال إلى السؤال التالي.

health.policybazaar.com/

الرمز

في مثال مقارنة الخطّة، تم استخدام :has() للتحقّق من توفّر class. يمكنك أيضًا التحقّق من حالة عنصر إدخال، مثل مربّع اختيار، باستخدام :has(input:checked). في المرئي الذي يعرض الاختبار، يكون كل سؤال في البانر الأرجواني مربّع اختيار. يتحقّق Policybazaar مما إذا تم الردّ على السؤال باستخدام :has(input:checked)، وإذا تم ذلك، يتم تشغيل صورة متحركة باستخدام animation: quesSlideOut 0.3s 0.3s linear forwards للانتقال إلى السؤال التالي. يمكنك الاطّلاع على طريقة عمل ذلك في الرمز التالي.

.segment_banner__wrap__questions {
 position: relative;
 animation: quesSlideIn 0.3s linear forwards;
}

.segment_banner__wrap__questions:has(input:checked) {
 animation: quesSlideOut 0.3s 0.3s linear forwards;
}


@keyframes quesSlideIn {
 from {
   transform: translateX(50px);
   opacity: 0;
 }
 to {
   transform: translateX(0px);
   opacity: 1;
 }
}

@keyframes quesSlideOut {
 from {
   transform: translateX(0px);
   opacity: 1;
 }
 to {
   transform: translateX(-50px);
   opacity: 0;
 }
}

Tokopedia

استخدَم Tokopedia :has() لإنشاء صورة مركّبة إذا كانت الصورة المصغّرة للمنتج تحتوي على فيديو. إذا كانت الصورة المصغّرة للمنتج تحتوي على فئة .playIcon، تتم إضافة تراكيب CSS. في ما يلي، يتم استخدام أداة الاختيار :has() مع أداة اختيار التداخل & ضمن الفئة الشاملة .thumbnailWrapper التي تنطبق على جميع الصور المصغّرة. يؤدي ذلك إلى إنشاء ملف CSS أكثر وحدات وسهولة في القراءة.

لقطة شاشة لصفحة Tokopedia قبل استخدام أداة الاختيار has وبعده
قبل استخدام :has() وبعده

الرمز

يستخدم الرمز التالي أدوات اختيار لغة CSS وأدوات الدمج (& و>) والتداخل مع :has() لتنسيق الصورة المصغّرة. بالنسبة إلى المتصفحات التي لا تتوافق مع هذه الميزة، يتم استخدام قاعدة فئة CSS العادية الإضافية كخيار احتياطي. تُستخدَم قاعدة @supports selector(:has(*)) أيضًا للتحقّق من توافق المتصفّح. وبالتالي، تكون التجربة الإجمالية متماثلة في جميع إصدارات المتصفّح.

export const thumbnailWrapper = css`
  padding: 0;
  margin-right: 7px;
  border: none;
  outline: none;
  background: transparent;

  > div {
    width: 64px;
    height: 64px;
    overflow: hidden;
    cursor: pointer;
    border-color: ;
    position: relative;
    border: 2px solid ${NN0};
    border-radius: 8px;
    transition: border-color 0.25s;

    &.active {
      border-color: ${GN500};
    }

    @supports selector(:has(*)) {
      &:has(.playIcon) {
        &::after {
          content: '';
          display: block;
          background: rgba(0, 0, 0, 0.2);
          position: absolute;
          top: 0;
          left: 0;
          right: 0;
          bottom: 0;
        }
      }
    }

    & > .playIcon {
      position: absolute;
      top: 25%;
      left: 25%;
      width: 50%;
      height: 50%;
      text-align: center;
      z-index: 1;
    }
  }
`;

أمور يجب مراعاتها عند استخدام :has()

يمكنك دمج :has() مع أدوات اختيار أخرى لإنشاء شرط أكثر تعقيدًا. يمكنك الاطّلاع على بعض الأمثلة في has()‏ family selector.

المصادر:

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