ساخت چیدمان چندستونی با Grid؛ سربرگ، محتوا، ستون کناری و پاورقی

درس 37 از دوره آموزش HTML و CSS ارومیا دیزاین

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

پروژه و پاسخ تمرین: دانلود پروژه درس 37 (ZIP). فایل شامل HTML، استایل اصلی، پاسخ مستقل و راهنمای آزمایش است. ZIP را استخراج و index.html را باز کنید؛ اینترنت و نصب ابزار لازم نیست.

تفاوت این جلسه با شبکه کارت های درس قبل

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

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

ساختار HTML پروژه چندستونی

<div class="layout">
  <header class="site-header">سربرگ</header>
  <main class="content">محتوای اصلی</main>
  <aside class="sidebar">مطالب مرتبط</aside>
  <footer class="site-footer">پاورقی</footer>
</div>

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

ابتدا نسخه تک ستونی را بسازید

.layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-areas:
    "header"
    "content"
    "sidebar"
    "footer";
  gap: 24px;
}

.site-header { grid-area: header; }
.content { grid-area: content; }
.sidebar { grid-area: sidebar; }
.site-footer { grid-area: footer; }

هر رشته در grid-template-areas یک ردیف و هر نام داخل رشته یک خانه را نشان می دهد. اینجا یک ستون داریم و چهار ناحیه زیر هم قرار می گیرند. grid-area روی هر فرزند، آن را به نام متناظر وصل می کند. نام ها باید دقیقا یکسان باشند؛ content با contents متفاوت است. برای نام گذاری ساده از واژه های کوتاه لاتین استفاده کنید تا خواندن کد راحت بماند.

minmax(0, 1fr) اجازه می دهد مسیر انعطاف پذیر از حداقل اندازه مبتنی بر محتوای بلند کوچک تر شود. روی فرزندان هم min-width: 0 می گذاریم و برای رشته بدون فاصله، overflow-wrap: anywhere تعریف می کنیم. این قواعد وظیفه متفاوتی دارند؛ کوچک شدن مسیر به تنهایی یک آدرس طولانی را نمی شکند. جزئیات سرریز را در درس overflow در CSS بخوانید.

تبدیل ساختار به دو ستون در فضای کافی

@media (min-width: 800px) {
  .layout {
    grid-template-columns: minmax(0, 2fr) minmax(220px, 1fr);
    grid-template-areas:
      "header header"
      "content sidebar"
      "footer footer";
  }
}

وقتی عرض viewport حداقل 800px باشد، این قانون فعال می شود. مقدار 800 انتخاب آموزشی این پروژه است؛ برای همه سایت ها استاندارد اجباری نیست. در محصول واقعی، مرز تغییر را با فضای لازم برای محتوا و ستون کناری انتخاب کنید. همچنین media query عرض viewport را بررسی می کند، نه عرض خود والد؛ اگر این نمونه را در یک قاب باریک داخل صفحه عریض بگذارید، باید محدودیت قاب را جدا در نظر بگیرید.

در حالت افقی فارسی و dir برابر rtl، اولین ستون تعریف شده از راست شروع می شود. بنابراین در رشته content sidebar، محتوای اصلی در راست و ستون کناری در چپ قرار می گیرد. نیازی به معکوس کردن ترتیب HTML نیست. در این مثال، هدر و فوتر نام تکراری در دو خانه دارند و هر کدام یک ناحیه مستطیلی تمام عرض می سازند.

نسبت ستون ها؛ چرا 2fr همیشه دو برابر نیست؟

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

.layout > * {
  min-width: 0;
  padding: 24px;
  overflow-wrap: anywhere;
}

* { box-sizing: border-box; }

برای درک تاثیر padding و border، مدل جعبه CSS را مرور کنید. اگر دو ستون را 70 و 30 درصد بگذارید و بعد gap اضافه کنید، مجموع ممکن است از عرض والد بیشتر شود. سهم های fr برای تقسیم فضای باقی مانده مناسب اند؛ با این حال حداقل اندازه ها و محتوای فرزندان را همچنان باید بررسی کنید.

قواعد مهم grid-template-areas

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

/* Valid: two columns in every row */
.layout {
  grid-template-areas:
    "header header"
    "content sidebar"
    "footer footer";
}

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

چیدمان چندستونی با Grid در نمای باریک و عریض با فونت یکان بخ
نسخه باریک یک ستون دارد؛ در فضای کافی، محتوا و ستون کناری کنار هم می نشینند.

شبکه داخل شبکه؛ کارت ها مستقل از صفحه

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

.card { min-width: 0; }

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

در این جلسه سراغ subgrid نمی رویم؛ برای پروژه، استقلال دو شبکه کافی است. اگر داخل کارت به چیدمان عنوان و لینک نیاز دارید، می توانید از روش Flexbox داخل کارت استفاده کنید. مقایسه و انتخاب هدفمند این دو ابزار، موضوع درس 38 خواهد بود.

امتداد یک آیتم با شماره خط

.practice {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 12px;
}

