بستن

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

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: initial0 1 autoرفتار پیش‌فرض واقعی
flex: auto1 1 autoرشد و کوچیک‌شدن آزاد، پایه = محتوا
flex: none0 0 autoاندازه‌ی کاملاً ثابت، نه رشد نه کوچیک‌شدن
flex: 11 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 یه طرف دیگه، همه هم‌تراز عمودی.

نمونه واقعی ساخت navbar با flexbox شامل justify-content و gap

🎴 مثال واقعی: چیدمان کارت‌های محصول با wrap

.product-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
}

.product-card {
  flex: 1 1 250px;
}

با این ترکیب، کارت‌ها خودکار به تعداد مناسب تو هر ردیف جا می‌گیرن (بسته به عرض صفحه)، و وقتی جا کم بشه، خودکار به خط بعدی می‌رن، بدون نیاز به هیچ Media Query‌ای برای این بخش خاص.

مقایسه رفتار flex-wrap در صفحه عریض و باریک

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

مقایسه بصری تمام مقادیر justify-content در flexbox

⚠️ اشتباهات رایج در کار با Flexbox

  • قاطی کردن justify-content و align-items: justify-content رو محور اصلیه (معمولاً افقی)، align-items رو محور عرضیه (معمولاً عمودی)، اگه flex-direction رو column بذاری، این دو تا جا عوض می‌کنن!
  • فراموش کردن flex-shrink: 0 برای عناصر ثابت:
  • استفاده از margin دستی به‌جای gap: باعث مشکلات لبه‌ی اول/آخر می‌شه که gap اصلاً نداره.
  • انتظار رفتار دوبعدی از Flexbox: Flexbox فقط یک‌بعدیه (یا ردیف یا ستون)؛ برای چیدمان دوبعدی واقعی (هم ردیف هم ستون هم‌زمان)، باید سراغ Grid بری (جلسات بعدی).

📋 جدول جامع نهایی: همه پراپرتی‌های Flexbox در یک نگاه

دستهپراپرتیرو چی اعمال می‌شه؟
Containerdisplay: flexوالد
flex-directionوالد
flex-wrapوالد
flex-flowوالد
justify-contentوالد
align-itemsوالد
align-contentوالد
gap / row-gap / column-gapوالد
Itemorderفرزند
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 تمرین رو ساختی؟ همین پایین برامون بنویس 🚀

شهرام نجفی

شهرام نجفی

شهرام نجفی — بیش از ۱۵ سال طراحی و توسعهٔ وب به‌صورت فریلنس. قالب اختصاصی آوای وب را از صفر نوشته‌ام. مطالب این سایت را بر پایهٔ مستندات رسمی MDN و WHATWG می‌نویسم و قبل از انتشار در مرورگرهای واقعی تست می‌کنم. نمونه‌کارهایم در shahramnajafi.com است.

نظر شما در این مورد چیه؟