CSS Container Queries: تصميم مكونات تتكيف مع المساحة المتاحة
شرح عملي لـ container-type و@container لبناء بطاقات ومكونات تتكيف مع عرض الحاوية بدل عرض الشاشة فقط.
ما المشكلة التي تحلها Container Queries؟
تعتمد media queries على خصائص نافذة العرض، مثل عرض الشاشة. لكن المكوّن الواحد قد يظهر في مواضع مختلفة داخل الموقع: بطاقة بعرض كامل في صفحة، وبطاقة صغيرة في عمود جانبي، وعنصرًا داخل نافذة منبثقة. قد تكون الشاشة واسعة في الحالات الثلاث، بينما تختلف المساحة الفعلية المتاحة للمكوّن اختلافًا كبيرًا.
تسمح Container Queries للمكوّن بتغيير مظهره بحسب حجم الحاوية التي يحتويه. وهذا يجعل المكونات أكثر قابلية لإعادة الاستخدام ويقلل الحاجة إلى معرفة مكان استخدامها مسبقًا. لا تستبدل هذه التقنية media queries؛ بل تكملها. استخدم استعلامات الوسائط لقرارات الصفحة العامة، واستعلامات الحاوية لقرارات المكوّن الداخلية.
تعريف الحاوية بطريقة صحيحة
تحتاج أولًا إلى إعلان العنصر الذي سيُقاس حجمه. في أغلب مكونات الواجهات، يكفي container-type: inline-size لأن المطلوب هو الاستجابة لعرض الحاوية على المحور المضمّن. ويمكن إعطاء الحاوية اسمًا لتصبح الاستعلامات أوضح عندما توجد عدة حاويات متداخلة.
.product-card-shell {
container-type: inline-size;
container-name: product-card;
}
تذكّر أن العنصر الذي تُطبق عليه قاعدة @container لا يكون عادةً الحاوية نفسها، بل أحد العناصر التابعة لها. لذلك افصل بين غلاف المكوّن والمحتوى الذي يتغير تخطيطه. هذا الفصل يجعل حدود المسؤولية واضحة ويسهل اكتشاف الأخطاء.
بناء بطاقة تتحول من عمود إلى صف
ابدأ بتخطيط بسيط يعمل في المساحة الضيقة، ثم أضف تحسينًا عند اتساع الحاوية. هذا النهج «التدرج من البسيط» أكثر أمانًا من افتراض أن كل بطاقة تملك مساحة كافية منذ البداية.
.product-card-shell {
container: product-card / inline-size;
}
.product-card {
display: grid;
grid-template-columns: minmax(0, 1fr);
gap: 1rem;
}
.product-card img {
display: block;
width: 100%;
aspect-ratio: 4 / 3;
object-fit: cover;
}
@container product-card (min-width: 34rem) {
.product-card {
grid-template-columns: minmax(9rem, 0.8fr) minmax(0, 1.2fr);
align-items: center;
}
}
في حاوية ضيقة تظهر الصورة والنص عموديًا، وعندما يتوفر عرض كافٍ يصبحان بجانب بعضهما. لاحظ استخدام minmax(0, ...) لتجنب تمدد الأعمدة بسبب المحتوى، وأن حد 34rem هنا مثال وليس قيمة معيارية؛ اختبر مكوناتك لتحديد الحد المناسب لها.
استعلامات الحاوية مع الأنماط النصية
لا تقتصر الفائدة على الأعمدة. قد تحتاج بطاقة صغيرة إلى عنوان أقل بروزًا أو إخفاء وصف ثانوي عندما تكون المساحة محدودة، مع إبقائه ظاهرًا في المساحات الأكبر. لكن تجنب إخفاء معلومات يحتاج إليها المستخدم لمجرد ضيق الحاوية؛ الأفضل غالبًا إعادة ترتيبها أو تقليل المسافات أولًا.
.story-card {
padding: 1rem;
}
.story-card__summary {
font-size: .95rem;
}
@container (min-width: 28rem) {
.story-card {
padding: 1.5rem;
}
.story-card__title {
font-size: 1.35rem;
}
}
يمكن أيضًا استخدام أسماء الحاويات لتقليل الالتباس في المكونات المتداخلة. عند كتابة استعلام غير مسمى، قد يطابق المتصفح أقرب حاوية مؤهلة؛ إذا كان التصميم يحتوي أكثر من مستوى، فالتسمية توضح الحاوية المقصودة وتقلل المفاجآت.
الفرق بين Container Queries وMedia Queries
- Media Queries: مناسبة لتغيير بنية الصفحة العامة، أو إظهار قائمة تنقل مختلفة وفق عرض نافذة العرض، أو مراعاة تفضيلات النظام مثل تقليل الحركة.
- Container Queries: مناسبة لبطاقات المنتجات، ومكونات المقالات، وعناصر لوحة التحكم التي قد تظهر في أعمدة متفاوتة العرض.
- Flexbox وGrid: لا يزالان أداتي التخطيط داخل المكوّن؛ أما الاستعلام فيقرر متى تتغير القواعد.
في مشروع واقعي، قد تستخدم الأدوات الثلاث معًا: Grid لبناء شبكة الصفحة، وContainer Queries لتغيير بنية البطاقة بحسب عمودها، وMedia Queries لضبط رأس الموقع أو القائمة الرئيسية.
أخطاء شائعة وكيفية تشخيصها
1. وضع الاستعلام على العنصر الخطأ
إذا لم تتغير القواعد، تحقق من أن العنصر المستهدف تابع للحاوية المؤهلة وليس الحاوية نفسها. افحص بنية HTML قبل تغيير عتبة العرض.
2. اختيار عتبة غير مناسبة
لا تنسخ قيمة من مثال آخر دون اختبار. جرّب المكوّن في أضيق وأوسع موضع يظهر فيه، ثم اختر العتبة التي تمنح النص والصورة مساحة حقيقية.
3. تجاهل المحتوى الطويل
الأسماء الطويلة، والأسعار، والترجمات، والروابط قد تكشف تمددًا غير مرغوب. استخدم min-width: 0 عند الحاجة، واسمح بالتفاف النص، ولا تعتمد على ارتفاع ثابت للنصوص.
4. توقع أن الحاوية تحل كل مشكلات التجاوب
لا تزال الصور بحاجة إلى أبعاد مناسبة، والأزرار إلى مساحة قابلة للاستخدام، والتباين إلى مراجعة، والصفحة إلى اختبار على الشاشات المختلفة. الاستعلام يغيّر القواعد ولا يعوض عن التصميم الجيد.
التوافق وخطة الرجوع
أصبحت استعلامات حجم الحاوية مدعومة في المتصفحات الحديثة، لكن المشاريع قد تحتاج إلى دعم إصدارات قديمة أو بيئات مؤسسية محددة. راجع بيانات التوافق عند بدء التنفيذ، واختبر المتصفحات الفعلية التي يستخدمها جمهورك بدل افتراض أن بيئة التطوير تمثل الجميع.
اجعل القاعدة الأساسية مفيدة من دون استعلام، ثم أضف التحسين داخل @container. إذا تجاهل متصفح قديم الاستعلام، سيظل المكوّن قابلًا للاستخدام بتخطيطه الأساسي. لا تعتمد على استعلام الحاوية لإخفاء محتوى ضروري أو لتمرير سلوك لا بد منه.
اختبار المكوّن قبل إعادة استخدامه
- ضع البطاقة في عمود ضيق وآخر واسع.
- اختبر عنوانًا من سطر واحد وآخر طويلًا جدًا.
- جرّب صورة أفقية ومربعة وصورة لا تُحمّل.
- تحقق من اتجاه RTL واللغة ذات الاتجاه LTR إذا كان الموقع متعدد اللغات.
- استخدم لوحة المفاتيح وتأكد من أن التركيز لا يُقص داخل الحاوية.
- افحص التكبير إلى 200% وتأكد من عدم ظهور تمرير أفقي غير ضروري.
تساعد أدوات المطور في معاينة أبعاد الحاوية ومعرفة أي استعلام ينطبق على العنصر. وإذا لم يتغير التخطيط، افحص أولًا ما إذا كانت الحاوية معرفة على العنصر الصحيح، ثم تأكد من أن العنصر الهدف داخلها، وبعد ذلك راجع الشرط العددي.
تسمية الحاويات واختيار الوحدات
عندما يحتوي التصميم على أكثر من حاوية، قد يكون الاستعلام غير المسمى مربكًا. امنح الحاوية اسمًا دالًا على دورها مثل product-card أو sidebar-panel، ثم استخدم الاسم داخل @container. الأسماء الواضحة لا تغيّر النتيجة التقنية فقط، بل تجعل القاعدة أسهل للفهم عندما يعود إليها مطور آخر بعد أشهر.
.dashboard-panel {
container: dashboard-panel / inline-size;
}
@container dashboard-panel (min-width: 32rem) {
.dashboard-panel__actions {
display: flex;
flex-wrap: wrap;
gap: .75rem;
}
}
يمكن استعمال وحدات نسبية في شروط الاستعلام، لكن تذكر أن العتبة يجب أن تعبّر عن احتياج المكوّن لا عن عرض جهاز معين. اختبر عندما يكون النص أكبر أو عندما تتغير إعدادات الخط الافتراضية، ولا تفترض أن 32rem يساوي دائمًا عددًا ثابتًا من البكسلات لدى كل مستخدم.
بناء مكوّن مرن خطوة بخطوة
- اكتب HTML دلاليًا بسيطًا يوضح الصورة والعنوان والوصف والإجراء.
- أنشئ تخطيطًا افتراضيًا عموديًا يعمل في المساحة الضيقة.
- حدد العنصر الذي يملك العرض الفعلي للمكوّن، واجعله حاوية للاستعلام.
- أضف شرطًا واحدًا يغيّر التخطيط عند وجود مساحة كافية.
- اختبر نصوصًا طويلة وصورًا مختلفة، ثم عدّل العتبة إذا ظهر ازدحام.
- راجع لوحة المفاتيح والتكبير واتجاه RTL إن كان المحتوى عربيًا.
هذا التسلسل يمنع تعقيد CSS قبل معرفة المشكلة. لا تضف استعلامات متعددة لتعديل تفاصيل صغيرة يمكن حلها باستخدام التخطيط المرن أو gap أو التفاف العناصر. ابدأ بأقل عدد من الحالات، ثم أضف قواعد أخرى فقط عندما يثبت الاختبار أن المكوّن يحتاج إليها.
ماذا عن استعلامات الأنماط؟
توجد إلى جانب استعلامات الحجم مفاهيم واستعمالات أخرى ضمن Container Queries، لكن لا تجعلها شرطًا لاستخدام الاستعلامات الأساسية. في معظم بطاقات المحتوى، يكون قياس العرض كافيًا لتغيير الأعمدة والمسافات. حافظ على قواعد بسيطة ومدعومة على نطاق واسع، وراجع توثيق المتصفح قبل اعتماد أي ميزة إضافية في مكوّن أساسي. الأهم أن يكون السلوك واضحًا عند غياب التحسين، وأن تظل المعلومات والإجراءات الضرورية متاحة.
تجنب الاعتماد على شكل واحد للمكوّن
قد تبدو البطاقة ممتازة عند عرض 40rem لكنها تصبح مزدحمة قليلًا قبل الوصول إلى العتبة التالية. لذلك لا تختبر نقطة واحدة فقط؛ غيّر العرض تدريجيًا وابحث عن المناطق التي يبدأ فيها النص بالتضييق أو تصبح الصورة صغيرة أكثر من اللازم. ينبغي أن يظل المكوّن متماسكًا قبل شرط @container وبعده، لا أن يقفز من شكل جيد إلى شكل سيئ.
لا تجعل تغيير التخطيط قائمًا على الصورة وحدها. افحص حجم زر الإجراء، وطول العنوان، ووجود شارة أو سعر، واتجاه المحتوى. في العربية، قد يكون عنوان من كلمتين أطول بصريًا من عنوان إنجليزي مماثل، لذلك اختبر المحتوى الفعلي الذي سيظهر في الإنتاج. أضف min-width: 0 للعناصر الشبكية عند الحاجة، واسمح للنص بالالتفاف بدل قصه.
قواعد صيانة للفِرق
وثّق وظيفة كل حاوية وسبب اختيار عتبة العرض، خاصة إذا كان المكوّن يستخدم في صفحات متعددة. لا تسمِّ الحاويات أسماء عامة مثل container1؛ استخدم اسمًا يصف المكوّن. وتجنب أن تتولى قواعد الصفحة وقواعد المكوّن مسؤولية التنسيق نفسه في الوقت ذاته، لأن ذلك يجعل نتائج الاستعلامات صعبة التوقع.
إذا تغيّر التصميم لاحقًا، عدّل المكوّن واختبر جميع مواضع استخدامه بدل إضافة استثناء محلي لكل صفحة. اجعل HTML يعبّر عن المحتوى، وCSS عن التخطيط، واستعلام الحاوية عن نقطة التحول الداخلية. هذا الفصل يقلل الترابط ويجعل إعادة الاستخدام أكثر أمانًا.
متى لا تحتاج إلى Container Queries؟
إذا كان المكوّن لا يغيّر تخطيطه داخل المساحات المختلفة، أو كان Flexbox مع التفاف العناصر يحقق النتيجة المطلوبة ببساطة، فلا تضف استعلام حاوية لمجرد استخدام ميزة حديثة. كل شرط إضافي يحتاج إلى اختبار وصيانة. استخدم التقنية عندما يكون عرض الحاوية هو العامل الحقيقي الذي يحدد شكل المكوّن، واجعل أبسط حل واضح هو الخيار الأول.
مبدأ أساسي
صمّم المكوّن أولًا ليكون مفهومًا وقابلًا للاستخدام في أصغر مساحة معقولة، ثم حسّنه عندما تتوفر مساحة أكبر. لا تجعل المساحة الواسعة شرطًا لعرض المحتوى أو الوصول إلى الإجراء الأساسي. بهذه القاعدة يصبح المكوّن مرنًا، ويظل سلوكه متوقعًا عند إعادة استخدامه في صفحات لم تُصمم وقت إنشاء المكوّن.
مصادر موثوقة
تحديد مسؤولية الحاوية
Container Queries مفيدة عندما يتغير شكل المكوّن بحسب المساحة التي وُضع فيها، مثل بطاقة داخل عمود جانبي أو شبكة. ضع container-type: inline-size على العنصر الذي يملك مساحة التخطيط، ثم اجعل قواعد @container تعدّل المكوّن الداخلي. لا تضف حاوية جديدة لكل عنصر دون حاجة؛ اختر حدًا واضحًا بين المكوّن والصفحة.
.card-region { container-type: inline-size; }
.card { display: grid; gap: 1rem; }
@container (min-width: 34rem) {
.card { grid-template-columns: 9rem 1fr; align-items: start; }
}اختبر المكوّن في سياقات متعددة العرض، لا على الصفحة الرئيسية فقط. تحقق من أن الصور والنصوص الطويلة لا تتجاوز الحاوية، وأن التصميم الأساسي يبقى مفهومًا قبل تفعيل القاعدة المتقدمة.
الخلاصة
الخلاصة: اختر container queries عندما ينبغي أن يستجيب المكوّن لمساحة الحاوية، واختبره في سياقات عرض متعددة. لا تستخدمها بدل media queries عندما يكون القرار متعلقًا بالصفحة كلها.