CSSمبتدی

Flexbox یا Grid در CSS: کدام را کِی استفاده کنیم

Flexbox و Grid هر دو عناصر را چیدمان می‌کنند، اما متفاوت فکر می‌کنند. قانون یک‌بعدی در برابر دوبعدی را یاد بگیرید و با هر کدام چیدمان‌های واقعی بسازید.

جعبه‌های Flexbox در یک سطر، کنار گریدی از جعبه‌ها که در سطرها و ستون‌ها گسترده شده‌اند
در این صفحه

Flexbox و CSS Grid دو سیستم چیدمانِ مدرن در CSS هستند و مبتدی‌ها اغلب می‌پرسند کدام «بهتر» است. جواب صادقانه این است: هیچ‌کدام. آن‌ها مسئله‌های متفاوتی را حل می‌کنند و چیدمان‌های حرفه‌ای از هر دو استفاده می‌کنند، اغلب در یک صفحه.

قانونی که باید به خاطر بسپارید#

Flexbox چیزها را در یک بُعد می‌چیند: یک سطر یا یک ستون.

Grid چیزها را در دو بُعد می‌چیند: سطرها و ستون‌ها، هم‌زمان.

به بیان دیگر: Flexbox محتوامحور است؛ آیتم‌ها تعیین می‌کنند چقدر فضا لازم دارند و کانتینر فضای باقی‌مانده را تقسیم می‌کند. Grid چیدمان‌محور است؛ شما ستون‌ها و سطرها را تعریف می‌کنید و بعد آیتم‌ها را در آن‌ها قرار می‌دهید.

display: flexdisplay: grid ⁧یک محور: یک سطر یا یک ستون⁩⁧دو محور: سطرها و ستون‌ها⁩
Flexbox آیتم‌ها را در امتداد یک محور توزیع می‌کند؛ Grid آن‌ها را هم‌زمان در سطرها و ستون‌ها تراز می‌کند

مبانی Flexbox#

هر عنصری را با display: flex به یک کانتینرِ فلکس تبدیل کنید. فرزندان مستقیمش به آیتم‌های فلکس تبدیل می‌شوند و در یک سطر کنار هم قرار می‌گیرند:

CSS
.toolbar {
  display: flex;
  align-items: center;            /* alignment on the cross axis */
  justify-content: space-between; /* distribution on the main axis */
  gap: 12px;
}

ویژگی‌هایی که ۹۰ درصد مواقع به کار می‌برید:

ویژگی کاری که انجام می‌دهد
flex-direction row (پیش‌فرض) یا column
justify-content فضا را در امتداد محور اصلی تقسیم می‌کند
align-items آیتم‌ها را روی محور عرضی تراز می‌کند
gap بین آیتم‌ها فاصله می‌گذارد
flex-wrap اجازه می‌دهد آیتم‌ها به خط بعد بروند
flex: 1 (روی یک آیتم) آیتم بزرگ می‌شود تا فضای موجود را پر کند

مثال: نوار ناوبری#

HTML
<nav class="navbar">
  <a class="logo" href="/">Brand</a>
  <ul class="links">
    <li><a href="/docs">Docs</a></li>
    <li><a href="/blog">Blog</a></li>
  </ul>
  <a class="button" href="/signup">Sign up</a>
</nav>
CSS
.navbar {
  display: flex;
  align-items: center;
  gap: 24px;
}

.links {
  display: flex;
  gap: 16px;
  margin: 0 auto 0 0;   /* the auto right margin pushes the button to the far right */
  padding: 0;
  list-style: none;
}

ترفند margin خودکار

در یک کانتینر فلکس، margin-left: auto یا margin-right: auto روی یک آیتم، تمام فضای خالیِ آن سمت را جذب می‌کند. این تمیزترین راه برای دور کردن یک آیتم از بقیه است.

مثال: وسط‌چین کردن کامل#

سؤال معروفِ «چطور یک div را وسط‌چین کنم؟» با Flexbox جواب کوتاهی دارد:

CSS
.center {
  display: flex;
  justify-content: center;
  align-items: center;
}

با Grid هم display: grid; place-items: center; همین کار را می‌کند.

مبانی Grid#

Grid وقتی می‌درخشد که بخواهید آیتم‌ها در هر دو جهت تراز شوند. ستون‌ها (و در صورت نیاز سطرها) را روی کانتینر تعریف کنید:

CSS
.gallery {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
}

واحد fr یعنی «یک سهم از فضای آزاد»، پس repeat(3, 1fr) سه ستونِ هم‌اندازه می‌سازد.

