استعلامات حاوية CSS: حالات الاستخدام واستراتيجيات الترحيل

نشرت: 2022-03-10
ملخص سريع ↬ تعمل استعلامات حاوية CSS على تقريب استعلامات الوسائط من العناصر المستهدفة نفسها وتمكينها من التكيف مع أي حاوية أو تخطيط معين تقريبًا. في هذه المقالة ، سنغطي أساسيات استعلام حاوية CSS وكيفية استخدامها اليوم مع التحسين التدريجي أو polyfills.

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

مثال على تخطيط الصفحة المستجيبة. تُظهر الصورة اليسرى تخطيط سطح المكتب عند عرض منفذ العرض 1280 بكسل والصورة اليمنى تُظهر تخطيط الهاتف المحمول بعرض 568 بكسل لإطار العرض.
مثال على تخطيط الصفحة المستجيبة. تُظهر الصورة اليسرى تخطيط سطح المكتب عند عرض منفذ العرض 1280 بكسل والصورة اليمنى تُظهر تخطيط الهاتف المحمول بعرض 568 بكسل لإطار العرض. (معاينة كبيرة)

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

مثال على مكون بطاقة المنتج المتجاوب. تُظهر الصورة اليسرى مكونًا عند عرض منفذ العرض 720 بكسل ، بينما تُظهر الصورة اليمنى تخطيط المكون عند عرض منفذ العرض 568 بكسل.
مثال على مكون بطاقة المنتج المتجاوب. تُظهر الصورة اليسرى مكونًا عند عرض منفذ العرض 720 بكسل ، بينما تُظهر الصورة اليمنى تخطيط المكون عند عرض منفذ العرض 568 بكسل. (معاينة كبيرة)

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

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

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

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

 .product-card { /* Default card style */ } .product-card--narrow { /* Style variation for narrow viewport and containers */ } @media screen and (min-width: 569px) { .product-card--wide { /* Style variation for wider viewport and containers */ } }

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

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

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

