كيفية استخدام طلبات البحث في الحاويات الآن

كتب "كريس كويير" مؤخرًا مشاركة مدونة طرحت السؤال التالي:

والآن بعد أن أصبحت طلبات البحث في الحاوية متاحة في جميع محركات المتصفحات، فلماذا لا يستخدمها المزيد من مطوّري البرامج؟

تسرد مشاركة "كريس" عددًا من الأسباب المحتملة (على سبيل المثال، قلة الوعي والعادات القديمة تمر بصعوبة)، ولكن هناك سبب خاص بارز.

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

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

نهج عملي

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

بعد ذلك يصبح السؤال: ما مدى شمولية الإجراء الاحتياطي؟

كما هو الحال مع أي إجراء احتياطي، يكمن التحدي في تحقيق توازن جيد بين الفائدة والأداء. بالنسبة إلى ميزات CSS، يكون من المستحيل غالبًا إتاحة واجهة برمجة التطبيقات الكاملة (راجِع سبب عدم استخدام رمز polyfill). ومع ذلك، يمكنك تحقيق تقدم كبير من خلال تحديد المجموعة الأساسية من الوظائف التي يرغب معظم المطورين في استخدامها، ثم تحسين الإجراء الاحتياطي لهذه الميزات فقط.

ولكن ما هي "المجموعة الأساسية من الوظائف" التي يريدها معظم المطورين لطلبات البحث في الحاوية؟ للإجابة عن هذا السؤال، فكِّر في الطريقة التي ينشئ بها معظم المطوّرين حاليًا مواقع إلكترونية سريعة الاستجابة باستخدام الاستعلامات عن الوسائط.

تم توحيد جميع أنظمة التصميم الحديثة ومكتبات المكوّنات تقريبًا على مبادئ الأجهزة الجوّالة أولاً، والتي تم تنفيذها باستخدام مجموعة من نقاط الإيقاف المحدَّدة مسبقًا (مثل SM وMD وLG وXL). وقد تم تحسين المكوّنات ليتم عرضها بشكل جيد على الشاشات الصغيرة تلقائيًا، وبعد ذلك يتم تطبيق الأنماط بشكل مشروط على إتاحة مجموعة ثابتة من قيم عرض الشاشات الأكبر. (يُرجى الاطّلاع على مستندات التمهيد وTailwind للحصول على أمثلة عن ذلك.)

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

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

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

طريقة العمل

الخطوة 1: تعديل أنماط المكوّنات لاستخدام قواعد @container بدلاً من قواعد @media

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

من الجيد أن تبدأ بمكون واحد أو مكونين فقط لمعرفة كيفية عمل هذه الإستراتيجية، ولكن إذا كنت تريد تحويل 100% من مكوناتك إلى تصميم مستند إلى الحاوية، فلا بأس أيضًا! يكمن الشيء العظيم في هذه الإستراتيجية في أنه يمكنك اعتمادها بشكل تدريجي إذا لزم الأمر.

بعد تحديد المكوّنات التي تريد تعديلها، يجب تغيير كل قاعدة @media في CSS لهذه المكوّنات إلى قاعدة @container. يمكنك الحفاظ على شروط الحجم كما هي.

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

في ما يلي مثال على أنماط المكوِّن .photo-gallery الذي يكون عمودًا واحدًا تلقائيًا، ثم يعدِّل نمطه ليصبح عمودين وثلاثة أعمدة في نقطتَي الإيقاف MD وXL (على التوالي):

.photo-gallery {
  display: grid;
  grid-template-columns: 1fr;
}

/* Styles for the `MD` breakpoint */
@media (min-width: 768px) {
  .photo-gallery {
    grid-template-columns: 1fr 1fr;
  }
}

/* Styles for the `XL` breakpoint */
@media (min-width: 1280px) {
  .photo-gallery {
    grid-template-columns: 1fr 1fr 1fr;
  }
}

