توسعه فرانت‌اند

CSS Grid: راهنمای کامل با مثال‌های عملی

آموزش CSS Grid با نمونه کارت و ناحیه‌های نام‌گذاری‌شده؛ تفاوت auto-fit و auto-fill، کاربرد Subgrid و بررسی سرریز و ترتیب خواندن.

1404/10/28 3 دقیقه مطالعه 2,174 بازدید
CSS Grid: راهنمای کامل با مثال‌های عملی

برای چیدن چند کارت، بدنه مقاله و ستون مطالب مرتبط، لازم نیست موقعیت هر عنصر را با عددهای جدا تنظیم کنیم. CSS Grid ردیف و ستون را در یک محدوده مدیریت می‌کند و اجازه می‌دهد قواعد چیدمان را نزدیک به ساختار صفحه بنویسیم. کار از محتوای مرتب در HTML شروع می‌شود؛ سپس برای نمای عریض و باریک تصمیم می‌گیریم هر بخش چه فضایی بگیرد.

این راهنما چند نمونه آموزشی دارد که می‌توانید جدا از پروژه اصلی امتحان کنید. عددها نقطه شروع آزمایش‌اند و نباید بدون بررسی وارد طراحی نهایی شوند. اگر هنوز تعداد ستون‌ها و رابطه بخش‌های صفحه روشن نیست، ابتدا گرید در طراحی و نظم بصری را بخوانید. شبکه راهنمای طراحی تصمیم بصری شماست و CSS Grid یکی از روش‌های اجرای آن در مرورگر است.

کانتینر، آیتم و خطوط شبکه

عنصری که display: grid می‌گیرد، کانتینر شبکه می‌شود و فرزندان مستقیم آن آیتم‌های شبکه هستند. برای یک فهرست، می‌توان خود فهرست را کانتینر کرد تا اعضای آن آیتم باشند. این رابطه را هنگام دیباگ بررسی کنید؛ اگر یک لایه اضافی دور کارت‌ها دارید، احتمال دارد قواعد جای‌گذاری را روی عنصری نوشته باشید که آیتم مستقیم شبکه نیست.

Track فضای بین دو خط مجاور است؛ یک ستون یا ردیف نمونه آن است. Cell محل تقاطع یک ردیف و ستون است و Area محدوده‌ای است که ممکن است چند خانه را پوشش دهد. این اصطلاح‌ها در راهنمای مفاهیم پایه MDN توضیح داده شده‌اند. هنگام کار، نمایش خطوط شبکه در ابزار توسعه مرورگر کمک می‌کند محدوده واقعی را ببینید.

نمونه اول: فهرست سه‌ستونی

فرض کنید شش کارت معرفی مقاله داریم. نمونه زیر در نمای عریض سه ستون هم‌اندازه می‌سازد. مقدار gap فاصله میان خانه‌ها را تنظیم می‌کند؛ حاشیه بیرونی صفحه را باید جدا تعیین کنید. در این نمونه، ارتفاع ردیف‌ها به محتوا وابسته است تا یک عنوان بلند موجب بریدن متن نشود. فایل را با یک عنوان کوتاه، یک عنوان بلند و تعداد کارت متفاوت امتحان کنید.

کد کامل زیر را در فایل grid-cards.html ذخیره و در مرورگر باز کنید. CSS در بخش style همان فایل قرار دارد. فهرست با کلاس cards کانتینر است و شش عنصر li با کلاس card فرزندان مستقیم و آیتم‌های آن هستند. در عرض کمتر از ۴۸rem یک ستون و از آن عرض به بعد سه ستون و دو ردیف ساخته می‌شود. این نقطه تغییر فقط برای نمونه انتخاب شده است.

<!doctype html>
<html lang="fa" dir="rtl">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>نمونه کارت‌ها با CSS Grid</title>
  <style>
    body {
      margin: 0;
      padding: 1rem;
      font-family: sans-serif;
      line-height: 1.7;
    }
    .cards {
      display: grid;
      grid-template-columns: minmax(0, 1fr);
      gap: 1rem;
      margin: 0;
      padding: 0;
      list-style: none;
    }
    .card {
      min-width: 0;
      padding: 1rem;
      border: 1px solid #cbd5e1;
      border-radius: 0.75rem;
      overflow-wrap: anywhere;
    }
    .card h2 { margin-block: 0 0.5rem; }
    .card p { margin: 0; }
    @media (min-width: 48rem) {
      .cards {
        grid-template-columns: repeat(3, minmax(0, 1fr));
      }
    }
  </style>
</head>
<body>
  <ul class="cards" aria-label="مقاله‌های پیشنهادی">
    <li class="card"><h2>مطلب اول</h2><p>توضیح کوتاه مقاله اول.</p></li>
    <li class="card"><h2>مطلب دوم با عنوان بلندتر</h2><p>توضیح مقاله دوم برای مقایسه ارتفاع کارت‌ها.</p></li>
    <li class="card"><h2>مطلب سوم</h2><p>توضیح کوتاه مقاله سوم.</p></li>
    <li class="card"><h2>مطلب چهارم</h2><p>توضیح کوتاه مقاله چهارم.</p></li>
    <li class="card"><h2>مطلب پنجم</h2><p>توضیح کوتاه مقاله پنجم.</p></li>
    <li class="card"><h2>مطلب ششم</h2><p>توضیح کوتاه مقاله ششم.</p></li>
  </ul>
