ورود به دومین سیستم چیدمان بزرگ CSS: Grid Container و Grid Item

وارد فصل سیزدهم شدیم؛ فصلی که به CSS Grid اختصاص داره، یکی دیگه از سیستم‌های قدرتمند چیدمان در CSS مدرن. در فصل ۱۲ با Flexbox آشنا شدیم که برای چیدمان یک‌بعدی (یک ردیف یا یک ستون) طراحی شده بود. Grid، برخلاف Flexbox، برای چیدمان دوبعدی طراحی شده؛ یعنی می‌تونه هم‌زمان روی ردیف‌ها و ستون‌ها کنترل داشته باشه. این درس، دقیقاً مثل درس ۱۲-۱، به دو مفهوم پایه‌ای‌ترین این فصل اختصاص داره: Grid Container و Grid Item.

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

در Flexbox، وقتی آیتم‌ها به خط بعدی می‌شکستن (با flex-wrap)، هیچ ارتباط مستقیمی بین ستون‌های خط اول و خط دوم وجود نداشت؛ هر خط، مستقل از خط‌های دیگه، فضای خودش رو مدیریت می‌کرد. اما در خیلی از طراحی‌ها (مثل یک جدول محصولات، یا یک چیدمان کامل صفحه با هدر/سایدبار/محتوا/فوتر)، نیاز داریم که ردیف‌ها و ستون‌ها، هم‌زمان و هماهنگ با هم، تعریف بشن؛ دقیقاً همون چیزی که Grid فراهم می‌کنه.

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

.container {
  display: grid;
}

دقیقاً مشابه چیزی که در فصل ۱۲ با display: flex دیدیم، وقتی display: grid روی یک عنصر تعریف بشه، دو اتفاق هم‌زمان می‌افته: خود این عنصر تبدیل به یک Grid Container (ظرف Grid) می‌شه، و تمام فرزندان مستقیمش، به‌طور خودکار، تبدیل به Grid Item (آیتم Grid) می‌شن.

یک تفاوت مهم نسبت به display: flex

.container {
  display: grid;
}
<div class="container">
  <div>آیتم ۱</div>
  <div>آیتم ۲</div>
  <div>آیتم ۳</div>
</div>

نکته مهمی که در همین اولین درس باید بدونیم: برخلاف display: flex که، به‌طور پیش‌فرض، بلافاصله باعث چیده شدن آیتم‌ها در یک ردیف افقی می‌شد، صرف تعریف display: grid، به‌تنهایی، ظاهر چندان قابل‌مشاهده‌ای ایجاد نمی‌کنه. در این مثال، بدون تعریف هیچ ستون یا ردیف مشخصی، هر سه آیتم، همچنان زیر هم (در یک ستون واحد) قرار می‌گیرن؛ چون هنوز به Grid نگفتیم دقیقاً چند ستون یا ردیف باید وجود داشته باشه. این کار، با Propertyهایی مثل grid-template-columns انجام می‌شه که در درس‌های بعدی همین فصل، با جزئیات کامل بررسی‌شون می‌کنیم.

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

هر عنصری که مقدار display‌ش برابر grid (یا inline-grid، که در ادامه می‌بینیم) باشه، به‌طور خودکار تبدیل به یک Grid Container می‌شه. این عنصر، دقیقاً مثل Flex Container، مسئول تعریف قوانین کلی چیدمان (تعداد و اندازه ستون‌ها و ردیف‌ها، فاصله بین‌شون، ترازبندی) برای فرزندانشه.

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

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

دقیقاً همون قانونی که در فصل ۱۲ با Flex Item دیدیم، اینجا هم صادقه: فقط فرزندان مستقیم یک Grid Container، تبدیل به Grid Item می‌شن؛ نه نوه‌ها یا سطوح عمیق‌تر. در این مثال، تگ p که داخل اولین div قرار داره، اصلاً Grid Item نیست.

خط‌های Grid: مفهومی که کل Grid روی آن ساخته می‌شود

یکی از مهم‌ترین مفاهیم Grid که در Flexbox اصلاً وجود نداشت، مفهوم Grid Line (خط شبکه) است. وقتی یک Grid Container با چند ستون و ردیف تعریف می‌شه، این ستون‌ها و ردیف‌ها، توسط یک سری خط فرضی از هم جدا می‌شن؛ این خط‌ها، شماره‌گذاری می‌شن و در درس‌های بعدی همین فصل (مثل grid-column و grid-row)، برای قرار دادن دقیق هر آیتم در محل مشخصی از Grid، ازشون استفاده می‌کنیم. فعلاً فقط لازمه بدونیم که این مفهوم وجود داره؛ جزئیات کاملش رو در همین فصل، به‌تدریج، می‌بینیم.