لتغيير أنماط المكوّنات هذه من استخدام قواعد @media إلى استخدام قواعد @container، يمكنك إجراء بحث واستبدال في الرمز البرمجي:

/* Before: */
@media (min-width: 768px) { /* ... */ }
@media (min-width: 1280px) { /* ... */ }

/* After: */
@container (min-width: 768px) { /* ... */ }
@container (min-width: 1280px) { /* ... */ }

بعد تعديل أنماط المكوّنات من قواعد @media إلى قواعد @container المستندة إلى نقاط التوقف، تتمثل الخطوة التالية في ضبط عناصر الحاوية.

الخطوة 2: إضافة عناصر الحاوية إلى رمز HTML

حددت الخطوة السابقة أنماط المكوّنات التي تستند إلى حجم عنصر الحاوية. الخطوة التالية هي تحديد العناصر في صفحتك التي يجب أن تكون عناصر الحاوية التي سيكون حجمها متناسبًا مع قواعد @container.

يمكنك تعريف أي عنصر ليكون عنصر حاوية في CSS من خلال ضبط السمة container-type على size أو inline-size. إذا كانت قواعد الحاوية تعتمد على العرض، ستكون السمة inline-size هي الخيار الذي تريد استخدامه بشكل عام.

فكّر في موقع ببنية HTML الأساسية التالية:

<body>
  <div class="sidebar">...</div>
  <div class="content">...</div>
</body>

لإنشاء عنصرَي .sidebar و.content على containers الموقع الإلكتروني هذه، أضِف هذه القاعدة إلى CSS:

.content, .sidebar {
  container-type: inline-size;
}

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

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

عليك إضافة بعض الرموز البرمجية التي ترصد تغيُّر حجم عناصر الحاوية، ثم تعدِّل نموذج العناصر في المستند (DOM) استنادًا إلى هذه التغييرات بطريقة يمكن لخدمة CSS جذبها.

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

يحدّد الرمز البرمجي التالي عنصر <responsive-container> قابلاً لإعادة الاستخدام يستجيب تلقائيًا لتغييرات الحجم ويضيف فئات نقاط الإيقاف التي يمكن لخدمة CSS ضبط نمطها استنادًا إلى ما يلي:

// A mapping of default breakpoint class names and min-width sizes.
// Redefine these as needed based on your site's design.
const defaultBreakpoints = {SM: 512, MD: 768, LG: 1024, XL: 1280};

// A resize observer that monitors size changes to all <responsive-container>
// elements and calls their `updateBreakpoints()` method with the updated size.
const ro = new ResizeObserver((entries) => {
  entries.forEach((e) => e.target.updateBreakpoints(e.contentRect));
});

class ResponsiveContainer extends HTMLElement {
  connectedCallback() {
    const bps = this.getAttribute('breakpoints');
    this.breakpoints = bps ? JSON.parse(bps) : defaultBreakpoints;
    this.name = this.getAttribute('name') || '';
    ro.observe(this);
  }
  disconnectedCallback() {
    ro.unobserve(this);
  }
  updateBreakpoints(contentRect) {
    for (const bp of Object.keys(this.breakpoints)) {
      const minWidth = this.breakpoints[bp];
      const className = this.name ? `${this.name}-${bp}` : bp;
      this.classList.toggle(className, contentRect.width >= minWidth);
    }
  }
}

self.customElements.define('responsive-container', ResponsiveContainer);

يعمل هذا الرمز من خلال إنشاء عنصر ResizeObserver يستجيب تلقائيًا لتغييرات الحجم لأي عناصر <responsive-container> في نموذج العناصر في المستند (DOM). إذا تطابق تغيير الحجم مع أحد أحجام نقاط الإيقاف المحددة، تتم إضافة فئة باسم نقطة التوقف هذه إلى العنصر (وإزالتها إذا لم يعد الشرط متطابقًا).