مثال: گریدِ کارتِ واکنش‌گرا بدون media query#

این یک خط ارزش حفظ کردن دارد:

CSS
.cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  gap: 24px;
}

معنایش این است: «هر تعداد ستونی که جا می‌شود بساز، هر کدام حداقل ۲۵۰ پیکسل، و آن‌ها را بکش تا سطر پر شود.» روی موبایل یک ستون می‌گیرید و روی یک مانیتور عریض شاید چهار ستون؛ بدون حتی یک media query.

مثال: چیدمان کامل صفحه#

grid-template-areas در Grid به شما اجازه می‌دهد چیدمانتان را به شکل متن بکشید:

CSS
.page {
  display: grid;
  grid-template-columns: 240px 1fr;
  grid-template-rows: auto 1fr auto;
  grid-template-areas:
    "header  header"
    "sidebar main"
    "footer  footer";
  min-height: 100vh;
}

.page > header { grid-area: header; }
.page > aside  { grid-area: sidebar; }
.page > main   { grid-area: main; }
.page > footer { grid-area: footer; }

@media (max-width: 700px) {
  .page {
    grid-template-columns: 1fr;
    grid-template-rows: auto 1fr auto auto;
    grid-template-areas:
      "header"
      "main"
      "sidebar"
      "footer";
  }
}

دقت کنید که نسخهٔ موبایل فقط ناحیه‌ها را جابه‌جا می‌کند. HTML اصلاً تغییری نمی‌کند.

مقایسهٔ کنار هم#

Flexbox Grid
ابعاد یک (سطر یا ستون) دو (سطرها و ستون‌ها)
رویکرد محتوامحور چیدمان‌محور
بهترین کاربرد نوار ناوبری، نوار ابزار، گروه دکمه‌ها، وسط‌چینی چیدمان صفحه، گالری، داشبورد، فرم
اندازه‌دهی آیتم‌ها اندازهٔ خودشان را تعیین می‌کنند و بعد منعطف می‌شوند ستون‌ها و سطرها اندازه را تعیین می‌کنند و آیتم‌ها آن را پر می‌کنند
آیتم‌های هم‌پوشان دشوار آسان: آیتم‌ها را در یک خانه قرار دهید

استفادهٔ هم‌زمان از هر دو#

رابط‌های کاربری واقعی این دو را تودرتو به کار می‌برند. یک الگوی رایج: Grid برای ساختار کلی، Flexbox داخل هر کامپوننت:

CSS
/* Grid arranges the cards */
.cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  gap: 24px;
}

/* Flexbox arranges the content inside each card */
.card {
  display: flex;
  flex-direction: column;
}

.card .footer {
  margin-top: auto;   /* pins the footer to the bottom of every card */
}

Grid همهٔ کارت‌های یک سطر را هم‌قد می‌کند و ترفند margin-top: auto فوتر کارت‌ها را تراز نگه می‌دارد، حتی وقتی مقدار متن کارت‌ها متفاوت است. جزئیاتی کوچک که طراحی را حرفه‌ای نشان می‌دهد.

راهنمای سریع تصمیم‌گیری#

از خودتان بپرسید:

  1. آیتم‌ها را در یک خط می‌چینم؟ از Flexbox استفاده کنید.
  2. لازم است آیتم‌ها در سطرها و ستون‌ها تراز شوند؟ از Grid استفاده کنید.
  3. محتوا باید اندازه را تعیین کند؟ از Flexbox استفاده کنید.
  4. چیدمان باید اندازه را تعیین کند؟ از Grid استفاده کنید.

اگر مطمئن نیستید، برای کامپوننت‌های کوچک با Flexbox و برای هر چیزی که شبیه جدول، گالری یا اسکلت صفحه است با Grid شروع کنید.

جمع‌بندی#

  • Flexbox یک‌بعدی و محتوامحور است و برای کامپوننت‌ها عالی است.
  • Grid دوبعدی و چیدمان‌محور است و برای ساختار صفحه و گالری‌ها عالی است.
  • repeat(auto-fill, minmax(…, 1fr)) بدون media query گریدِ واکنش‌گرا به شما می‌دهد.
  • آن‌ها را ترکیب کنید: Grid برای ساختار، Flexbox داخل اجزا.

ابزار DevTools مرورگرتان را روی هر وب‌سایت مدرنی باز کنید و چیدمان را بررسی کنید. همه‌جا این دو سیستم را در کنار هم پیدا می‌کنید.