پایه‌ای‌ترین مفهوم Flexbox: Flex Container و Flex Item

وارد فصل دوازدهم شدیم؛ فصلی که به یکی از قدرتمندترین و پرکاربردترین سیستم‌های چیدمان در CSS مدرن اختصاص داره: Flexbox. قبل از هر Property خاصی، باید دو مفهوم پایه رو کاملاً درک کنیم: Flex Container و Flex Item؛ چون تمام مباحث این فصل، حول همین دو مفهوم می‌چرخه.

Flexbox چه مشکلی را حل می‌کند؟

تا اینجا با روش‌های مختلفی برای چیدمان آشنا شدیم: Normal Flow (فصل ۵) و Positioning (فصل ۱۰). اما این روش‌ها برای کارهایی مثل «چند عنصر رو در یک ردیف، با فاصله مساوی از هم، کنار هم بچین» یا «این عنصر رو دقیقاً وسط والدش قرار بده»، یا خیلی پیچیده بودن یا اصلاً امکان‌پذیر نبودن. Flexbox (مخفف Flexible Box) دقیقاً برای حل همین دسته از مسائل چیدمان یک‌بعدی (در یک ردیف یا یک ستون) طراحی شده.

display: flex چه کاری انجام می‌دهد؟

.container {
  display: flex;
}

وقتی display: flex روی یک عنصر تعریف بشه، دو اتفاق مهم هم‌زمان می‌افته: اول، خود این عنصر تبدیل به یک Flex Container (ظرف Flex) می‌شه؛ دوم، تمام فرزندان مستقیم این عنصر، به‌طور خودکار و بدون نیاز به هیچ Property اضافه‌ای، تبدیل به Flex Item (آیتم Flex) می‌شن.

یک مثال ساده برای دیدن اولین تأثیر

.container {
  display: flex;
}
<div class="container">
  <div>آیتم اول</div>
  <div>آیتم دوم</div>
  <div>آیتم سوم</div>
</div>

در فصل ۵ دیدیم که div، به‌طور پیش‌فرض display: block داره؛ یعنی هر کدوم یک خط جدا رو اشغال می‌کنن و زیر هم چیده می‌شن. اما به‌محض اینکه والدشون (.container) مقدار display: flex بگیره، این سه div، بدون هیچ تغییر دیگه‌ای در کدشون، به‌طور خودکار کنار هم و در یک ردیف افقی قرار می‌گیرن. این، اولین و ساده‌ترین تأثیر Flexbox‌ه.

Flex Container: چه کسی این نقش را می‌گیرد؟

هر عنصری که مقدار display‌ش برابر flex (یا inline-flex، که در ادامه می‌بینیم) باشه، به‌طور خودکار تبدیل به یک Flex Container می‌شه. این عنصر، مسئول تعریف قوانین کلی چیدمان برای فرزندانشه؛ یعنی جهت چیدمان، نحوه توزیع فضا، و ترازبندی، همگی از طریق Propertyهایی تعریف می‌شن که روی همین Flex Container قرار می‌گیرن (نه روی فرزندانش).

Flex Item: چه کسی این نقش را می‌گیرد؟

هر فرزند مستقیم یک Flex Container، به‌طور خودکار تبدیل به یک Flex Item می‌شه. نکته مهم اینجاست: فقط فرزندان مستقیم؛ نه نوه‌ها یا سطوح عمیق‌تر.

.container {
  display: flex;
}
<div class="container">
  <div>
    آیتم اول (Flex Item است)
    <p>این پاراگراف، Flex Item نیست؛ چون فرزند مستقیم container نیست.</p>
  </div>
  <div>آیتم دوم (Flex Item است)</div>
</div>

در این مثال، دو div که مستقیماً داخل .container قرار دارن، Flex Item محسوب می‌شن. اما تگ p که داخل اولین div قرار داره (یعنی یک سطح عمیق‌تر)، اصلاً Flex Item نیست و از قوانین Flexbox پیروی نمی‌کنه؛ این تگ، طبق همون Normal Flow معمولی (که در فصل ۵ دیدیم) رفتار می‌کنه.

تغییرات خودکار روی Flex Itemها