على سبيل المثال، إذا كان width للعنصر <responsive-container> بين 768 و1024 بكسل (استنادًا إلى قيم نقاط الإيقاف التلقائية التي تم ضبطها في الرمز)، ستتم إضافة الفئتَين SM وMD على النحو التالي:

<responsive-container class="SM MD">...</responsive-container>

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

لتعديل رمز HTML السابق لاستخدام عنصر الحاوية هذا، غيِّر الشريط الجانبي وعناصر <div> للمحتوى الرئيسي لتصبح عناصر <responsive-container> بدلاً من ذلك:

<body>
  <responsive-container class="sidebar">...</responsive-container>
  <responsive-container class="content">...</responsive-container>
</body>

في معظم الحالات، يمكنك استخدام العنصر <responsive-container> فقط بدون أيّ تخصيص، ولكن إذا أردت تخصيصه، تتوفّر لك الخيارات التالية:

  • أحجام نقاط الإيقاف المخصصة: يستخدم هذا الرمز مجموعة من أسماء فئات نقاط التوقف التلقائية وأحجام الحد الأدنى للعرض، ولكن يمكنك تغيير هذه الإعدادات التلقائية إلى ما تريده. يمكنك أيضًا إلغاء هذه القيم على أساس كل عنصر باستخدام السمة breakpoints.
  • الحاويات المُعنونة: يتيح هذا الرمز أيضًا استخدام الحاويات المُسمّاة من خلال تمرير السمة name. قد يكون هذا مهمًا إذا كنت بحاجة إلى دمج عناصر الحاوية. راجِع قسم القيود للتعرّف على مزيد من التفاصيل.

في ما يلي مثال يحدّد كلا خيارَي الضبط هذين:

<responsive-container
  name='sidebar'
  breakpoints='{"bp1":500,"bp2":1000,"bp3":1500}'>
</responsive-container>

أخيرًا، عند تجميع هذا الرمز، تأكّد من استخدام اكتشاف الميزات وimport() الديناميكي لتحميله فقط إذا لم يكن المتصفّح متوافقًا مع طلبات الحاوية.

if (!CSS.supports('container-type: inline-size')) {
  import('./path/to/responsive-container.js');
}

الخطوة 3: إضافة أنماط احتياطية إلى CSS

الخطوة الأخيرة في هذه الاستراتيجية هي إضافة أنماط احتياطية للمتصفّحات التي لا تتعرّف على الأنماط المحدّدة في قواعد @container. يمكنك إجراء ذلك من خلال تكرار هذه القواعد باستخدام فئات نقاط الإيقاف التي يتم ضبطها على عناصر <responsive-container>.

استكمالاً للمثال .photo-gallery السابق، قد تظهر الأنماط الاحتياطية لقاعدتَي @container على النحو التالي:

/* Container query styles for the `MD` breakpoint. */
@container (min-width: 768px) {
  .photo-gallery {
    grid-template-columns: 1fr 1fr;
  }
}

/* Fallback styles for the `MD` breakpoint. */
@supports not (container-type: inline-size) {
  :where(responsive-container.MD) .photo-gallery {
    grid-template-columns: 1fr 1fr;
  }
}

/* Container query styles for the `XL` breakpoint. */
@container (min-width: 1280px) {
  .photo-gallery {
    grid-template-columns: 1fr 1fr 1fr;
  }
}

/* Fallback styles for the `XL` breakpoint. */
@supports not (container-type: inline-size) {
  :where(responsive-container.XL) .photo-gallery {
    grid-template-columns: 1fr 1fr 1fr;
  }
}

في هذا الرمز، تتوفر لكل قاعدة @container قاعدة مكافئة تتطابق بشكل مشروط مع العنصر <responsive-container> في حال توفّر فئة نقطة الإيقاف المقابلة.

يتم ربط الجزء من أداة الاختيار المتطابق مع عنصر <responsive-container> في أداة اختيار من الفئة الصورية :where() للحفاظ على خصوصية أداة الاختيار الاحتياطية مكافئة لخصوصية أداة الاختيار الأصلية ضمن القاعدة @container.