راجع القلم [بطاقات المنتج: حاويات مختلفة] (https://codepen.io/smashingmag/pen/eYvWVxz) بواسطة Adrian Bece.

انظر بطاقات منتج القلم: حاويات مختلفة بواسطة Adrian Bece.

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

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

- "استعلامات الحاويات: مرة أخرى حتى الخرق" مات ماركيز

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

دعم المتصفح

تعد استعلامات الحاوية ميزة تجريبية ، وهي متوفرة حاليًا في إصدار Chrome Canary وقت كتابة هذه المقالة. إذا كنت ترغب في متابعة وتشغيل أمثلة CodePen في هذه المقالة ، فستحتاج إلى تمكين استعلامات الحاوية في عنوان URL للإعدادات التالية.

 chrome://flags/#enable-container-queries
استفسارات الحاويات
(معاينة كبيرة)

في حال كنت تستخدم متصفحًا لا يدعم استعلامات الحاوية ، فسيتم توفير صورة تعرض مثال العمل المقصود جنبًا إلى جنب مع العرض التوضيحي CodePen.

المزيد بعد القفز! أكمل القراءة أدناه ↓

العمل مع استعلامات الحاوية

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

خاصية الاحتواء

تمت إضافة خاصية contain CSS إلى غالبية المتصفحات الحديثة ولديها دعم متصفح لائق بنسبة 75٪ وقت كتابة هذا المقال. تُستخدم خاصية contain بشكل أساسي لتحسين الأداء من خلال التلميح إلى المستعرض حول الأجزاء (الأشجار الفرعية) من الصفحة التي يمكن التعامل معها على أنها مستقلة ولن تؤثر على التغييرات التي تطرأ على العناصر الأخرى في الشجرة. بهذه الطريقة ، إذا حدث تغيير في عنصر واحد ، فسيعيد المتصفح عرض هذا الجزء فقط (الشجرة الفرعية) بدلاً من الصفحة بأكملها. باستخدام قيم الخاصية contain ، يمكننا تحديد أنواع الاحتواء التي نريد استخدامها - layout أو size أو paint .

هناك العديد من المقالات الرائعة حول خاصية contain التي تحدد الخيارات المتاحة وحالات الاستخدام بمزيد من التفاصيل ، لذلك سأركز فقط على الخصائص المتعلقة باستعلامات الحاوية.

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

سنستخدم قيم layout​ style​ contain​ ، لكننا سنحتاج أيضًا إلى قيمة إضافية تشير إلى المتصفح حول المحور الذي سيحدث فيه التغيير.

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

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

 <section> <article class="card"> <div class="card__wrapper"> <!-- Card content --> </div> </article> </section>
 .card { contain: layout inline-size style; } .card__wrapper { display: grid; grid-gap: 1.5em; grid-template-rows: auto auto; /* ... */ }

لاحظ كيف أننا لا نضيف هذه القيمة إلى section أشبه بالوالدين الأبعد ونحافظ على الحاوية قريبة قدر الإمكان من العنصر المتأثر.

"الأداء هو فن تجنب العمل والقيام بأي عمل بأكبر قدر ممكن من الكفاءة. في كثير من الحالات ، يتعلق الأمر بالعمل مع المتصفح ، وليس ضده ".

- "أداء الأداء" بول لويس

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

استعلام حاوية

بعد إضافة خاصية contain إلى غلاف عنصر البطاقة ، يمكننا كتابة استعلام حاوية. لقد أضفنا خاصية contain إلى عنصر به فئة card ، لذا يمكننا الآن تضمين أي من العناصر الفرعية في استعلام الحاوية.

تمامًا كما هو الحال مع استعلامات الوسائط العادية ، نحتاج إلى تحديد استعلام باستخدام خصائص min-width أو max-width ودمج جميع المحددات داخل الكتلة. ومع ذلك ، @container الكلمة الأساسيةcontainer بدلاً من @media لتحديد استعلام حاوية.

 @container (min-width: 568px) { .card__wrapper { align-items: center; grid-gap: 1.5em; grid-template-rows: auto; grid-template-columns: 150px auto; } .card__image { min-width: auto; height: auto; } }

كل من عنصر card__wrapper و card__image هما عنصران تابعان لعنصر card يحتوي على خاصية contain محددة. عندما نستبدل استعلامات الوسائط العادية باستعلامات الحاوية ، ونزيل فئات CSS الإضافية للحاويات الضيقة ، ونشغل مثال CodePen في متصفح يدعم استعلامات الحاوية ، نحصل على النتيجة التالية.

في هذا المثال ، لا نقوم بتغيير حجم إطار العرض ، ولكن عنصر الحاوية <section> نفسه الذي تم تطبيق خاصية CSS لتغيير حجمه. يقوم المكون تلقائيًا بالتبديل بين التخطيطات وفقًا لأبعاد الحاوية.
في هذا المثال ، لا نقوم بتغيير حجم منفذ العرض ، ولكن تم تطبيق عنصر الحاوية <section> نفسه الذي تم تطبيق خاصية CSS لتغيير حجمه. يقوم المكون تلقائيًا بالتبديل بين التخطيطات وفقًا لأبعاد الحاوية. (معاينة كبيرة)

راجع القلم [بطاقات المنتج: استعلامات الحاويات] (https://codepen.io/smashingmag/pen/PopmQLV) بواسطة Adrian Bece.

راجع بطاقات منتج القلم: استعلامات الحاويات بواسطة Adrian Bece.

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

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

التحسين التدريجي و Polyfills

دعونا نرى ما إذا كان بإمكاننا إضافة رجوع إلى تنوع فئة CSS واستعلامات الوسائط. يمكننا استخدام استعلامات ميزات CSS مع قاعدة @supports لاكتشاف ميزات المتصفح المتاحة. ومع ذلك ، لا يمكننا التحقق من وجود استعلامات أخرى ، لذلك نحتاج إلى إضافة تحقق من عنصر contain: layout inline-size style . سيتعين علينا أن نفترض أن المتصفحات التي تدعم خاصية inline-size تدعم أيضًا استعلامات الحاوية.

 /* Check if the inline-size value is supported */ @supports (contain: inline-size) { .card { contain: layout inline-size style; } } /* If the inline-size value is not supported, use media query fallback */ @supports not (contain: inline-size) { @media (min-width: 568px) { /* ... */ } } /* Browser ignores @container if it's not supported */ @container (min-width: 568px) { /* Container query styles */ }

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

راجع القلم [بطاقات المنتج: استعلامات الحاويات مع التحسين التدريجي] (https://codepen.io/smashingmag/pen/zYZwRXZ) بواسطة Adrian Bece.

راجع بطاقات منتج Pen: استعلامات الحاويات مع التحسين التدريجي بواسطة Adrian Bece.

نظرًا لأن مواصفات استعلام الحاوية لا تزال في مرحلة تجريبية ، فمن المهم أن تضع في اعتبارك أن المواصفات أو التنفيذ عرضة للتغيير في الإصدارات المستقبلية.

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

  • cqfill بواسطة جوناثان نيل
    برنامج JavaScript polyfill لـ CSS و PostCSS
  • react-container-query كريس جارسيا
    ربط مخصص ومكون لـ React

الترحيل من استعلامات الوسائط إلى استعلامات الحاوية

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

 <section> <div class="card__wrapper card__wrapper--wide"> <!-- Wide card content --> </div> </section> /* ... */ <aside> <div class="card__wrapper"> <!-- Narrow card content --> </div> </aside>
 .card__wrapper { display: grid; grid-gap: 1.5em; grid-template-rows: auto auto; /* ... */ } .card__image { /* ... */ } @media screen and (min-width: 568px) { .card__wrapper--wide { align-items: center; grid-gap: 1.5em; grid-template-rows: auto; grid-template-columns: 150px auto; } .card__image { /* ... */ } }

أولاً ، قم بلف عنصر HTML الجذر الذي تم تطبيق استعلام وسائط عليه باستخدام عنصر له خاصية contain .

 <section> <article class="card"> <div class="card__wrapper"> <!-- Card content --> </div> </article> </section>
 @supports (contain: inline-size) { .card { contain: layout inline-size style; } }

بعد ذلك ، قم بلف استعلام وسائط في استعلام ميزة وقم بإضافة استعلام حاوية.

 @supports not (contain: inline-size) { @media (min-width: 568px) { .card__wrapper--wide { /* ... */ } .card__image { /* ... */ } } } @container (min-width: 568px) { .card__wrapper { /* Same code as .card__wrapper--wide in media query */ } .card__image { /* Same code as .card__image in media query */ } }

على الرغم من أن هذه الطريقة تؤدي إلى بعض تضخم التعليمات البرمجية وتكرار التعليمات البرمجية ، إلا أنه باستخدام SASS أو PostCSS ، يمكنك تجنب تكرار كود التطوير ، لذلك تظل التعليمات البرمجية المصدر لـ CSS قابلة للصيانة.

بمجرد تلقي استعلامات الحاوية دعم المستعرض المناسب ، قد ترغب في إزالة @supports not (contain: inline-size) كتل التعليمات البرمجية ومواصلة دعم استعلامات الحاوية حصريًا.

نشرت Stephanie Eckles مؤخرًا مقالًا رائعًا حول استعلامات الحاوية التي تغطي استراتيجيات الترحيل المختلفة. أوصي بالتحقق من ذلك لمزيد من المعلومات حول الموضوع.

سيناريوهات حالة الاستخدام

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

تشمل الأمثلة الأخرى (تتطلب الأمثلة متصفحًا يدعم استعلامات الحاوية):

  • المكونات المعيارية مثل البطاقات وعناصر النموذج واللافتات وما إلى ذلك.
  • تخطيطات قابلة للتكيف
  • ترقيم الصفحات بوظائف مختلفة للجوال وسطح المكتب
  • تجارب ممتعة مع تغيير حجم CSS

خاتمة

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

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

مراجع

  • "استعلامات الحاويات: دليل البدء السريع" بقلم ديفيد إيه هيرون
  • "قل مرحبًا بطلبات حاوية CSS ،" أحمد شديد
  • "احتواء CSS في Chrome 52" ، بول لويس
  • راشيل أندرو "مساعدة المتصفحات على التحسين باستخدام خاصية احتواء CSS"