وقتی یک عنصر تبدیل به Flex Item می‌شه، بعضی از رفتارهای پیش‌فرضش تغییر می‌کنه؛ حتی بدون این‌که خودمون مستقیماً Property خاصی روش تعریف کرده باشیم:

  • مقدار display اصلی عنصر (مثلاً block یا inline) دیگه اهمیتی نداره؛ همه Flex Itemها، صرف‌نظر از نوع اصلی‌شون، رفتار یکسانی از نظر چیدمان دارن.
  • Flex Itemها به‌طور پیش‌فرض، در یک ردیف افقی (نه زیر هم) قرار می‌گیرن؛ جهت دقیق این چیدمان رو با Property به اسم flex-direction، که در درس بعدی می‌بینیم، کنترل می‌کنیم.
  • عرض پیش‌فرض Flex Itemها، دیگه لزوماً کل عرض والد نیست (برخلاف رفتار معمول عناصر Block)؛ بلکه بر اساس محتوای داخلی و Propertyهای مخصوص Flex (که در درس‌های بعدی می‌بینیم) محاسبه می‌شه.

display: inline-flex

.container {
  display: inline-flex;
}

علاوه بر flex، یک مقدار دیگه هم به اسم inline-flex وجود داره. تفاوتش با flex، دقیقاً مشابه تفاوتی‌ست که در فصل ۵ بین block و inline-block دیدیم: خود Flex Container، در این حالت، مثل یک عنصر Inline رفتار می‌کنه (یعنی در جریان متن قرار می‌گیره و کل عرض والدش رو اشغال نمی‌کنه)، ولی فرزندانش، دقیقاً مثل حالت flex معمولی، طبق قوانین Flexbox چیده می‌شن.

دو محور اصلی: Main Axis و Cross Axis

یکی از مهم‌ترین مفاهیمی که باید از همین ابتدا درک کنیم، وجود دو محور در هر Flex Container‌ه: Main Axis (محور اصلی) و Cross Axis (محور عرضی). این دو محور، پایه‌ی تقریباً تمام Propertyهای دیگه‌ای هستن که در ادامه این فصل می‌بینیم (مثل justify-content و align-items). به‌طور پیش‌فرض، Main Axis افقیه (از چپ به راست) و Cross Axis عمودیه (از بالا به پایین)؛ اما این جهت‌ها، با Property به اسم flex-direction، که در درس بعدی به‌طور کامل بررسیش می‌کنیم، کاملاً قابل تغییرن.

یک مثال بصری برای جمع‌بندی

.toolbar {
  display: flex;
  background-color: #f5f5f5;
  padding: 8px;
}

.toolbar div {
  padding: 8px 16px;
  background-color: white;
  border: 1px solid #ddd;
}
<div class="toolbar">
  <div>خانه</div>
  <div>درباره</div>
  <div>تماس</div>
</div>

در این مثال، .toolbar یک Flex Container‌ست و سه div داخلش، بدون هیچ Property اضافه‌ای، به‌طور خودکار به‌صورت یک نوار ابزار افقی و کنار هم چیده می‌شن؛ چیزی که قبل از Flexbox، معمولاً نیاز به روش‌های پیچیده‌تر (مثل Float یا حتی جدول) داشت.

نکات مهم

  • display: flex یک عنصر را به Flex Container تبدیل می‌کند و تمام فرزندان مستقیمش را به‌طور خودکار به Flex Item تبدیل می‌کند.
  • فقط فرزندان مستقیم Flex Container، Flex Item محسوب می‌شوند؛ نه نوه‌ها یا سطوح عمیق‌تر.
  • هر Flex Container دو محور دارد: Main Axis و Cross Axis؛ که جهت پیش‌فرض‌شان به‌ترتیب افقی و عمودی است.

اشتباهات رایج

  • تصور اینکه display: flex روی تمام فرزندان تودرتو (نه فقط فرزندان مستقیم) اثر می‌گذارد.
  • فراموش کردن اینکه display اصلی خود عنصر (block یا inline)، بعد از تبدیل شدن به Flex Item، دیگر رفتار قبلی خودش را ندارد.
  • قاطی کردن flex و inline-flex؛ تفاوتشان فقط در رفتار خود Container نسبت به بیرون است، نه رفتار فرزندان داخلش.

جمع‌بندی

display: flex یک عنصر را به Flex Container تبدیل می‌کند و فرزندان مستقیم آن، به‌طور خودکار، بدون نیاز به هیچ Property اضافه‌ای، تبدیل به Flex Item می‌شوند. هر Flex Container دو محور اصلی دارد: Main Axis و Cross Axis، که پایه‌ی تمام مفاهیم بعدی این فصل خواهند بود. مقدار inline-flex، رفتار مشابهی برای فرزندان ایجاد می‌کند، ولی خود Container را مثل یک عنصر Inline نمایش می‌دهد.