ويتم أيضًا التفاف كل قاعدة احتياطية في بيان @supports. على الرغم من أنّ هذا الإجراء ليس ضروريًا تمامًا للعمل الاحتياطي، يعني ذلك أنّ المتصفّح يتجاهل هذه القواعد تمامًا إذا كان يتوافق مع طلبات البحث في الحاوية، ما قد يؤدي إلى تحسين أداء مطابقة الأنماط بشكل عام. ومن المحتمل أيضًا أن يسمح لأدوات إنشاء أو شبكات توصيل المحتوى (CDN) بإزالة هذه التعريفات إذا كانوا يعلمون أن المتصفح يدعم استعلامات الحاوية ولا يحتاج إلى هذه الأنماط الاحتياطية.

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

@use 'sass:map';

$breakpoints: (
  'SM': 512px,
  'MD': 576px,
  'LG': 1024px,
  'XL': 1280px,
);

@mixin breakpoint($breakpoint) {
  @container (min-width: #{map.get($breakpoints, $breakpoint)}) {
    @content();
  }
  @supports not (container-type: inline-size) {
    :where(responsive-container.#{$breakpoint}) & {
      @content();
    }
  }
}

بعد الحصول على هذا المزيج، يمكنك تعديل أنماط مكوِّن .photo-gallery الأصلية إلى نمط مشابه، ما سيزيل التكرار تمامًا:

.photo-gallery {
  display: grid;
  grid-template-columns: 1fr;

  @include breakpoint('MD') {
    grid-template-columns: 1fr 1fr;
  }

  @include breakpoint('XL') {
    grid-template-columns: 1fr 1fr 1fr;
  }
}

وهذا كل ما في الأمر!

ملخّص

إذًا، لنلخص ما سبق، إليك كيفية تحديث التعليمات البرمجية لاستخدام استعلامات الحاويات الآن باستخدام إجراء احتياطي متداخل المتصفحات.

  1. مكوّنات الهوية التي تريد تغيير نمطها بما يتوافق مع حاويتها، وتعديل قواعد @media في لغة CSS لاستخدام قواعد @container ويمكنك أيضًا توحيد مجموعة من أسماء نقاط التوقف (إذا لم يسبق لك ذلك) لتتطابق مع شروط الحجم في قواعد الحاوية.
  2. أضِف رمز JavaScript الذي يتيح استخدام عنصر <responsive-container> المخصّص، ثم أضِف العنصر <responsive-container> إلى أي مناطق محتوى في صفحتك تريد ربط المكوّنات بها.
  3. للتوافق مع المتصفحات القديمة، يمكنك إضافة أنماط احتياطية إلى CSS تتطابق مع فئات نقاط الإيقاف التي تتم إضافتها تلقائيًا إلى عناصر <responsive-container> في HTML. يُفضَّل استخدام مزيج من المعالجات المسبقة لـ CSS لتجنب الاضطرار إلى كتابة الأنماط نفسها مرتين.

الأمر الجيد في هذه الاستراتيجية هو وجود تكلفة إعداد تُدفع لمرة واحدة، ولكن بعد ذلك لن يلزم أي جهد إضافي لإضافة مكونات جديدة وتحديد الأنماط النسبية للحاوية لها.

أمثلة واقعية

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

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

هذا العرض التوضيحي هو إصدار معدَّل من موقع إلكتروني تم إنشاؤه في عام 2019 (قبل توفُّر طلبات البحث في الحاوية) للمساعدة في توضيح سبب أهمية طلبات البحث في الحاوية لإنشاء مكتبات مكوّنات متجاوبة حقًا.

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

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

القيود والتحسينات المحتملة

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

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

وحدات طلب الحاوية

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

