آموزش کامل Flexbox در CSS

این جلسه ادامه دوره کامل آموزش CSS آوای وبه. تو جلسه هفتم یاد گرفتیم چطور عناصر رو دقیق جایگذاری کنیم. حالا وقتشه با Flexbox در CSS، یکی از قدرتمندترین و پرکاربردترین ابزارهای چیدمان مدرن، کامل و بدون هیچ استثنایی آشنا بشیم.
آنچه در این مقاله میخوانید:
Flexbox مخصوص چیدمان یکبعدی طراحی شده، یعنی یا یه ردیف، یا یه ستون (نه هر دو همزمان مثل Grid). ولی همین محدودیت باعث شده برای اکثر چیدمانهای روزمره (navbar، کارتها، فرمها، دکمهها) بهترین و سادهترین انتخاب باشه.
🎯 اهداف یادگیری این جلسه
- تمام پراپرتیهای Flex Container رو با هر مقداری که دارن یاد بگیری
- تمام پراپرتیهای Flex Item رو کامل بفهمی
- با
gapو جدیدترین مقادیر مثلsafe/unsafeآشنا بشی - بتونی هر چیدمان واقعی (navbar، کارت، فرم) رو با Flexbox پیادهسازی کنی
📦 شروع: تبدیل یه عنصر به Flex Container
.container {
display: flex; /* یا inline-flex */
}بهمحض گذاشتن display: flex، همهی فرزندهای مستقیم اون عنصر بهطور خودکار به Flex Item تبدیل میشن و از قوانین Flexbox پیروی میکنن. inline-flex دقیقاً همین کارو میکنه، فقط خود کانتینر بهجای block، مثل inline رفتار میکنه.
1️⃣ پراپرتیهای Flex Container (رو والد اعمال میشن)
flex-direction — جهت چیدمان
.container {
flex-direction: row;
}| مقدار | توضیح |
|---|---|
row (پیشفرض) | افقی، از شروع خط (در فارسی: راست به چپ) |
row-reverse | افقی، ولی برعکس (از چپ به راست در فارسی) |
column | عمودی، از بالا به پایین |
column-reverse | عمودی، از پایین به بالا |
💡 نکته RTL: تو سایتهای فارسی، row بهطور خودکار از راست به چپ میچینه (چون جهت صفحه RTLه)، بدون نیاز به هیچ تغییری.
flex-wrap — شکستن به خط بعدی
.container {
flex-wrap: wrap;
}| مقدار | توضیح |
|---|---|
nowrap (پیشفرض) | همه آیتمها تو یه خط میمونن، حتی اگه فشرده بشن |
wrap | وقتی جا نبود، آیتمها به خط بعدی میرن |
wrap-reverse | مثل wrap ولی خطهای جدید از پایین به بالا اضافه میشن |
flex-flow — میانبر direction + wrap
.container {
flex-flow: row wrap;
}دقیقاً معادل نوشتن flex-direction و flex-wrap جدا، فقط کوتاهتر.
justify-content — چیدمان روی محور اصلی (Main Axis)
.container {
justify-content: space-between;
}| مقدار | توضیح |
|---|---|
flex-start (پیشفرض) | آیتمها از ابتدای محور اصلی میچسبن |
flex-end | آیتمها به انتهای محور میچسبن |
center | آیتمها وسط محور جمع میشن |
space-between | فاصلهی مساوی بین آیتمها؛ اولی و آخری به لبه میچسبن |
space-around | هر آیتم فاصلهی مساوی از دو طرف داره (فاصلهی کناریها نصف وسطیهاست) |
space-evenly | همهی فاصلهها (حتی کناریها) کاملاً مساوی |
normal | معادل flex-start در اکثر موارد؛ مقدار پیشفرض واقعی طبق مشخصات |
🆕 start / end | مشابه flex-start/flex-end ولی مستقل از جهت flex، بر پایهی جهت نوشتار سند |
align-items — چیدمان روی محور عرضی (Cross Axis)
.container {
align-items: center;
}| مقدار | توضیح |
|---|---|
stretch (پیشفرض) | آیتمها کشیده میشن تا کل ارتفاع/عرض کراساکسیس رو پر کنن |
flex-start | آیتمها به ابتدای محور عرضی میچسبن |
flex-end | آیتمها به انتهای محور عرضی میچسبن |
center | آیتمها وسط محور عرضی قرار میگیرن |
baseline | آیتمها بر اساس خط پایهی متنشون همتراز میشن |
🆕 safe center / unsafe center | وقتی فضا کم بود، safe از overflow و بریدگی محتوا جلوگیری میکنه |
align-content — چیدمان کل خطوط (وقتی چند خط داری)
.container {
flex-wrap: wrap;
align-content: space-between;
}⚠️ فرق مهم با align-items:align-items هر آیتم رو تو خط خودش تراز میکنه؛ align-content فاصلهی بین کل خطها رو (وقتی flex-wrap: wrap فعاله و بیشتر از یه خط داری) کنترل میکنه. اگه فقط یه خط داشته باشی، align-content معمولاً هیچ اثری نداره.
مقادیرش دقیقاً همونهای justify-contentه: flex-start, flex-end, center, space-between, space-around, space-evenly, stretch (پیشفرض).
🆕 place-content — میانبر justify-content + align-content
.container {
place-content: center space-between;
}مقدار اول برای align-content، مقدار دوم برای justify-content. یه سینتکس کوتاهنویسی مدرن که کمتر شناخته شده.
gap، row-gap، column-gap — فاصله بین آیتمها
.container {
gap: 20px; /* هم ردیف هم ستون */
row-gap: 10px;
column-gap: 20px;
}این جدیدترین و تمیزترین راه برای فاصلهگذاریه، قبلاً مجبور بودن با margin دستی رو هر آیتم این کارو بکنن (که با مشکلات لبههای اول/آخر همراه بود). gap این مشکلات رو کامل حل میکنه و امروز پشتیبانی کامل مرورگری داره.
2️⃣ پراپرتیهای Flex Item (رو فرزندان اعمال میشن)
order — تغییر ترتیب نمایش بدون تغییر HTML
.item-3 {
order: -1;
}پیشفرض همهی آیتمها order: 0ه. هرچی عدد کوچیکتر باشه، زودتر نمایش داده میشه. میتونی منفی هم بدی. این فقط رو نمایش بصری اثر میذاره، نه ترتیب واقعی تو DOM (برای دسترسپذیری، ترتیب خواندهشدن توسط screen reader هنوز طبق HTMLه، نه order).
flex-grow — رشد کردن برای پر کردن فضای خالی
.item {
flex-grow: 1;
}پیشفرض 0ه (رشد نمیکنه). اگه بدی 1، اون آیتم فضای خالی باقیموندهی کانتینر رو میگیره. اگه چند آیتم مقدار متفاوت داشته باشن (مثلاً یکی ۱ و یکی ۲)، فضای اضافه رو بهنسبت این اعداد تقسیم میکنن (دومی دو برابر اولی رشد میکنه).
flex-shrink — کوچیک شدن وقتی جا کم میاد
.item {
flex-shrink: 0;
}پیشفرض 1ه (اجازهی کوچیکشدن داره). اگه بذاریش 0، اون آیتم هرگز کوچیک نمیشه، حتی اگه باعث سرریز (Overflow) بشه، خیلی برای آیکونها یا لوگوهایی که نباید فشرده بشن کاربردیه.
flex-basis — اندازهی پایه قبل از رشد/کوچیکشدن
.item {
flex-basis: 200px;
}مقدار پیشفرض autoه (یعنی اندازهی طبیعی محتوا یا width/height تعیینشده). این مشخص میکنه قبل از اینکه grow یا shrink اعمال بشه، اندازهی اولیهی آیتم چقدر باشه.
flex — شکل کوتاهنویسی (توصیهشده)
.item {
flex: 1 1 200px; /* grow shrink basis */
}| مقدار کوتاهنویسی | معادل کامل | کاربرد |
|---|---|---|
flex: initial | 0 1 auto | رفتار پیشفرض واقعی |
flex: auto | 1 1 auto | رشد و کوچیکشدن آزاد، پایه = محتوا |
flex: none | 0 0 auto | اندازهی کاملاً ثابت، نه رشد نه کوچیکشدن |
flex: 1 | 1 1 0% | پرکاربردترین حالت — همهی آیتمها همعرض میشن |
💡 توصیهی استاندارد صنعت: تقریباً همیشه بهجای نوشتن جدا flex-grow/flex-shrink/flex-basis، از شکل کوتاه flex استفاده کن؛ چون خواناتره و کمتر جا میفته یکیشون رو تنظیم نکنی.
align-self — override کردن align-items فقط برای یه آیتم
.item-special {
align-self: flex-end;
}همون مقادیر align-items رو داره (stretch, flex-start, flex-end, center, baseline)، ولی فقط رو همون یه آیتم خاص اثر میذاره، بدون اینکه align-items کل کانتینر رو تغییر بدی.
🛍️ مثال واقعی: ساخت یه Navbar کامل با Flexbox
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
gap: 16px;
padding: 16px 24px;
}
.nav-links {
display: flex;
gap: 24px;
}
.nav-cta {
flex-shrink: 0;
}این ۳ خط ساده (justify-content + align-items + gap) دقیقاً همون الگویییه که ۹۰٪ نوارهای ناوبری سایتهای امروزی دنیا باهاش ساخته میشن، لوگو یه طرف، لینکهای منو وسط، دکمهی CTA یه طرف دیگه، همه همتراز عمودی.

