وقتی Grid فراتر از نقشه اولیه رشد می‌کند: Implicit و Explicit Grid، Auto Placement

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

Explicit Grid: بخشی که ما مستقیماً تعریف می‌کنیم

.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: 100px 100px;
}

Explicit Grid (شبکه صریح)، به اون بخشی از Grid گفته می‌شه که مستقیماً با grid-template-columns و grid-template-rows تعریف کردیم. در این مثال، Explicit Grid، دقیقاً شامل سه ستون و دو ردیفه؛ یعنی جمعاً شش خانه از پیش تعریف‌شده.

مشکل: چه اتفاقی می‌افتد وقتی آیتم‌ها بیشتر از این خانه‌ها باشند؟

<div class="container">
  <div>آیتم ۱</div>
  <div>آیتم ۲</div>
  <div>آیتم ۳</div>
  <div>آیتم ۴</div>
  <div>آیتم ۵</div>
  <div>آیتم ۶</div>
  <div>آیتم ۷</div>
  <div>آیتم ۸</div>
</div>

در این مثال، هشت آیتم داریم، ولی Explicit Grid فقط شش خانه تعریف کرده. سؤال اینه: آیتم‌های هفتم و هشتم کجا می‌رن؟

Implicit Grid: بخشی که مرورگر خودش می‌سازد

Implicit Grid (شبکه ضمنی)، به ردیف‌ها یا ستون‌های اضافه‌ای گفته می‌شه که مرورگر، به‌طور خودکار، برای جا دادن آیتم‌های اضافی، در انتهای Explicit Grid می‌سازه؛ بدون این‌که ما مستقیماً ازش خواسته باشیم. در مثال بالا، چون فقط دو ردیف Explicit تعریف کردیم ولی هشت آیتم (که در سه‌ستونه، نیاز به سه ردیف کامل داره) داریم، مرورگر، خودش یک ردیف سوم (Implicit) اضافه می‌کنه تا آیتم‌های هفتم و هشتم هم جا بشن.

grid-auto-rows: کنترل اندازه ردیف‌های Implicit

.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: 100px 100px;
  grid-auto-rows: 80px;
}

به‌طور پیش‌فرض، ارتفاع ردیف‌های Implicit، بر اساس محتوای داخلشون محاسبه می‌شه (دقیقاً مثل رفتاری که در درس ۱۳-۳ برای عدم تعریف grid-template-rows دیدیم). اما با Property به اسم grid-auto-rows، می‌شه اندازه دقیقی برای تمام ردیف‌های Implicitی که ممکنه در آینده ساخته بشن، از پیش مشخص کرد. در این مثال، ردیف سوم (که Implicit است)، دقیقاً ۸۰ پیکسل ارتفاع خواهد داشت؛ نه یک ارتفاع خودکار و متغیر.

grid-auto-columns: همان مفهوم، برای ستون‌ها

.container {
  display: grid;
  grid-template-rows: repeat(2, 100px);
  grid-auto-flow: column;
  grid-auto-columns: 120px;
}

دقیقاً همون منطق، برای grid-auto-columns هم صادقه؛ با این تفاوت که این Property، وقتی معنا پیدا می‌کنه که Grid، به‌جای ساختن ردیف‌های اضافه، ستون‌های اضافه بسازه؛ که این رفتار، مستقیماً به Property بعدی که می‌بینیم وابسته‌ست.

grid-auto-flow: کنترل جهت رشد Implicit Grid

.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-flow: row;
}

Property به اسم grid-auto-flow، مشخص می‌کنه وقتی آیتم‌های اضافی نیاز به جای جدید دارن، Grid باید در چه جهتی رشد کنه.

مقدار رفتار
row (پیش‌فرض) آیتم‌های اضافی، ردیف‌به‌ردیف، به‌ترتیب پر می‌شوند؛ ردیف‌های جدید Implicit در صورت نیاز ساخته می‌شوند
column آیتم‌های اضافی، ستون‌به‌ستون پر می‌شوند؛ ستون‌های جدید Implicit در صورت نیاز ساخته می‌شوند
dense (معمولاً همراه row یا column) تلاش می‌کند خانه‌های خالی قبلی را نیز، در صورت امکان، با آیتم‌های بعدی پر کند

یک مثال با grid-auto-flow: column

.container {
  display: grid;
  grid-template-rows: repeat(2, 100px);
  grid-auto-flow: column;
}