مع ذلك، إذا كنت بحاجة إلى استخدام وحدات طلبات البحث في الحاوية، يمكنك بسهولة إضافة دعم لها باستخدام الخصائص المخصَّصة. على وجه التحديد، من خلال تحديد خاصية مخصصة لكل وحدة مستخدمة في عنصر الحاوية، كما يلي:

responsive-container {
  --cqw: 1cqw;
  --cqh: 1cqh;
}

وبعد ذلك، عندما تحتاج إلى الوصول إلى وحدات طلب الحاوية، استخدِم هذه السمات بدلاً من استخدام الوحدة نفسها:

.photo-gallery {
  font-size: calc(10 * var(--cqw));
}

بعد ذلك، لإتاحة المتصفحات القديمة، اضبط قيم هذه السمات المخصّصة في عنصر الحاوية ضمن استدعاء ResizeObserver.

class ResponsiveContainer extends HTMLElement {
  // ...
  updateBreakpoints(contentRect) {
    this.style.setProperty('--cqw', `${contentRect.width / 100}px`);
    this.style.setProperty('--cqh', `${contentRect.height / 100}px`);

    // ...
  }
}

ويتيح لك ذلك "تمرير" هذه القيم من JavaScript إلى CSS بشكل فعّال، وبعد ذلك ستتوفر لك إمكانات CSS الكاملة (على سبيل المثال، calc() وmin() وmax() وclamp()) للتعامل معها حسب الحاجة.

توافُق الخصائص المنطقية ووضع الكتابة

ربما لاحظت استخدام inline-size بدلاً من width في تعريفات @container في بعض أمثلة CSS هذه. ربما لاحظت أيضًا الوحدتَين cqi وcqb الجديدتَين (لأحجام الوحدات المضمّنة وأحجام الكتل، على التوالي). تعكس هذه الميزات الجديدة تحول CSS إلى الخصائص والقيم المنطقية بدلاً من السمات المادية أو المستندة إلى الاتجاهات.

للأسف، لا تزال واجهات برمجة التطبيقات مثل Resize Observer تعرض القيم في width وheight، وبالتالي إذا كانت تصميماتك تحتاج إلى مرونة في الخصائص المنطقية، عليك معرفة ذلك بنفسك.

يمكن استخدام وضع الكتابة باستخدام عنصر مثل getComputedStyle() لإدخال عنصر الحاوية، إلا أنّ ذلك يترتّب عليه تكلفة ولا يمكن رصد أي تغييرات في وضع الكتابة.

لهذا السبب، فإنّ أفضل طريقة هي أن يقبل العنصر <responsive-container> نفسه سمة وضع الكتابة التي يمكن لمالك الموقع الإلكتروني ضبطها (وتعديلها) حسب الحاجة. لتنفيذ ذلك، يجب اتّباع الطريقة نفسها الموضّحة في القسم السابق، وتبديل width وheight حسب الحاجة.

الحاويات المتداخلة

تسمح لك السمة container-name بمنح الحاوية اسمًا، يمكنك بعد ذلك الإشارة إليه في قاعدة @container. تكون الحاويات المُعنوَنة مفيدة إذا كانت لديك حاويات مضمَّنة في حاويات وكنت بحاجة إلى قواعد معيّنة لمطابقة حاويات معيّنة فقط (وليس فقط حاوية الأصل الأقرب).

تستخدم الاستراتيجية الاحتياطية الموضحة هنا المكمِّلات التابعة لتصميم العناصر التي تتطابق مع فئات نقاط توقف معيّنة. يمكن أن يتوقف هذا الأمر إذا كان لديك حاويات مضمَّنة، لأنّ أي عدد من فئات نقاط الإيقاف من كيانات عناصر الحاوية المتعددة يمكن أن يتطابق مع مكون معيّن في الوقت نفسه.

على سبيل المثال، يوجد هنا عنصران <responsive-container> يلتفان حول المكوِّن .photo-gallery، ولكن نظرًا لأن الحاوية الخارجية أكبر من الحاوية الداخلية، تمت إضافة فئات نقاط توقف مختلفة.

