الوحدة 2 · تخطيط يصمد
الـ Subgrid لبطاقات متحاذية
17 دقراءة 4 دبيئة تجريب الكود
الدرس في لمحة
استخدم الـ subgrid لتصطفّ أجزاء كل بطاقة جلسة (الوقت والعنوان والملخّص والقاعة) عبر صف البطاقات كله، أيًّا كان طول كل عنوان.
لا فيديو هنا، بل الشيء الحقيقي: درس مكتوب وأمثلة قابلة للتشغيل واختبار وتدريب.
ضع ثلاث بطاقات جلسات من Waypoint جنبًا إلى جنب، وستقفز المشكلة أمامك. عنوانٌ يتّسع في سطر، وآخر يلتفّ على سطرين، وثالث على ثلاثة. كل بطاقة تخطّط محتواها بنفسها، فتبدأ الملخّصات على ثلاثة ارتفاعات مختلفة، وتشكّل تسميات القاعات في الأسفل درجًا. المصمّمون يلاحظون. والمستخدمون يلاحظون أقل، لكن الصفحة تبدو غير مكتملة.
الإصلاحات القديمة كانت ارتفاعات ثابتة (تنكسر مع المحتوى الحقيقي)، أو JavaScript يقيس كل عنوان. أما الـ subgrid (الشبكة الفرعية) فيجعل البطاقات تتشارك مجموعة صفوف واحدة.
لماذا لا تصطفّ الشبكات المتداخلة
حين تصبح البطاقة display: grid، تنشئ tracks خاصة بها ومستقلة. صف العنوان فيها بارتفاع عنوانها هي؛ وصف العنوان في البطاقة المجاورة بارتفاع ذلك العنوان. لا شيء يربط بينهما، لأن كل بطاقة لا تعرف إلا محتواها.
ما تريده هو أن يكون «صف العنوان» track واحدًا تتشاركه كل البطاقات في الصف البصري نفسه، ويتحدّد حجمه بأطول عنوان. وهذا الـ track المشترك يجب أن يعيش في الأب، أي شبكة .sessions، وعلى البطاقات أن تستعيره.
استعارة صفوف الأب
.sessions {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(min(16rem, 100%), 1fr));
gap: 24px;
}
.session-card {
display: grid;
grid-row: span 4; /* time, title, abstract, room */
grid-template-rows: subgrid; /* use the parent's four rows */
row-gap: 8px; /* tighter than the parent's 24px */
}تصريحان يؤدّيان العمل. grid-row: span 4 تجعل كل بطاقة تشغل أربعة صفوف من الشبكة الأب. وgrid-template-rows: subgrid تخبر البطاقة ألّا تنشئ صفوفها الخاصة بل تستخدم الصفوف الأربعة التي تمتدّ عليها. ويوضع أبناء البطاقة الأربعة (الوقت والعنوان والملخّص والقاعة) في صفوف الأب تلك بالترتيب.
الآن يحدّد المتصفّح حجم كل صف في الأب بأطول محتوى وُضع فيه من كل البطاقات في ذلك الصف. يكبر track العنوان ليتّسع للعنوان ذي الأسطر الثلاثة، وتحصل العناوين الأقصر على الـ track نفسه، ويبدأ كل ملخّص على الخط نفسه. وتصطفّ تسميات القاعات في الأسفل.
لاحظ أن الأب لا يعلن grid-template-rows أبدًا. لا يحتاج إلى ذلك: امتداد البطاقات ينشئ صفوفًا ضمنية، وتتحدّد أحجام هذه الصفوف من المحتوى الذي تضعه فيها الـ subgrids. وكل صف جديد من البطاقات يحصل على tracks أربعة خاصة به، فتصطفّ البطاقات في الصف البصري الثاني فيما بينها لا مع الصف الأول، وهذا ما تريده.
الفجوات والخطوط والأعمدة
يرث الـ subgrid الـ gap من الأب. الأب هنا يستخدم 24px بين البطاقات، وهذا أكثر بكثير مما ينبغي بين العنوان وملخّصه، لذا تتجاوز البطاقة row-gap في الـ tracks الخاصة بها. أما المسافة بين البطاقات فلا تتأثّر.
ويعمل الـ subgrid على الأعمدة أيضًا. حالة كلاسيكية في Waypoint هي نموذج الملف الشخصي للمتحدّث: التسميات في عمود، والحقول في العمود التالي، وعمود التسميات بالعرض نفسه عبر عدّة fieldsets. جعل كل fieldset grid-column: span 2; grid-template-columns: subgrid يعطي كل fieldset أعمدة النموذج الخارجي، فتصطفّ التسميات حتى الأسفل. وخطوط الشبكة المسمّاة في الأب مرئية أيضًا داخل الـ subgrid، لذا تظل grid-column: content-start / content-end تعمل بمستوى أدنى.
دورك الآن
يعطيك التمرين ثلاث بطاقات جلسات بعناوين مختلفة الطول. حوّل كل بطاقة إلى subgrid للصفوف لتصطفّ الملخّصات وتسميات القاعات عبر الصف. تقارن الفحوصات المواضع الرأسية لتلك الأجزاء عبر البطاقات. ويبقى الدرس التالي مع الأحجام: min() وmax() وclamp() والكلمات المفتاحية التي تترك للمحتوى أن يقرّر حجم الأشياء.
أهم النقاط
- الشبكة المتداخلة التي لها
grid-template-rows: subgridتستخدم صفوف الـ tracks الخاصة بالأب بدل أن تنشئ صفوفها، فيتشارك المحتوى في البطاقات الشقيقة الصفوف نفسها. - يجب أن يمتدّ العنصر الذي يستخدم الـ subgrid على عدد من tracks الأب يساوي عدد أجزائه، مثل
grid-row: span 4لبطاقة من أربعة أجزاء. - يرث الـ subgrid الفجوة (gap) من الأب افتراضيًا، ويستطيع تجاوزها بـ
row-gapأوcolumn-gapخاصة به. - الـ subgrid ضمن Baseline منذ سبتمبر 2023 ومتاح على نطاق واسع منذ مارس 2026، لذا لم تعد تخطيطات البطاقات المتحاذية تحتاج إلى ارتفاعات ثابتة أو قياسات بـ JavaScript.