</body>
</html>

واحد fr سهمی از فضای باقی‌مانده را بیان می‌کند. در نمونه سه سهم برابر داریم. minmax(0, 1fr) اجازه می‌دهد حداقل اندازه track صفر باشد؛ با این حال، رفتار محتوای داخل آن هنوز به بررسی نیاز دارد. اگر آدرس طولانی بدون فاصله دارید، تصمیم مناسب برای شکستن واژه را هم روی متن اعمال کنید. محدود کردن ستون به‌تنهایی تضمین نمی‌کند که هر محتوایی داخل آن جا بگیرد.

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

نمونه دوم: ستون‌هایی که با عرض سازگار می‌شوند

در فهرست کارت‌هایی که تعداد ستون ثابت لازم ندارند، می‌توان حداقل عرض کارت را معرفی کرد و جا دادن ستون‌ها را به شبکه سپرد. نمونه زیر یک نقطه شروع است. حداقل پیشنهادی شانزده rem را با فونت، عنوان و تصویر پروژه خودتان آزمایش کنید. استفاده از min کمک می‌کند حداقل تعیین‌شده از عرض کانتینر باریک‌تر فراتر نرود.

برای این نمونه، همان HTML شش کارت را نگه دارید. قاعده .cards زیر را جایگزین قاعده پایه آن کنید و Media Query سه‌ستونی نمونه قبل را حذف کنید تا روی این چیدمان اثر نگذارد. قواعد .card و سایر سبک‌های نمونه قبل باقی می‌مانند. margin: 0، padding: 0 و list-style: none را هم در قاعده جدید حفظ کنید.

.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr));
  gap: 1rem;
}

این روش به تعداد مشخصی از دستگاه‌ها وابسته نیست. وقتی فضای کافی برای ستون تازه وجود دارد، شبکه آن را جا می‌دهد. عنوان سه‌خطی، کارت بدون عکس و یک تصویر بسیار عریض را هم آزمایش کنید. هدف صرفاً حذف media query نیست؛ اگر رفتار محتوا به تغییر دیگری نیاز دارد، نوشتن یک نقطه تغییر روشن از اصرار بر یک عبارت پیچیده بهتر است.

تفاوت auto-fit و auto-fill

در الگوهای تکرارشونده، auto-fill برای trackهای قابل جا دادن فضا نگه می‌دارد. auto-fit پس از جای‌گذاری، trackهای خالی را جمع می‌کند و فضای باقی‌مانده می‌تواند به trackهای دیگر برسد. این تفاوت وقتی تعداد آیتم‌ها کم است بهتر دیده می‌شود. نمونه را فقط با یک فهرست پر امتحان نکنید؛ دو کارت در یک کانتینر عریض هم بگذارید.

تصویر زیر یک نمایش مفهومی از همین موقعیت است؛ اندازه دقیق خروجی به تعریف ستون و عرض کانتینر بستگی دارد. برای جزئیات نحو و محدودیت‌های تکرار خودکار، مرجع repeat در MDN را بررسی کنید. انتخاب بین این دو مقدار باید بر اساس رفتار مورد انتظار کارت‌ها باشد.

مقایسه مفهومی حفظ ستون خالی با گسترش دو کارت در یک ردیف

نمونه سوم: ناحیه‌های نام‌گذاری‌شده

وقتی یک صفحه چند بخش مشخص دارد، نام دادن به محدوده‌ها خواندن CSS را آسان‌تر می‌کند. در مثال زیر ابتدا همه بخش‌ها زیر هم‌اند و در عرض بزرگ‌تر، مطالب مرتبط کنار بدنه قرار می‌گیرند. HTML را به ترتیب منطقی بنویسید: عنوان، بدنه و سپس مطالب مرتبط. این ترتیب باید بدون CSS هم قابل فهم باشد.

این مثال مستقل از فهرست کارت‌هاست. داخل body فایل نمونه، فهرست قبلی را با HTML زیر جایگزین کنید و CSS چیدمان را در style بگذارید. سه بخش، فرزندان مستقیم layout هستند و کلاس هر بخش با selector مربوط در CSS مطابقت دارد.

<div class="layout">
  <header class="page-header"><h1>راهنمای طراحی صفحه</h1></header>
  <main class="main-content"><h2>متن اصلی</h2><p>محتوای مقاله در این بخش قرار می‌گیرد.</p></main>
  <aside class="related" aria-label="مطالب مرتبط"><h2>مطالب مرتبط</h2><p>معرفی مطالب مرتبط در این بخش قرار می‌گیرد.</p></aside>
</div>
.layout {
  display: grid;
  gap: 1.5rem;
  grid-template-areas: "header" "main" "aside";
}
.page-header { grid-area: header; }
.main-content { grid-area: main; }
.related { grid-area: aside; }

@media (min-width: 52rem) {
  .layout {
    grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
    grid-template-areas: "header header" "main aside";
  }
}

