بدء استخدام استعلامات الأنماط

أصبحت إمكانية طلب حجم عنصر رئيسي مضمّن وقيم وحدات طلبات البحث عن الحاوية متاحة مؤخرًا في جميع محركات المتصفحات الحديثة.

Browser Support

  • Chrome: 105.
  • Edge: 105.
  • Firefox: 110.
  • Safari: 16.

Source

ومع ذلك، تتضمّن مواصفات الاحتواء أكثر من مجرد طلبات البحث عن الحجم، فهي تتيح أيضًا طلب قيم نمط عنصر رئيسي. اعتبارًا من الإصدار 111 من Chromium، سيصبح بإمكانك تطبيق احتواء النمط على قيم الخصائص المخصّصة وطلب قيمة خاصية مخصّصة من عنصر رئيسي.

Browser Support

  • Chrome: 111.
  • Edge: 111.
  • Firefox: 151.
  • Safari: 18.

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

تسمح مواصفات CSS Containment Module Level 3، التي تغطي طلبات البحث عن الحجم والنمط، بطلب أي أنماط من عنصر رئيسي، بما في ذلك أزواج الخصائص والقيم، مثل font-weight: 800. ومع ذلك، في عملية طرح هذه الميزة، لا تعمل طلبات البحث عن النمط حاليًا إلا مع قيم الخصائص المخصّصة في CSS. يظل ذلك مفيدًا جدًا لدمج الأنماط وفصل البيانات عن التصميم. لنلقِ نظرة على كيفية استخدام طلبات البحث عن النمط مع الخصائص المخصّصة في CSS:

البدء في استخدام طلبات البحث عن النمط

لنفترض أنّ لدينا رمز HTML التالي:

<ul class="card-list">
  <li class="card-container">
    <div class="card">
      ...
    </div>
  </li>
</ul>

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

طلب العناصر الرئيسية المباشرة

مخطّط بياني لطلب بحث عن نمط

على عكس طلبات البحث عن النمط، لا تحتاج إلى تطبيق الاحتواء باستخدام السمة container-type أو container على .card-container ليتمكّن .card من طلب أنماط العنصر الرئيسي المباشر. ومع ذلك، علينا تطبيق الأنماط (قيم الخصائص المخصّصة في هذه الحالة) على حاوية (.card-container في هذه الحالة) أو أي عنصر يحتوي على العنصر الذي ننسّقه في DOM. لا يمكننا تطبيق الأنماط التي نطلبها على العنصر المباشر الذي ننسّقه باستخدام طلب البحث هذا لأنّ ذلك قد يؤدي إلى حلقات لا نهائية.

لطلب عنصر رئيسي مباشرةً، يمكنك كتابة ما يلي:

/* styling .card based on the value of --theme on .card-container */
@container style(--theme: warm) {
  .card {
    background-color: wheat;
    border-color: brown; 
    ...
  }
}

ربما لاحظت أنّ طلب البحث عن النمط يغلّف طلب البحث بالدالة style(). يتم ذلك لتمييز قيم الحجم عن الأنماط. على سبيل المثال، يمكنك كتابة طلب بحث عن عرض الحاوية على النحو التالي: @container (min-width: 200px) { … }. سيؤدي ذلك إلى تطبيق الأنماط إذا كان عرض الحاوية الرئيسية 200 بكسل على الأقل. ومع ذلك، يمكن أن تكون min-width أيضًا خاصية CSS، ويمكنك طلب قيمة CSS للسمة min-width باستخدام طلبات البحث عن النمط. لهذا السبب، عليك استخدام برنامج التضمين style() لتوضيح الفرق: @container style(min-width: 200px) { … }.

تنسيق العناصر الرئيسية غير المباشرة

إذا أردت طلب أنماط لأي عنصر ليس عنصرًا رئيسيًا مباشرًا، عليك منح هذا العنصر container-name. على سبيل المثال، يمكننا تطبيق أنماط على .card استنادًا إلى أنماط .card-list من خلال منح .card-list اسم container-name والإشارة إليه في طلب البحث عن النمط.

/* styling .card based on the value of --moreGlobalVar on .card-list */
@container cards style(--moreGlobalVar: value) {
  .card {
    ...
  }
}

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

لكن كل ذلك يصبح أكثر منطقية في الممارسة. لنلقِ نظرة على بعض الأمثلة:

طلبات البحث عن النمط قيد التنفيذ

صورة توضيحية تتضمّن بطاقات منتجات متعددة، بعضها يتضمّن تصنيف &quot;منتج جديد&quot; أو &quot;كمية محدودة&quot;، وبطاقة &quot;كمية محدودة&quot; بخلفية حمراء

