طراحی وب با HTML و CSS فهرست مطالب
فصل ۱۱

گرید: چیدمان دوبعدی

فلکس‌باکس در یک بُعد عالی است. گرید برای وقتی است که هم ستون و هم ردیف را هم‌زمان می‌خواهید کنترل کنید.

در این فصل با این مباحث آشنا می‌شوید
  1. گرید چیست و کجا بهتر از فلکس است
  2. ستون‌ها و واحد fr
  3. ردیف‌ها و فاصله
  4. اشغال چند خانه
  5. نام‌گذاری نواحی
  6. نمونه نهایی فصل

۱. گرید چیست و کجا بهتر از فلکس است

فلکس‌باکس یک‌بعدی است: یا در یک ردیف کار می‌کند یا در یک ستون. گرید دوبعدی است و هم‌زمان ستون‌ها و ردیف‌ها را می‌سازد و کنترل می‌کند.

موقعیتابزار بهتر
یک ردیف دکمه یا لینکفلکس‌باکس
سربرگ با لوگو در یک سو و منو در سوی دیگرفلکس‌باکس
گالری تصاویر با سطر و ستون منظمگرید
چیدمان کلی صفحه: سربرگ، کناری، محتوا، پاورقیگرید

این دو رقیب هم نیستند و در یک صفحه واقعی هر دو را با هم به کار می‌بریم: گرید برای اسکلت کلی صفحه و فلکس‌باکس برای جزئیات داخل هر بخش.

<div class="grid">
    <div class="item">۱</div>
    <div class="item">۲</div>
    <div class="item">۳</div>
    <div class="item">۴</div>
</div>
.grid {
    display: grid;
}

اولین گرید: نمونه 01-display-grid-intro

شرح مثال

درست مانند فلکس‌باکس، display: grid را روی ظرف می‌نویسیم و فرزندان مستقیمش آیتم می‌شوند. تنها با همین یک خط، آیتم‌ها هنوز زیر هم هستند، چون هنوز نگفته‌ایم چند ستون می‌خواهیم. آن قدم بعدی است.

۲. ستون‌ها و واحد fr

.three-equal {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
}

.sidebar-layout {
    display: grid;
    grid-template-columns: 250px 1fr;
}

.mixed {
    display: grid;
    grid-template-columns: 2fr 1fr 1fr;
}

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

ستون‌ها: نمونه 02-grid-template-columns

شرح مثال

grid-template-columns ستون‌ها را می‌سازد. تعداد مقادیری که می‌نویسید، تعداد ستون‌هاست و هر مقدار، عرض یک ستون است. پس 1fr 1fr 1fr یعنی سه ستون مساوی.

واحد fr مخفف fraction یعنی «کسر» و مخصوص گرید است. معنی‌اش «یک سهم از فضای باقی‌مانده» است. اگر بنویسید 2fr 1fr 1fr، فضا به چهار سهم تقسیم می‌شود و ستون اول دو سهم و بقیه هر کدام یک سهم می‌گیرند.

چرا fr بهتر از درصد است

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

می‌شود واحدها را ترکیب کرد. در 250px 1fr ستون اول همیشه دویست و پنجاه پیکسل می‌ماند و ستون دوم هر چه باقی ماند را می‌گیرد. این دقیقاً همان چیدمان نوار کناری است که در فصل هشتم با فلکس ساختیم، اینجا تنها ساده‌تر.

repeat(4, 1fr) هم تنها یک میان‌بر نوشتاری است و معادل 1fr 1fr 1fr 1fr. برای گریدهای دوازده‌ستونه این میان‌بر واقعاً به کار می‌آید.

۳. ردیف‌ها و فاصله

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

.grid2 {
    display: grid;
    grid-template-columns: 1fr 1fr;
    row-gap: 30px;
    column-gap: 10px;
}

ردیف‌ها و فاصله: نمونه 03-grid-template-rows-gap

شرح مثال

grid-template-rows ارتفاع ردیف‌ها را مشخص می‌کند و دقیقاً مانند ستون‌ها کار می‌کند.

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

gap همان چیزی است که در فصل هشتم برای فلکس دیدیم و اینجا هم دقیقاً همان‌طور کار می‌کند. نسخه‌های جداگانه‌اش row-gap و column-gap هستند، یا با دو مقدار: gap: 30px 10px که اولی فاصله سطرها و دومی فاصله ستون‌هاست.

۴. اشغال چند خانه

تا اینجا هر آیتم یک خانه می‌گرفت. حالا می‌خواهیم بعضی آیتم‌ها بزرگ‌تر باشند و چند خانه را اشغال کنند.

.grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 15px;
}

.wide {
    grid-column: span 2;          /* دو ستون بگیر */
}

.full {
    grid-column: 1 / -1;          /* تمام عرض */
}

.tall {
    grid-row: span 2;             /* دو ردیف بگیر */
}

.big {
    grid-column: span 2;
    grid-row: span 2;             /* بزرگ در هر دو جهت */
}

اشغال چند خانه: نمونه 04-grid-column-row-span

شرح مثال

این دو ویژگی روی آیتم نوشته می‌شوند، نه روی ظرف. این را یادتان باشد؛ همان تقسیم‌بندی ظرف و آیتم که در فلکس‌باکس داشتیم، در گرید هم برقرار است.

گالری تصاویر حرفه‌ای

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

۵. نام‌گذاری نواحی