🎴 مثال واقعی: چیدمان کارتهای محصول با wrap
.product-grid {
display: flex;
flex-wrap: wrap;
gap: 20px;
}
.product-card {
flex: 1 1 250px;
}با این ترکیب، کارتها خودکار به تعداد مناسب تو هر ردیف جا میگیرن (بسته به عرض صفحه)، و وقتی جا کم بشه، خودکار به خط بعدی میرن، بدون نیاز به هیچ Media Queryای برای این بخش خاص.

📊 مقایسه بصری justify-content — همه مقادیر کنار هم

⚠️ اشتباهات رایج در کار با Flexbox
- قاطی کردن justify-content و align-items: justify-content رو محور اصلیه (معمولاً افقی)، align-items رو محور عرضیه (معمولاً عمودی)، اگه flex-direction رو column بذاری، این دو تا جا عوض میکنن!
- فراموش کردن flex-shrink: 0 برای عناصر ثابت:
- استفاده از margin دستی بهجای gap: باعث مشکلات لبهی اول/آخر میشه که gap اصلاً نداره.
- انتظار رفتار دوبعدی از Flexbox: Flexbox فقط یکبعدیه (یا ردیف یا ستون)؛ برای چیدمان دوبعدی واقعی (هم ردیف هم ستون همزمان)، باید سراغ Grid بری (جلسات بعدی).
📋 جدول جامع نهایی: همه پراپرتیهای Flexbox در یک نگاه
| دسته | پراپرتی | رو چی اعمال میشه؟ |
|---|---|---|
| Container | display: flex | والد |
flex-direction | والد | |
flex-wrap | والد | |
flex-flow | والد | |
justify-content | والد | |
align-items | والد | |
align-content | والد | |
gap / row-gap / column-gap | والد | |
| Item | order | فرزند |
flex-grow | فرزند | |
flex-shrink | فرزند | |
flex-basis | فرزند | |
flex (شکل کوتاه) | فرزند | |
align-self | فرزند (override تکآیتمی) |
🧪 تمرین این جلسه
یه navbar کامل با لوگو، ۳ لینک منو و یه دکمه بساز، دقیقاً مثل مثال بالا. بعد یه گرید از ۶ کارت با flex-wrap بساز و صفحه رو کوچیک/بزرگ کن تا رفتار wrap رو ببینی. در پایان، هر ۶ مقدار justify-content رو یکییکی امتحان کن و فرقشون رو با چشم خودت ثبت کن.
❓ سوالات متداول
فرق justify-content و align-items چیه؟
justify-content روی محور اصلی (Main Axis) کار میکنه — که با flex-direction: row معمولاً افقیه؛ align-items روی محور عرضی (Cross Axis) کار میکنه — که معمولاً عمودیه. اگه flex-direction رو column کنی، این دو جا عوض میکنن.
چرا آیتمهای من با flex: 1 همعرض نمیشن؟
محتملترین دلیل اینه که محتوای داخل یکی از آیتمها (مثل یه متن طولانی بدون فاصله یا یه تصویر بزرگ) اجازهی کوچیکشدن کامل رو نمیده. امتحان کن min-width: 0 رو به اون آیتم اضافه کنی.
gap با margin چه فرقی داره؟
gap فقط بین آیتمها فاصله میذاره، نه دور اولی و آخری؛ margin روی هر آیتم جدا اعمال میشه و باید دستی لبههای اول/آخر رو مدیریت کنی (مثلاً با nth-child).
🎯 جمعبندی و قدم بعدی
حالا هر پراپرتی Flexbox در CSS — چه رو کانتینر چه رو آیتمها، رو کامل میشناسی و میتونی هر چیدمان یکبعدی واقعی رو باهاش پیادهسازی کنی. جلسه بعد میریم سراغ CSS Grid، برای چیدمانهای دوبعدی و پیچیدهتر.
جلسه نهم: آموزش کامل CSS Grid ←
💬 نوبت توئه!
کدوم پراپرتی Flexbox برات جدید بود؟ navbar تمرین رو ساختی؟ همین پایین برامون بنویس 🚀