تكون طلبات البحث عن النمط مفيدة بشكل خاص عندما يكون لديك مكوّن قابل لإعادة الاستخدام يتضمّن أشكالًا متعددة، أو عندما لا يكون لديك تحكّم في جميع أنماطك ولكن عليك تطبيق تغييرات في حالات معيّنة. يعرض هذا المثال مجموعة من بطاقات المنتجات التي تشترك في مكوّن البطاقة نفسه. تحتوي بعض بطاقات المنتجات على تفاصيل/ملاحظات إضافية، مثل "جديد" أو "كمية قليلة"، يتم تفعيلها من خلال خاصية مخصّصة باسم --detail. بالإضافة إلى ذلك، إذا كانت كمية المنتج "قليلة"، يحصل على خلفية حمراء داكنة للحدود. من المحتمل أن يتم عرض هذا النوع من المعلومات من جهة الخادم، ويمكن تطبيقه على البطاقات من خلال الأنماط المضمّنة على النحو التالي:

 <div class="product-list">
  <div class="product-card-container" style="--detail: new">
    <div class="product-card">
      <div class="media">
        <img .../>
      <div class="comment-block"></div>
    </div>
  </div>
  <div class="meta">
    ...
  </div>
  </div>
  <div class="product-card-container" style="--detail: low-stock">
    ...
  </div>
  <div class="product-card-container">
    ...
  </div>
  ...
</div>

بالنظر إلى هذه البيانات المنظَّمة، يمكنك تمرير القيم إلى --detail واستخدام هذه الخاصية المخصّصة في CSS لتطبيق الأنماط:

@container style(--detail: new) {
  .comment-block {
    display: block;
  }
  
  .comment-block::after {
    content: 'New';
    border: 1px solid currentColor;
    background: white;
    ...
  }
}

@container style(--detail: low-stock) {
  .comment-block {
    display: block;
  }
  
  .comment-block::after {
    content: 'Low Stock';
    border: 1px solid currentColor;
    background: white;
    ...
  }
  
  .media-img {
    border: 2px solid brickred;
  }
}

يسمح لنا الرمز أعلاه بتطبيق شريحة لـ --detail: low-stock و--detail: new، ولكن ربما لاحظت بعض التكرار في مجموعة الرموز. في الوقت الحالي، ليس هناك طريقة لطلب وجود --detail فقط باستخدام @container style(--detail)، ما سيسمح بمشاركة الأنماط بشكل أفضل وتقليل التكرار. تتم مناقشة هذه الإمكانية حاليًا في فريق العمل.

بطاقات الطقس

استخدم المثال السابق خاصية مخصّصة واحدة تتضمّن قيمًا متعددة ممكنة لتطبيق الأنماط. ولكن يمكنك مزجها باستخدام خصائص مخصّصة متعددة وطلبها أيضًا. لنأخذ مثال بطاقة الطقس هذا:

عرض توضيحي لبطاقات الطقس

لتنسيق تدرّجات الخلفية والرموز لهذه البطاقات، ابحث عن خصائص الطقس، مثل "غائم" أو "مُمطر" أو "مُشمس":

@container style(--sunny: true) {
  .weather-card {
    background: linear-gradient(-30deg, yellow, orange);
  }
  
  .weather-card:after {
    content: url(<data-uri-for-demo-brevity>);
    background: gold;
  }
}

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

@container style(--sunny: true) and style(--cloudy: true) {
    .weather-card {
      background: linear-gradient(24deg, pink, violet);
    }
  
  .weather-card:after {
      content: url(<data-uri-for-demo-brevity>);
      background: violet;
  }
}

فصل البيانات عن التصميم

في كلا العرضَين التوضيحيَين، هناك فائدة هيكلية لفصل طبقة البيانات (DOM التي سيتم عرضها على الصفحة) عن الأنماط المطبّقة. تتم كتابة الأنماط كأشكال مختلفة محتملة ضمن نمط المكوّنات، بينما يمكن لنقطة نهاية إرسال البيانات التي ستستخدمها بعد ذلك لتنسيق المكوّن. يمكنك استخدام قيمة واحدة، كما في الحالة الأولى، لتعديل قيمة --detail، أو استخدام متغيّرات متعددة، كما في الحالة الثانية (ضبط --rainy أو --cloudy أو --sunny). والأفضل من ذلك أنّه يمكنك دمج هذه القيم أيضًا، إذ إنّ التحقّق من كل من --sunny و--cloudy يمكن أن يعرض نمطًا غائمًا جزئيًا.

يمكن تعديل قيم الخصائص المخصّصة من خلال JavaScript بسلاسة، إما أثناء إعداد نموذج DOM (أي أثناء إنشاء المكوّن في إطار عمل)، أو تعديلها في أي وقت باستخدام <parentElem>.style.setProperty('--myProperty’, <value>). I

إليك عرضًا توضيحيًا يوضّح كيفية تعديل --theme لزر وتطبيق الأنماط باستخدام طلبات البحث عن النمط والخاصية المخصّصة (--theme) في بضعة أسطر من الرمز:

لتنسيق البطاقة باستخدام طلبات البحث عن النمط، إليك رمز JavaScript المستخدَم لتعديل قيم الخصائص المخصّصة:

const themePicker = document.querySelector('#theme-picker')
const btnParent = document.querySelector('.btn-section');

themePicker.addEventListener('input', (e) => {
  btnParent.style.setProperty('--theme', e.target.value);
})

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