این زیباترین قابلیت گرید است: می‌توانید به هر ناحیه یک نام بدهید و بعد نقشه صفحه را به شکل یک تصویر متنی بکشید.

.layout {
    display: grid;
    grid-template-columns: 200px 1fr;
    grid-template-rows: auto 1fr auto;
    gap: 15px;
    min-height: 100vh;

    grid-template-areas:
        "header  header"
        "sidebar content"
        "footer  footer";
}

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

نام‌گذاری نواحی: نمونه 05-grid-template-areas

شرح مثال

روش کار سه مرحله دارد:

  1. در ظرف، با grid-template-areas نقشه را می‌کشید. هر رشته داخل گیومه یک ردیف است و هر کلمه داخل آن، یک خانه.
  2. نام تکراری یعنی آن ناحیه کشیده می‌شود. در ردیف اول، header دو بار آمده، پس سربرگ هر دو ستون را می‌گیرد.
  3. به هر عنصر با grid-area می‌گویید در کدام ناحیه بنشیند.

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

قدرت واقعی این روش

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

۶. نمونه نهایی فصل

<body>

    <div class="layout">

        <header class="site-header">
            <h1>گالری هنری</h1>
        </header>

        <aside class="site-sidebar">
            <h3>دسته‌ها</h3>
            <p>نقاشی</p>
            <p>عکاسی</p>
        </aside>

        <main class="site-content">
            <div class="gallery">
                <div class="pic big">۱</div>
                <div class="pic">۲</div>
                <div class="pic">۳</div>
                <div class="pic wide">۴</div>
                <div class="pic">۵</div>
            </div>
        </main>

        <footer class="site-footer">
            <p>مؤسسه فنی و آموزشی کادوس</p>
        </footer>

    </div>

</body>
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    font-family: Tahoma, sans-serif;
}

body {
    background-color: #f5f5f5;
    line-height: 1.9;
}

/* گرید بیرونی: اسکلت کل صفحه */
.layout {
    display: grid;
    grid-template-columns: 220px 1fr;
    grid-template-rows: auto 1fr auto;
    grid-template-areas:
        "header  header"
        "sidebar content"
        "footer  footer";
    gap: 15px;
    min-height: 100vh;
    padding: 15px;
}

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

.site-header,
.site-footer {
    background-color: #2f4f4f;
    color: white;
    padding: 20px;
    border-radius: 10px;
}

.site-sidebar {
    background-color: white;
    padding: 20px;
    border-radius: 10px;
}

.site-sidebar h3 {
    color: #2f4f4f;
    margin-bottom: 10px;
}

/* گرید درونی: خود گالری */
.gallery {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 12px;
}

.pic {
    background-color: #2f4f4f;
    color: white;
    border-radius: 10px;
    min-height: 130px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 24px;
}

.pic.big {
    grid-column: span 2;
    grid-row: span 2;
}

.pic.wide {
    grid-column: span 2;
}

نمونه نهایی فصل: نمونه 06-final-example

شرح مثال

در این صفحه دو گرید تودرتو داریم و این نکته مهمی است:

در grid-template-rows بیرونی از سه مقدار auto 1fr auto استفاده کرده‌ایم. یعنی سربرگ و پاورقی به اندازه محتوایشان ارتفاع بگیرند و ردیف وسط تمام فضای باقی‌مانده را. همراه با min-height: 100vh، نتیجه‌اش پاورقی‌ای است که همیشه پایین صفحه می‌ماند، حتی وقتی محتوا کم است. این الگو در طراحی سایت بسیار پرکاربرد است.

و توجه کنید که داخل خانه‌های گالری از فلکس‌باکس استفاده کرده‌ایم تا شماره‌ها وسط قرار بگیرند. این همان نکته ابتدای فصل است: گرید برای اسکلت، فلکس برای جزئیات.

فایل‌های تمرینی این فصل

پوشه 11-grid شامل نمونه‌های 01-display-grid-intro تا 06-final-example.

خلاصه فصل

ویژگیروی چهکارش
display: gridظرففعال کردن گرید
grid-template-columnsظرفتعداد و عرض ستون‌ها
grid-template-rowsظرفارتفاع ردیف‌ها. معمولاً لازم نیست.
frواحدیک سهم از فضای باقی‌مانده
repeat(3, 1fr)میان‌برمعادل 1fr 1fr 1fr
gapظرففاصله بین خانه‌ها
grid-column: span 2آیتماشغال دو ستون
grid-column: 1 / -1آیتماشغال تمام عرض
grid-row: span 2آیتماشغال دو ردیف
grid-template-areasظرفکشیدن نقشه صفحه با نام
grid-areaآیتمنشستن در ناحیه نام‌گذاری‌شده

تمرین‌های فصل یازده

  1. یک گالری با چهار ستون مساوی و ده تصویر بسازید.
  2. در همان گالری، دو تصویر را با span بزرگ‌تر کنید.
  3. چیدمان کامل یک صفحه را با grid-template-areas بسازید: سربرگ، کناری، محتوا، پاورقی.
  4. مقدار ستون‌ها را از 1fr 1fr 1fr به 2fr 1fr 1fr عوض کنید و تفاوت را ببینید.
  5. یک بار سه ستون را با درصد بسازید و gap اضافه کنید تا ببینید چرا fr بهتر است.
  6. در یک صفحه، هم گرید و هم فلکس‌باکس را با هم به کار ببرید.
فصل قبل: فرم‌ها فصل بعد: طراحی واکنش‌گرا