Flexbox المتقدم — تصميم CSS
Flexbox: خصائص العناصر
الدرس السابق كان عن الحاوية. هنا نتحكم في كل عنصر: كم يكبر، كم يصغر، ومن أين يبدأ حجمه.
flex-basis: الحجم الابتدائي
الحجم على المحور الرئيسي قبل توزيع المساحة. auto (الافتراضي) يعني: استخدم width (أو حجم المحتوى).
flex-grow: من يأخذ المساحة الزائدة؟
رقم يمثل نصيب العنصر من المساحة الفارغة:
.sidebar { flex-grow: 0; flex-basis: 240px; } /* ثابت */
.main { flex-grow: 1; } /* يأخذ كل ما تبقى */عنصران grow: 1 و grow: 2 — الثاني يأخذ ضعف المساحة الزائدة (لا ضعف الحجم الكلي).
flex-shrink: من يتنازل عند الضيق؟
الافتراضي 1 (كل العناصر تتقلص). flex-shrink: 0 يمنع التقلص — للشعار أو الأيقونة أو الصورة:
.avatar { flex-shrink: 0; width: 48px; }الاختصار flex (استخدمه دائماً)
| الكتابة | تعني | الاستخدام |
|---|---|---|
| flex: 1 | 1 1 0% | أعمدة متساوية تماماً |
| flex: auto | 1 1 auto | تكبر وتصغر لكن تبدأ من حجم محتواها |
| flex: none | 0 0 auto | حجم ثابت حسب المحتوى |
| flex: 0 0 240px | — | عرض ثابت 240px |
.columns { display: flex; gap: 16px; }
.columns > * { flex: 1; } /* ثلاثة أعمدة متساوية مهما كان محتواها */مشكلة min-width: auto
عنصر flex لا يتقلص افتراضياً أصغر من محتواه (كلمة طويلة، رابط، كود). إن خرج النص عن حدوده رغم flex: 1:
.main { flex: 1; min-width: 0; } /* اسمح له بالتقلص */align-self
محاذاة عنصر واحد بخلاف align-items للحاوية:
.card-footer-btn { align-self: flex-end; }margin-inline-start: auto — حيلة مفيدة
الهامش التلقائي داخل flex يبتلع المساحة الفارغة:
.navbar { display: flex; gap: 16px; }
.navbar .login { margin-inline-start: auto; } /* يدفع زر الدخول لنهاية الشريط */order: بحذر
order يغيّر ترتيب العرض فقط. لوحة المفاتيح وقارئ الشاشة يتبعان ترتيب HTML، فيصبح التنقل مربكاً (التركيز يقفز بشكل غير منطقي). استخدمه للتعديلات البصرية البسيطة فقط، والأفضل ترتيب HTML صحيحاً من البداية.
تخطيط: بطاقة أفقية
.media {
display: flex;
gap: 16px;
align-items: flex-start;
}
.media img { flex: 0 0 120px; }
.media .body { flex: 1; min-width: 0; }تمرين
ابنِ تخطيط "قائمة جانبية + محتوى": جانبية flex: 0 0 240px والمحتوى flex: 1. ضع في المحتوى رابطاً طويلاً جداً بلا مسافات ولاحظ المشكلة، ثم أصلحها بـ min-width: 0 و overflow-wrap.
/* flex-grow: توزيع المساحة */
.sidebar {
flex-grow: 0;
width: 250px;
}
.main-content {
flex-grow: 1; /* يأخذ المساحة المتبقية */
}
/* flex-shrink: التحكم بالتصغير */
.logo {
flex-shrink: 0; /* لا يصغر أبداً */
}
/* flex-basis: الحجم الأساسي */
.column {
flex-basis: 33.333%;
}
/* flex المختصر */
.flex-item {
flex: 1; /* grow:1, shrink:1, basis:0 */
}
.fixed-size {
flex: 0 0 200px; /* لا يكبر، لا يصغر، 200px */
}
.flexible {
flex: 1 1 auto; /* يكبر، يصغر، حجم تلقائي */
}
/* align-self: محاذاة فردية */
.special-item {
align-self: flex-end; /* هذا العنصر فقط في الأسفل */
}
/* order: تغيير الترتيب */
.first {
order: 1;
}
.second {
order: 2;
}
.move-to-start {
order: -1; /* قبل الكل */
}
/* مثال عملي: Holy Grail Layout */
.holy-grail {
display: flex;
min-height: 100vh;
}
.holy-grail nav {
flex: 0 0 200px;
order: -1; /* يظهر أولاً رغم أنه في HTML ثانياً */
}
.holy-grail main {
flex: 1;
}
.holy-grail aside {
flex: 0 0 200px;
}اختبر فهمك