.practice .summary {
  grid-column: 1 / -1;
}

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

این کد برای فهم امتداد است. در پاسخ پروژه، تعریف سه ستون را فقط داخل media query فعال می کنیم تا تمرین در موبایل تک ستونی بماند. اگر برای یک آیتم grid-column: span 3 بخواهید اما شبکه فقط یک ستون داشته باشد، ممکن است ستون های ضمنی بسازید. استفاده از 1 / -1 برای پوشاندن عرض شبکه صریح، در این نمونه روشن تر است.

ارتفاع محتوا را آزاد بگذارید

برای main و aside ارتفاع ثابت تعیین نمی کنیم. وقتی مقاله طولانی شود، ردیف محتوا ارتفاع لازم را پیدا می کند و فوتر پایین آن قرار می گیرد. align-items: start روی والد، در صورت نیاز می تواند جلوی کشیده شدن خود سایدبار در ارتفاع ردیف را بگیرد. این تصمیم ظاهری است؛ متن را برای هم ارتفاع کردن بخش ها حذف نکنید و با hidden محتوای ضروری را نبرید.

برای فاصله بین بخش ها از gap و برای فاصله داخلی از padding استفاده کنید. رنگ پس زمینه و border-radius را با آموزش کادر و گوشه گرد هماهنگ کنید. اندازه نوشته و فاصله سطر نیز باید از اصول خوانایی متن پیروی کنند؛ چندستونی بودن نباید متن را بیش از اندازه باریک کند.

ترتیب خواندن و حرکت با صفحه کلید

جای گذاری با Grid، ترتیب سند را بازنویسی نمی کند. در پروژه، کاربر پس از لینک های سربرگ به لینک های کارت های main و سپس لینک sidebar می رسد. این ترتیب را با Tab آزمایش کنید. اگر برای زیبایی، بخش های تعاملی را در جای دور از ترتیب منطقی نمایش دهید، کاربر ممکن است مسیر فوکوس را غیرمنتظره ببیند. به جای شماره های مثبت tabindex، ترتیب HTML را اصلاح کنید.

نشانه فوکوس را نگه دارید و عنوان ستون کناری را مشخص کنید. درس focus-visible روش نمایش فوکوس را توضیح می دهد. تغییر چیدمان در عرض کم باید همه لینک ها و متن اصلی را در دسترس نگه دارد؛ ناپدید کردن sidebar جای طراحی مناسب نسخه باریک را نمی گیرد.

تمرین مستقل درس 37 و پاسخ

در پروژه، بخش practice در حالت اولیه تک ستونی است. آن را در عرض حداقل 800px سه ستونی کنید و جمع بندی را تمام عرض قرار دهید. زیر این مرز، همه موارد باید در یک ستون بمانند. پاسخ را ابتدا خودتان بنویسید؛ سپس solution.css را بعد از style.css به head اضافه کنید.

<link rel="stylesheet" href="solution.css">
@media (min-width: 800px) {
  .practice {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
  .practice .summary {
    grid-column: 1 / -1;
  }
}

مرز تغییر را در عرض های 799 و 800 پیکسل بررسی کنید. سپس صفحه را در 320 و 1280 پیکسل ببینید. متن یک کارت را بلند کنید و با ابزار Grid مرورگر، خطوط شبکه بیرونی و داخلی را جدا روشن کنید. فایل README روش آزمایش و فعال کردن پاسخ را دارد. تمام کدهای پروژه با اعداد انگلیسی نوشته شده اند.

پرسش های متداول

آیا نام content در grid-area تگ HTML می سازد؟

خیر؛ این نام فقط محل جای گذاری CSS را مشخص می کند. ساختار و نقش معنایی را با تگ های HTML تعیین می کنیم.

چرا الگوی ناحیه ها اعمال نمی شود؟

تطبیق نام ها، تعداد برابر خانه های ردیف ها و مستطیلی بودن هر ناحیه را بررسی کنید. یک خطای الگو می تواند همان declaration را نامعتبر کند.

آیا ترتیب دیداری، ترتیب Tab را هم تغییر می دهد؟

جای گذاری Grid به تنهایی ترتیب سند و پیمایش عادی صفحه کلید را تغییر نمی دهد. ساختار HTML را منطقی نگه دارید.

آیا شبکه کارت ها از خطوط شبکه صفحه استفاده می کند؟

در پروژه این درس خیر؛ شبکه داخلی، خطوط و اندازه گذاری مستقل دارد.

آیا فایل پروژه پاسخ تمرین دارد؟

بله؛ HTML، CSS اصلی، solution.css و راهنمای اجرای آفلاین داخل ZIP هستند.

دانلود پروژه، راهنما و پاسخ تمرین درس 37

در درس 38؛ انتخاب درست بین Flexbox و Grid، این دو ابزار را با مقایسه عملی و پروژه ترکیبی بررسی می کنیم. برای مراجعه فنی، مشخصات رسمی CSS Grid در W3C در دسترس است.

5/5 - (4 امتیاز)

بدون دیدگاه

دیدگاهتان را بنویسید