display: inline-grid

.container {
  display: inline-grid;
}

دقیقاً مثل تفاوتی که در فصل ۱۲ بین flex و inline-flex دیدیم، تفاوت grid و inline-grid اینه که خود Grid Container، در حالت inline-grid، مثل یک عنصر Inline رفتار می‌کنه (یعنی در جریان متن قرار می‌گیره و کل عرض والدش رو اشغال نمی‌کنه)؛ در حالی که فرزندانش، دقیقاً همون رفتار معمول Grid رو دارن.

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

دقیقاً مشابه چیزی که در فصل ۱۲ درباره Flex Itemها دیدیم، تبدیل شدن به Grid Item هم، بعضی از رفتارهای پیش‌فرض یک عنصر رو تغییر می‌ده؛ مثلاً مقدار display اصلی عنصر (مثل block یا inline)، بعد از تبدیل شدن به Grid Item، دیگه به همون شکل قبلی رفتار نمی‌کنه؛ بلکه از قوانین Grid پیروی می‌کنه.

یک مثال ساده برای جمع‌بندی اولیه

.gallery {
  display: grid;
  grid-template-columns: 100px 100px 100px;
  gap: 10px;
}
<div class="gallery">
  <div>آیتم ۱</div>
  <div>آیتم ۲</div>
  <div>آیتم ۳</div>
  <div>آیتم ۴</div>
</div>

در این مثال، با تعریف grid-template-columns (که با جزئیات کامل در درس بعدی می‌بینیم)، حالا Grid دقیقاً می‌دونه باید سه ستون، هرکدوم ۱۰۰ پیکسل، بسازه. آیتم‌ها، به‌طور خودکار، در این ستون‌ها پر می‌شن؛ و وقتی به آیتم چهارم می‌رسیم که دیگه جایی در همون ردیف اول نمونده، Grid، خودش، به‌طور خودکار یک ردیف جدید می‌سازه و آیتم چهارم رو اونجا قرار می‌ده. این رفتار خودکار (که در Grid بهش Auto Placement گفته می‌شه)، رو با جزئیات کامل در درس‌های بعدی همین فصل بررسی می‌کنیم.

مقایسه سریع Flexbox و Grid (پیش‌نمایشی از پایان فصل)

ویژگی Flexbox Grid
بُعد چیدمان یک‌بعدی (یک ردیف یا یک ستون) دوبعدی (ردیف و ستون هم‌زمان)
Container Flex Container Grid Container
Item Flex Item Grid Item
رفتار پیش‌فرض بدون تنظیم اضافه چیدمان فوری در یک ردیف بدون تغییر ظاهری قابل‌توجه (نیاز به grid-template)

مقایسه کامل‌تر و دقیق‌تر این دو سیستم، شامل این‌که چه زمانی از هرکدوم استفاده کنیم، در آخرین درس همین فصل، به‌طور مفصل بررسی می‌شه.

نکات مهم

  • display: grid یک عنصر را به Grid Container تبدیل می‌کند و فرزندان مستقیمش را به‌طور خودکار به Grid Item تبدیل می‌کند.
  • برخلاف display: flex، صرف تعریف display: grid بدون تعریف ستون یا ردیف، تغییر ظاهری قابل‌توجهی ایجاد نمی‌کند.
  • فقط فرزندان مستقیم Grid Container، Grid Item محسوب می‌شوند؛ نه نوه‌ها یا سطوح عمیق‌تر.

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

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

جمع‌بندی

display: grid یک عنصر را به Grid Container تبدیل می‌کند و فرزندان مستقیم آن، به‌طور خودکار، به Grid Item تبدیل می‌شوند؛ برخلاف Flexbox که یک‌بعدی است، Grid برای چیدمان دوبعدی (ردیف و ستون هم‌زمان) طراحی شده است. بدون تعریف صریح ستون‌ها و ردیف‌ها (که در درس‌های بعدی این فصل می‌بینیم)، صرف display: grid، به‌تنهایی، تغییر ظاهری قابل‌توجهی ایجاد نمی‌کند.