در این مثال، به‌جای تعریف ستون، فقط دو ردیف Explicit تعریف کردیم؛ و با grid-auto-flow: column، گفتیم که آیتم‌های اضافی، به‌جای ساختن ردیف‌های جدید، باید ستون‌های جدید (Implicit) بسازن. یعنی آیتم‌ها، ابتدا اولین ستون رو (از بالا به پایین، در دو ردیف) پر می‌کنن، بعد به ستون دوم می‌رن، و به همین ترتیب.

Auto Placement: منطق پیش‌فرض چیدن آیتم‌ها

Auto Placement (جایگذاری خودکار)، به کل فرایندی گفته می‌شه که Grid، بدون این‌که ما موقعیت دقیق هر آیتم رو (با grid-column یا grid-area که در درس ۱۳-۵ دیدیم) مشخص کرده باشیم، خودش تصمیم می‌گیره هر آیتم رو کجا بذاره. رفتار پیش‌فرض این فرایند، دقیقاً همون چیزیه که در طول این فصل، بارها بدون اسم بردن ازش دیدیم: آیتم‌ها، به‌ترتیبی که در HTML اومدن، یکی‌یکی، در اولین خانه خالی موجود، قرار می‌گیرن.

ترکیب Auto Placement با آیتم‌های موقعیت‌دهی‌شده

.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
}

.pinned-item {
  grid-column: 2;
  grid-row: 1;
}
<div class="container">
  <div>آیتم اول (خودکار)</div>
  <div class="pinned-item">آیتم ثابت</div>
  <div>آیتم سوم (خودکار)</div>
</div>

می‌شه بعضی آیتم‌ها رو دستی موقعیت‌دهی کرد (مثل .pinned-item)، و بقیه رو به Auto Placement سپرد. در این حالت، Grid، اول جای آیتم‌های ثابت رو رزرو می‌کنه، و بعد، بقیه آیتم‌ها رو، به‌ترتیب، در خانه‌های خالی باقی‌مانده قرار می‌ده.

یک مثال کامل: کارت‌های محصول با ردیف نامحدود

.products {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: 200px;
  gap: 16px;
}

در این مثال، تعداد ستون‌ها (چهار عدد) کاملاً مشخصه، ولی تعداد ردیف‌ها، عمداً تعریف نشده؛ چون تعداد محصولات، ممکنه در آینده تغییر کنه. با grid-auto-rows: 200px، هر ردیف Implicit جدیدی که برای جا دادن محصولات بیشتر ساخته بشه، دقیقاً همون ارتفاع ۲۰۰ پیکسلی رو خواهد داشت؛ بدون نیاز به این‌که از قبل بدونیم دقیقاً چند ردیف لازم می‌شه.

نکات مهم

  • Explicit Grid، بخشی از Grid است که مستقیماً با grid-template-columns و grid-template-rows تعریف می‌شود.
  • Implicit Grid، ردیف‌ها یا ستون‌های اضافه‌ای است که مرورگر، برای جا دادن آیتم‌های بیشتر از ظرفیت Explicit Grid، خودش می‌سازد.
  • grid-auto-flow جهت رشد Implicit Grid را (ردیفی یا ستونی) کنترل می‌کند؛ grid-auto-rows و grid-auto-columns، اندازه این ردیف‌ها یا ستون‌های اضافی را مشخص می‌کنند.

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

  • تصور اینکه Grid، بدون تعریف کافی ردیف یا ستون، آیتم‌های اضافی را نادیده می‌گیرد؛ در حالی که به‌طور خودکار برایشان جا می‌سازد.
  • فراموش کردن grid-auto-rows در چیدمان‌هایی با تعداد آیتم نامشخص، که باعث ارتفاع ناهماهنگ ردیف‌های Implicit می‌شود.
  • قاطی کردن grid-auto-flow: column با grid-template-columns؛ اولی فقط جهت رشد Implicit را کنترل می‌کند، نه ساختار اصلی Grid را.

جمع‌بندی

Explicit Grid، بخشی از ساختار Grid است که مستقیماً توسط ما تعریف می‌شود، در حالی که Implicit Grid، بخش‌های اضافه‌ای است که مرورگر، برای جا دادن آیتم‌های بیشتر از ظرفیت تعریف‌شده، به‌طور خودکار می‌سازد. Propertyهایی مثل grid-auto-rows، grid-auto-columns و grid-auto-flow، امکان کنترل دقیق اندازه و جهت این بخش خودکار را فراهم می‌کنند، و Auto Placement، منطق کلی‌ای است که تعیین می‌کند آیتم‌های بدون موقعیت دستی، دقیقاً کجا قرار بگیرند.