نام‌هایی که یک area را تشکیل می‌دهند باید محدوده مستطیلی بسازند. عدد نقطه تغییر هم برای این نمونه انتخاب شده و نسخه عمومی نیست. در صفحه فارسی با جهت راست‌به‌چپ، جای شروع شبکه را در مرورگر ببینید. جهت متن و ترتیب منبع را آگاهانه تنظیم کنید و فرض نکنید عوض کردن دو نام در قالب، مسئله ترتیب خواندن را حل می‌کند.

Subgrid برای هم‌ترازی بخش‌های داخلی

گاهی چند کارت داریم که عنوان و توضیح آن‌ها باید با خطوط مشترک هم‌راستا شوند. ساختن یک شبکه مستقل در هر کارت لزوماً خطوط داخلی را هماهنگ نمی‌کند. Subgrid به یک آیتم اجازه می‌دهد تعریف ردیف یا ستون والد را برای شبکه داخلی به کار بگیرد. برای استفاده، خود آیتم باید شبکه باشد و محور مورد نیاز را با مقدار subgrid تعریف کند.

پیش از افزودن آن، مشخص کنید دقیقاً کدام بخش‌ها باید مشترک باشند. هم‌تراز کردن همه خطوط یک کارت ممکن است لازم نباشد. راهنمای Subgrid در MDN مثال‌های این رابطه را نشان می‌دهد. سازگاری مرورگرهای هدف پروژه را بررسی کنید و اگر لازم است، یک چیدمان ساده‌تر به‌عنوان مسیر جایگزین داشته باشید.

هم‌ترازی، سرریز و ترتیب خواندن

هم‌ترازی آیتم در خانه با هم‌ترازی کل شبکه در کانتینر فرق دارد. وقتی فضای اضافی می‌بینید، اول مشخص کنید از کدام سطح آمده است. ارتفاع ثابت، حداقل عرض یک تصویر یا متن بدون محل شکست ممکن است علت باشد. با اضافه کردن marginهای پراکنده، نشانه مشکل را پنهان نکنید؛ خطوط شبکه و اندازه محاسبه‌شده عنصر را در ابزار توسعه بررسی کنید.

جای‌گذاری بصری و مقدار dense ممکن است نمایش عناصر را از ترتیب منبع جدا کند. مسیر صفحه‌کلید و خواندن ابزار کمکی را هم آزمایش کنید. راهنمای دسترس‌پذیری Grid این تفاوت را توضیح می‌دهد. برای تصمیم درباره اولویت بخش‌ها، مقاله ترکیب‌بندی بصری همراه مناسبی است.

آزمون قبل از تحویل

برای خطاهای سرریز، یک مسیر بررسی ثابت داشته باشید. ابتدا مرز کانتینر را در ابزار توسعه پیدا کنید، بعد اندازه track و سپس عرض محتوای آیتم را ببینید. ممکن است یک تصویر عرض ذاتی بزرگی داشته باشد یا یک فرزند عرض حداقل تعیین‌شده داشته باشد. اصلاح باید روی همان علت انجام شود. پنهان کردن سرریز کل صفحه می‌تواند اطلاعات یا نشانه فوکوس را از دید خارج کند و مشکل اصلی را باقی بگذارد.

اگر کارت دکمه یا لینک دارد، با صفحه‌کلید بین آن‌ها حرکت کنید. مرز فوکوس باید دیده شود و مسیر حرکت با ترتیب قابل فهم صفحه هماهنگ بماند. سپس یک کارت تازه میان فهرست اضافه کنید و دوباره مسیر را ببینید. این آزمون برای شبکه‌هایی که جای بعضی آیتم‌ها دستی تعیین شده است مفید است؛ جای‌گذاری استثنایی ممکن است پس از تغییر محتوا به بررسی دوباره نیاز داشته باشد.

نمونه نهایی را با یک آیتم، تعداد فرد و تعداد زیاد کارت بررسی کنید. عرض صفحه را پیوسته کم کنید، متن را بزرگ کنید و یک عنوان طولانی بگذارید. در هر حالت، عکس نباید متن را کنار بزند و دکمه نباید از محدوده خارج شود. مشخص کنید ارتفاع کارت باید با محتوا رشد کند یا محدودیت واقعی محصولی دارد؛ سپس همان تصمیم را مستند کنید.

در تحویل، فقط عبارت CSS را ننویسید. رفتار مورد انتظار در عرض باریک، حداقل قابل قبول کارت، ترتیب محتوا و حالت عنوان بلند را هم ثبت کنید. اگر توسعه‌دهنده بعدی بداند چرا ستون خالی حفظ شده یا چرا دو کارت گسترش یافته‌اند، تغییر محتوای تازه را با حدس انجام نمی‌دهد. این توضیح کوتاه از چند استثنای پراکنده در فایل سبک مفیدتر است.

واکنش به این مقاله

اشتراک‌گذاری این مقاله:
دیدگاه‌ها 0
۰ / ۲۰۰۰

هنوز دیدگاهی ثبت نشده

اولین نفری باشید که نظر می‌دهد!