<responsive-container class="SM MD LG">
  ...
  <responsive-container class="SM">
    ...
    <div class="photo-gallery">...</div class="photo-gallery">
  </responsive-container>
</responsive-container>

في هذا المثال، ستؤثّر الفئتان MD وLG الموجودة في الحاوية الخارجية في قواعد النمط المطابِقة للمكوّن .photo-gallery، والتي لا تتطابق مع سلوك طلبات الحاوية (لأنّها تتطابق فقط مع حاوية الأصل الأقرب).

للتعامل مع هذه المشكلة، عليك اتّخاذ أحد الإجراءَين التاليَين:

  1. احرص دائمًا على تسمية أي حاويات تدمجها، ثم تأكَّد من أنّ فئات نقاط التوقف بادئة باسم الحاوية لتجنُّب حدوث أي تعارضات.
  2. يمكنك استخدام المكمِّل الثانوي بدلاً من أداة التجميع الفرعية في أدوات الاختيار الاحتياطية (التي تكون أكثر دقّة).

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

ماذا عن المتصفّحات التي لا تتوافق مع :where() أو العناصر المخصّصة أو تغيير حجم المراقب؟

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

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

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

من المفترض أن تظل وظائف الموقع الإلكتروني تعمل، وهذا هو المهم حقًا.

لماذا لا يتم استخدام polyfill لطلب بحث الحاوية فقط؟

من المعروف أنّ إضافة ميزات CSS صعبة جدًّا وتتطلب بشكل عام إعادة تنفيذ محلّل CSS بالكامل ومنطق التتابع التدريجي في JavaScript. نتيجةً لذلك، على مؤلّفي رموز polyfill CSS إجراء العديد من المُفاضلات التي تكون غالبًا مع العديد من القيود المفروضة على الميزات، بالإضافة إلى النفقات العامة المرتبطة بالأداء.

لهذه الأسباب، لا ننصح عمومًا باستخدام رموز polyfill CSS في الإنتاج، بما في ذلك container-query-polyfill من ميزات Google Chrome الاختبارية التي لم تعد تخضع للصيانة (وكانت مصمّمة في المقام الأول لأغراض تجريبية).

إنّ الاستراتيجية الاحتياطية التي تمت مناقشتها هنا تتضمّن عددًا أقل من القيود، وتتطلّب رمزًا أقل بكثير، وستعمل بشكل أفضل بكثير من أيٍ من رموز polyfill لطلب البحث في الحاوية.

هل تحتاج حتى إلى تنفيذ إجراء احتياطي للمتصفّحات القديمة؟

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

وفقًا للموقع الإلكتروني caniuse.com، يساهم استخدام طلبات البحث في الحاويات في 90% من مستخدمي الإنترنت على مستوى العالم، وبالنسبة إلى الكثير من الأشخاص الذين يقرؤون هذه المشاركة، من المرجّح أن يكون العدد أعلى قليلاً بالنسبة إلى قاعدة مستخدميهم. لذا من المهم أن تضع في اعتبارك أن معظم المستخدمين سيرون إصدار طلب بحث الحاوية لواجهة المستخدم في تطبيقك. وبالنسبة إلى الـ 10٪ من المستخدمين الذين لن يفعلوا ذلك، لا يبدو الأمر وكأنهم سيتعرضون لتجربة سيئة. عند اتباع هذه الإستراتيجية، سيرى هؤلاء المستخدمون في أسوأ الحالات التخطيط الافتراضي أو "الهاتف المحمول" لبعض المكونات، وليس نهاية العالم.

عند إجراء المفاضلات، من الممارسات الجيدة إجراء تحسين لغالبية المستخدمين - بدلاً من التخلف عن نهج أدنى قاسم مشترك يمنح جميع المستخدمين تجربة متسقة، ولكن دون المستوى نفسه.

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

التطلّع إلى المستقبل

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

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

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