آموزش جامع و کامل کار با CSS Grid

A Complete Guide to CSS Grid

07 اردیبهشت 1400
آموزش جامع و کامل کار با CSS Grid

تاریخچه ای از طراحی وب و CSS

در سال های اخیر حتما نام CSS Grid را شنیده اید. برای آموزش CSS Grid ابتدا باید کمی در رابطه با تاریخچه موقعیت دهی به عناصر در زبان CSS صحبت کنیم. زبان CSS همیشه در موقعیت دهی به عناصر مختلف و طراحی چیدمان صفحات وب نقش اصلی را داشته است اما هیچ وقت این کار را به خوبی انجام نداده است. در بسیاری از نظرسنجی ها، بسیاری از توسعه دهندگان (مخصوصا توسعه دهندگان backend) به شدت با CSS و درک کارایی آن مشکل دارند. با اینکه احتمالا شما چنین تصوری را نداشتید اما به غیر از طراحان Front-end که کارشان CSS است، دیگر توسعه دهندگان از CSS دل خوشی ندارند!

اگر از توسعه دهندگان قدیمی دنیای وب باشید احتمالا به خاطر دارید که در گذشته و در ابتدای توسعه وب، ما چیزی به نام table grid را داشتیم. در آن سال ها CSS آنچنان ضعیف بود که برای چیدمان صفحات وب سایت خودمان، کل صفحه را به صورت یک جدول (تگ های <table>) در نظر می گرفتیم و با ترفند های عجیب و غریب سایت ها را طراحی می کردیم.

در سال های بعد از آن Flexbox به دنیای طراحی وب معرفی شد و نسبت به table ها کمک بسیار بزرگ تری بود و این دو اصلا قابل مقایسه نیستند اما هنوز هم درد ما را به طور کامل درمان نمی کرد! چرا؟ به دلیل اینکه Flexbox برای طراحی تک بعدی (در یک محور) مناسب بود اما زمانی که کار به طراحی دو بعدی می کشید باعث اضافه نویسی زیادی می شد. در هنگام استفاده از Flexbox مجبور به تعریف Div های بی معنی مختلف هستیم تا بتوانیم عناصر را از دو جهت موقعیت دهی کنیم که خودش باعث افزایش شدید حجم کدهای HTML ما می شد.

CSS Grid یا همان CSS Grid Layout که بین طراحان وب با نام Grid نیز صدا زده می شود، اولین ماژول زبان CSS است که برای طراحی دو بعدی (محور X و Y) طراحی شده است. در واقع CSS Grid تنها راه صحیح طراحی صفحات وب بدون استفاده از ترفندهای مختلف است! آیا باورتان می شود که این همه سال طول کشیده است تا بالاخره به چنین تکنولوژی ساده ای دست پیدا کنیم؟ واقعا عجیب است! البته اینطور نیست که Flexbox دیگر منسوخ شده باشد. امروزه معمولا Flexbox را با Grid ترکیب می کنند تا از قدرت ترکیبی هر دو استفاده کنند. اکثر طراحان وب کارکشته می دانند که این Flexbox و Grid واقعا مکمل یکدیگر هستند.

مخاطبین مقاله آموزش CSS Grid

مقاله آموزش CSS Grid برای تمام افرادی طراحی شده است که به دنبال استفاده از CSS هستند. چه توسعه دهنده back-end باشید و فقط کمی با CSS کار می کنید و چه متخصص front-end باشید، به شما توصیه می کنم این مقاله را مطالعه نمایید گرچه که حجم آن زیاد است اما مطمئن باشید کارتان را بسیار راحت تر می کند. همچنین برای مطالعه این مقاله نیازی به دانش تخصصی از CSS نیست اما آشنایی ساده با عناصر HTML و دستورات ساده CSS به درک شما از مفاهیم ارائه شده در آن کمک می کند. به غیر از آشنایی اولیه با HTML و CSS به هیچ دانش دیگری نیاز ندارد.

در صورتی که می خواهید یادگیری CSS را شروع کنید، پیشنهاد می کنم به جای مطالعه این مقاله ابتدا با مفاهیم پایه ای CSS (مانند padding و margin و box sizing و غیره) آشنا شده و سپس به این مقاله برگردید.

پشتیبانی مرورگرها از CSS Grid

همیشه زمانی که بحث از تکنولوژی جدید می شود، طراحان Front-end نگران پشتیبانی مرورگرها از آن تکنولوژی هستند. با اینکه شاید به تازگی نام Grid را شنیده باشید اما Grid به هیچ عنوان تکنولوژی دیروز یا هفته قبل نیست. با مراجعه به وب سایت caniuse و مشاهده تاریخ پشتیبانی مرورگرها متوجه خواهید شد که از سال 2017 مرورگر کروم (نسخه دسکتاپ و نسخه اندروید)، مرورگر فایرفاکس (نسخه دسکتاپ و نسخه اندروید)، مرورگر سافاری (نسخه دسکتاپ و iOS) و مرورگر Opera همگی از Grid پشتیبانی می کنند. تنها نسخه های 10 و 11 مرورگر Internet Explorer هستند که به طور کامل از Grid پشتیبانی نمی کنند اما اهمیتی ندارد چرا که دیگر کسی با این مرورگر کار نمی کند. همچنین امکان ندارد کاربران از سال 2017 تا به حال (چهار سال پیش!) مرورگر خود را به روز رسانی نکرده باشند، مخصوصا که در اکثر مواقع خود مرورگر به صورت خودکار به روز رسانی می شود.

ساختار کلی CSS Grid

قبل از اینکه بخواهیم به صورت مفصل وارد جزئیات آموزش آموزش CSS Grid بشویم باید با ساختار کلی گرید و برخی از مفاهیم اصلی (مانند grid container و grid item و غیره) آشنا بشوید. من در این قسمت به صورت خلاصه و سریع توضیحاتی را ارائه می کنم و در بخش بعدی به سراغ جزئیات آن می روم بنابراین اگر متوجه چیزی نشدید نگران نباشید.

برای استفاده از Grid ابتدا به یک container (نگهدارنده) نیاز داریم. نگهدارنده عنصری است که دیگر عناصر در آن قرار می گیرند (عنصری با نقش پدری). اولین قدم این است که به نگهدارنده خصوصیت display: grid را بدهیم. با انجام این کار نگهدارنده تبدیل به عنصر پدری grid می شود که به آن grid container و به عناصر داخل آن grid item می گوییم.

در مرحله بعدی باید اندازه ستون ها و ردیف ها را مشخص کنیم که به ترتیب با استفاده از grid-template-columns و grid-template-rows انجام می شوند. این دو خصوصیت CSS لیستی از اندازه های ستون ها و ردیف ها را می گیرند. مقادیر درون این لیست ها با اسپیس (space) از هم جدا می شوند. در مرحله بعدی grid item یا فرزندان نگهدارنده را در آن قرار می دهید و با استفاده از grid-column و grid-row آن ها را تنظیم می کنید. ترتیب نوشتن grid item ها اهمیتی ندارد چرا که CSS Grid می تواند ترتیب آن ها را مشخص کند.

مفاهیم و واژگان آموزش CSS Grid

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

نکته: از این به بعد در این مقاله به grid با نام «شبکه» اشاره خواهد شد.

Grid Container

Grid Container یا نگهدارنده شبکه به عنصر پدری گفته می شود که خصوصیت display: grid را دارد. نگهدارنده پدر مستقیم عناصر درون خود محسوب می شود. در مثال زیر div ای که کلاس container را دارد همان grid container ما است:

<div class="container">

  <div class="item item-1"> </div>

  <div class="item item-2"> </div>

  <div class="item item-3"> </div>

</div>

Grid Item

grid item یا همان فرزندان شبکه به عناصری گفته می شود که مستقیما درون container قرار دارند. در مثال زیر div هایی که کلاس item را دارند یک grid item به شما می آیند اما تگ <p> با کلاس sub-item جزوی از این دسته محسوب نمی شود چرا که فرزند مستقیم نیست:

<div class="container">

  <div class="item"> </div>

  <div class="item">

    <p class="sub-item"> </p>

  </div>

  <div class="item"> </div>

</div>

Grid line

Grid line یا خطوط شبکه همان خطوطی هستند که ساختار شبکه grid را مشخص می کنند. اگر این خطوط عمودی باشند column grid lines (خطوط ستون) نام خواهند داشت و اگر افقی باشند با نام row grid lines (خطوط ردیف) شناخته خواهند شد. در تصویر زیر خط زردی که مشاهده می کنید یک نمونه ساده از خطوط ستون یا column grid lines می باشد:

خطوط شبکه یا grid line در CSS Grid
خطوط شبکه یا grid line در CSS Grid

Grid Cell

grid cell یا خانه های شبکه دقیقا مانند خانه های یک جدول هستند یعنی به فضای بین دو خط ستون و دو خط ردیف یک خانه یا cell می گویند. تصویر زیر یک cell را بین خطوط ردیف ۱ و ۲ و خطوط ستون ۲ و ۳ نمایش می دهد (با رنگ زرد پُر شده است):

خانه های شبکه یا grid cell در CSS Grid
خانه های شبکه یا grid cell در CSS Grid

Grid Track

Grid Track یا شیار شبکه به فضای اشغال شده بین دو خط شبکه (grid line) گفته می شود. شما می توانید آن را به صورت کل یک ستون یا کل یک ردیف از شبکه ببینید. توجه کنید که زمانی که از grid line صحبت می کنیم بحثمان خطوط تعریف کننده ستون و ردیف هستند اما track یا شیار خانه های درون شبکه را شامل می شوند. تصویر زیر این موضوع را به خوبی نمایش می دهد:

شیار های شبکه یا grid track در CSS Grid
شیار های شبکه یا grid track در CSS Grid

Grid Area

grid area یا فضای شبکه به فضای اشغال شده توسط چهار خط شبکه گفته می شود. هر فضای شبکه می تواند هر تعداد خانه شبکه یا grid cell را داشته باشد. تصویر زیر یک فضای شبکه را بین خطوط ردیف ۱ و ۳ و خطوط ستون ۱ و ۳ نمایش می دهد:

فضای شبکه یا grid area در CSS Grid
فضای شبکه یا grid area در CSS Grid

تمام واژگان اصطلاحی کار با Grid همین چند مورد بودند. حالا باید به سراغ دستورات CSS آن برویم.

خصوصیات CSS برای Grid

حالا که با مفاهیم اصلی و بنیادین CSS Grid آشنا شده ایم نوبت به بررسی خصوصیات موجود در CSS Grid می باشد. همانطور که می دانید زبان CSS خصوصیات مختلفی را دارد؛ مثلا background-position یک خصوصیت ساده CSS است که روی عنصر خاصی اعمال می شود و موقعیت تصویر پس زمینه را مشخص می کند. این خصوصیت، یک خصوصیت ساده CSS است و ربطی به Grid ندارد اما Grid ها نیز خصوصیات خاص خودشان را دارند که هم روی نگهدارنده و هم روی فرزندان آن اعمال می شوند. ما می خواهیم در این بخش با تک تک این خصوصیات آشنا شویم.

نکته: خصوصیات CSS برای Grid به دو سطح Level 1 و Level 2 تقسیم می شوند. از آنجایی که خصوصیات Level 2 (سطح دوم) هنوز در هیچ مرورگری پشتیبانی نمی شوند من آن ها را بررسی نخواهم کرد چرا که عملا نمی توانید از آن ها استفاده کنید.

خصوصیات نگهدارنده: تعریف ستون و ردیف

اولین خصوصیتی که برای container یا نگهدارنده در نظر گرفته شده است، خصوصیت display می باشد. display باعث تعریف یک نگهدارنده شده و ساختار اولیه برای استفاده از grid را مشخص می کند. مقادیر ممکن برای این خصوصیت رشته های grid و inline-grid هستند که به ترتیب باعث ساخت یک شبکه block و یک شبکه inline می شوند. به مثال زیر توجه کنید:

.container {

  display: grid;

}




.container {

  display: inline-grid;

}

همانطور که می بینید شما می توانید یکی از این دو گزینه را برای نگهدارنده خود تعریف کنید.

خصوصیت های بعدی grid-template-columns و grid-template-rows هستند که به ترتیب مسئول تعریف کردن ستون ها و ردیف ها هستند. مقادیری که به این دو خصوصیت پاس می دهید باید با اسپیس از هم جدا شده باشند و هر مقدار نشان دهنده اندازه یک ستون یا یک ردیف است اما تمام مقادیر با هم نشان دهنده track size یا اندازه شیار است. از طرف دیگر هر اسپیس نشان دهنده یک خط شبکه (grid line) است. اندازه track یا شیار می تواند در واحد های مختلفی مانند درصد، پیکسل و حتی fr باشد (در مورد واحد fr در ادامه توضیح می دهم).

زمانی که فقط مقادیر مورد نظر خود را به عنوان track size (اندازه شیار) پاس بدهید باید آن ها را با اسپیس از هم جدا کنیم و گفتم که هر اسپیس به معنی یک خط شبکه است. در این حالت CSS این خطوط را به صورت خودکار نام گذاری می کند. به مثال زیر توجه کنید:

.container {

  grid-template-columns: 40px 50px auto 50px 40px;

  grid-template-rows: 25% 100px auto;

}

در ابتدا grid-template-columns را داریم که مقادیر مختلفی را گرفته است. مثلا ابتدا ۴۰ پیکسل را  به آن داده ایم که یعنی ستون اول ۴۰ پیکسل عرض داشته باشد و سپس ستون دوم ۵۰ پیکسل و ستون سوم auto باشد (عرض خودکار) و الی آخر. تمام این مقادیر با هم نشان دهنده اندازه شیار هستند. نتیجه اجرای این کد به شکل زیر خواهد بود:

نتیجه ی اجرای مثال - شماره 1
نتیجه اجرای مثال - شماره 1

با توجه به این تصویر متوجه اندازه های مشخص شده برای هر ردیف و ستون می شوید. همچنین می بینید که هر خط با اعداد مثبت و منفی نام گذاری شده است چرا که ما هیچ نامی را برای این خطوط انتخاب نکردیم. در صورتی که می خواهید نام این خطوط را خودتان انتخاب کنید باید به جای اسپیس از ساختار [name] استفاده کنید. مثال:

.container {

  grid-template-columns: [first] 40px [line2] 50px [line3] auto [col4-start] 50px [five] 40px [end];

  grid-template-rows: [row1-start] 25% [row1-end] 100px [third-line] auto [last-line];

}

با اجرای این کد نتیجه زیر را می گیریم:

نتیجه ی اجرای مثال - شماره 2
نتیجه اجرای مثال - شماره 2

در ضمن در نظر داشته باشید که هر خط می تواند بیشتر از یک نام داشته باشد مثلا:

.container {

  grid-template-rows: [row1-start] 25% [row1-end row2-start] 25% [row2-end];

}

همانطور که می بینید ما به یکی از خطوط دو نام row1-end (پایان ردیف اول) و row2-start (شروع ردیف دوم) را داده ایم. همچنین در صورتی که مقادیر پاس داده شده توسط شما تکراری هستند می توانید از تابع ()repeat در CSS استفاده کنید تا اضافه نویسی نداشته باشید:

.container {

  grid-template-columns: repeat(3, 20px [col-start]);

}

آرگومان اول این تابع تعداد دفعات تکرار است و آرگومان دوم مقداری است که باید تکرار شود. به زبان ساده ۲۰ پیکسل و نام خط باید سه بار تکرار شوند تا سه ستون ۲۰ پیکسلی داشته باشیم. کد بالا دقیقا معادل کد زیر است:

.container {

  grid-template-columns: 20px [col-start] 20px [col-start] 20px [col-start];

}

یکی از واحدهایی که می توانید برای اندازه دهی به این ستون ها و ردیف ها استفاده کنید، fr است که به شما اجازه می دهد اندازه شیار را بر اساس درصدی از فضای خالی container (نگهدارنده) تعیین کنید. به مثال زیر توجه کنید:

.container {

  grid-template-columns: 1fr 1fr 1fr;

}

در این حالت سه ستون خواهیم داشت که هر کدام یک سوم از فضای خالی نگهدارنده را می گیرند. چرا؟ ما به هر ستون 1fr داده ایم، یعنی در مجموع 3fr داریم. 3fr برابر با کل فضای خالی container است بنابراین هر یک fr برابر با یک سوم فضای خالی خواهد بود. البته توجه داشته باشید که fr پس از تخصیص فضا به واحد های ثابت محاسبه می شود. یعنی چه؟ به مثال زیر توجه کنید:

.container {

  grid-template-columns: 1fr 50px 1fr 1fr;

}

در این مثال ابتدا ۵۰ پیکسل از فضای نگهدارنده را به ستون دوم اختصاص می دهیم و سپس فضای باقی مانده را بین fr های دیگر تقسیم می کنیم.

خصوصیات آیتم: ترتیب نمایش فرزندان

در همین ابتدا باید برایتان توضیح بدهم که استفاده از float یا inline-block یا table-cell یا vertical-align و کلاس های *-column هیچ تاثیری در نحوه نمایش آیتم های grid ندارد بنابراین از آن ها برای تصحیح نمایش آیتم ها استفاده نکنید.

در Grid چهار خصوصیت را داریم که مسئول تعیین ترتیب نمایش آیتم ها درون نگهدارنده هستند:

  • grid-column-start: شروع خط ستون
  • grid-row-start: شروع خط ردیف
  • grid-column-end: پایان خط ستون
  • grid-row-end: پایان خط ردیف

مقادیر مختلفی برای پاس دادن به این خصوصیات وجود دارند. اولین مقدار نام خط شبکه (name) یا شماره خط شبکه است تا بدین صورت آن را هدف بگیریم. دومین مقدار ساختار <span <number را دارد، یعنی مقداری که چندین بخش یک track را پوشش می دهد. ما می توانیم تعداد این بخش ها را به صورت عدد به جای number مشخص کنیم. مقدار سوم ساختار <span <name را دارد و مانند حالت قبل است با این تفاوت که به حرکت خود ادامه می دهد تا زمانی که به name (نام خط) برسد. مقدار چهارم auto است که به صورت خودکار اندازه را تعیین می کند و یا اینکه به صورت پیش فرض اندازه ۱ را در نظر می گیرد. احتمالا خیلی گیج شده باشید! بگذارید به صورت عملی آن ها را بررسی کنیم. ساختار کلی استفاده از این چهار خصوصیت به شکل زیر است:

.item {

  grid-column-start: <number> | <name> | span <number> | span <name> | auto;

  grid-column-end: <number> | <name> | span <number> | span <name> | auto;

  grid-row-start: <number> | <name> | span <number> | span <name> | auto;

  grid-row-end: <number> | <name> | span <number> | span <name> | auto;

}

من از خط عمودی | برای جدا کردن این مقادیر استفاده کرده ام اما واقعا آن ها را در CSS نمی نویسیم (در مثال بعدی می بینید). علامت | یعنی «یا» بنابراین فقط یکی از این چهار مقدار را برای این خصوصیات انتخاب می کنیم. یک مثال ساده و عملی به شکل زیر است:

.item-a {

  grid-column-start: 2;

  grid-column-end: five;

  grid-row-start: row1-start;

  grid-row-end: 3;

}

در کد بالا گفته ایم که اندازه آیتم ما (فرزند container) از ستون دوم شروع شده (grid-column-start: 2) و در ستونی به نام five متوقف شود (grid-column-end: five). بنابراین دستور اول که عدد ۲ را دارد از نوع شماره خط شبکه و دستور دوم که five را گرفته است نام خط شبکه است. تا اینجا عرض آیتم را با ستون ها مشخص کرده ایم اما هنوز طول آن (ارتفاع) باقی مانده است که با ردیف ها مشخص می شود. grid-row-start مشخص می کند که شروع آیتم باید از خط ردیفی به نام  row1-start باشد و تا خط ۳ ادامه داشته باشد. نتیجه این کار به شکل زیر خواهد بود:

اشغال محیط خاص با row start و row end
اشغال محیط خاص با row start و row end

حالا بیایید یک مثال از کاربرد span را نیز بزنیم:

.item-b {

  grid-column-start: 1;

  grid-column-end: span col4-start;

  grid-row-start: 2;

  grid-row-end: span 2;

}

در مورد عرض آیتم ما آن را از خط ستون ۱ شروع کرده ایم و با استفاده از span گفته ایم که باید تا خطی به نام col4-start ادامه پیدا کنید. برای ارتفاع آیتم نیز همین کار را کرده ایم و گفته ایم از خط شماره ۲ شروع کرده و تا ۲ خط بعدی ادامه داشته باشد. یادتان باشد زمانی که روبروی span از عدد استفاده کنید به معنی کشیده شدن آیتم به تعداد خطوط آن عدد است اما اگر از نام خط استفاده کنید به معنی کشیده شدن آیتم تا آن خط مشخص است. کد بالا نتیجه زیر را تولید می کند:

اشغال محیطی خاص با column start و column end
اشغال محیطی خاص با column start و column end

در صورتی که آیتم های شما روی هم قرار گرفتند می توانید با استفاده از z-index آن ها را کنترل کنید.

نکته: در صورتی که از grid-column-end یا grid-row-end برای تعیین انتهای آیتم استفاده نشود، آیتم به صورت پیش فرض به اندازه یک واحد (یک خط) کشیده می شود.

خصوصیات آیتم: میانبر طول و عرض آیتم

در grid خصوصیاتی به نام grid-column و grid-row را داریم که خلاصه یا میانبر چهار خصوصیت grid-column-start + grid-column-end, and grid-row-start + grid-row-end هستند. روش استفاده از آن ها نیز مشخص کردن خط ابتدا و خط انتها است و می توانید مقادیر مختلف خودتان را به آن پاس بدهید. ساختار کلی استفاده از این خصوصیت به شکل زیر است:

.item {

  grid-column: <start-line> / <end-line> | <start-line> / span <value>;

  grid-row: <start-line> / <end-line> | <start-line> / span <value>;

}

همانطور که می بینید حتی می توانیم از span نیز استفاده کنیم. به مثال زیر توجه کنید:

.item-c {

  grid-column: 3 / span 2;

  grid-row: third-line / 4;

}

همانطور که قبلا دیدیم عرض آیتم با ستون ها تنظیم می شود بنابراین از grid-column استفاده کرده ایم و گفته ایم از خط شماره ۳ شروع شود و تا دو خط بعدی ادامه پیدا کند. برای ارتفاع عنصر نیز از grid-row استفاده کرده و می گوییم از خطی به نام third-line شروع شود و تا خط شماره ۴ ادامه پیدا کند. نتیجه اجرای این کد به شکل زیر خواهد بود:

اشغال محیطی خاص از روش میانبر
اشغال محیطی خاص از روش میانبر

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

خصوصیات آیتم: نام دهی به آیتم

در grid خصوصیتی به نام grid-area وجود دارد که با استفاده از آن می توانیم به یک آیتم (نه به خط های آن) یک نام دلخواه بدهیم و بعدا آن را با استفاده از خصوصیت دیگری به نام grid-template-areas هدف قرار بدهیم (بعدا در مورد آن صحبت می کنیم). البته علاوه بر نام گذاری آیتم ها می توانیم از این دستور به عنوان روش میانبری برای تمام خصوصیات grid-row-start + grid-column-start + grid-row-end + grid-column-end استفاده کنیم! مقادیر ممکن برای این خصوصیت یا همان نامی است که می خواهید به آیتم خود بدهید و یا مقادیر ابتدا و انتهای برای ستون و ردیف های شبکه. ساختار کلی استفاده از این دستور به شکل زیر است:

.item {

  grid-area: <name> | <row-start> / <column-start> / <row-end> / <column-end>;

}

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

.item-d {

  grid-area: header;

}

با این کار آیتم شما نام header را می گیرد. شما می توانید به جای header هر نام دلخواه دیگری را انتخاب کنید. همچنین حالت دیگر استفاده از آن، روش میانبر است:

.item-d {

  grid-area: 1 / col4-start / last-line / 6;

}

با اجرای این کد چنین نتیجه ای را می گیریم:

اشغال محیطی خاص با نام دهی به خطوط
اشغال محیطی خاص با نام دهی به خطوط

خصوصیات نگهدارنده: ساخت قالب شبکه

شما می توانید با خصوصیتی به نام grid-template-areas یک قالب (template) را برای شبکه grid خود تعریف کنید. این کار با هدف گرفتن نام یک آیتم انجام می شود که با استفاده از grid-area انجام می شد. در این حالت تکرار کردن نام grid-area باعث می شود محتوا در طول آن خانه ها کشیده شود. همچنین علامت نقطه نشان دهنده خانه ای خالی در شبکه است. در واقع اگر به مقادیر این خصوصیت نگاه کنید متوجه می شوید که ظاهر این مقادیر همان ظاهر شبکه را مشخص می کند.

مقادیر ممکن برای این خصوصیت سه مقدار است: اول استفاده از نام یک آیتم که با grid-area تعریف شده بود، دوم استفاده از نقطه برای خالی گذاشتن خانه و سوم none است که به معنی تعریف نشدن grid area است. ساختار کلی این دستور به شکل زیر است:

.container {

  grid-template-areas:

    " | . | none | ..."

    "...";

}

بیایید یک مثال واقعی از این خصوصیت را بررسی کنیم:

.item-a {

  grid-area: header;

}

.item-b {

  grid-area: main;

}

.item-c {

  grid-area: sidebar;

}

.item-d {

  grid-area: footer;

}




.container {

  display: grid;

  grid-template-columns: 50px 50px 50px 50px;

  grid-template-rows: auto;

  grid-template-areas:

    "header header header header"

    "main main . sidebar"

    "footer footer footer footer";

}

همانطور که می بینید من در کدهای بالا به آیتم های item-a و item-b و item-c و item-d نام های دلخواه خودم را داده ام (طبیعتا شما می توانید هر نام دیگری را برایشان انتخاب کنید) که به ترتیب header و meain و sidebar و footer هستند. در مرحله بعدی به سراغ نگهدارنده (container) خود رفته ایم و چهار ستون ۵۰ پیکسلی را تعریف کرده ایم. ردیف ها را نیز روی auto گذاشته ام تا به صورت خودکار تنظیم شوند. بخش مهم برای ما خصوصیت grid-template-areas است که ردیف هایش به صورت سه رشته مختلف مشخص شده اند و در هر رشته از نام های آیتم هایمان (grid-area ها) استفاده کرده ایم. دلیل انتخاب grid-template-rows: auto نیز همین بود! زمانی که تعداد ردیف ها را روی auto می گذاریم می توانیم با تعداد رشته ها در خصوصیت grid-template-areas ردیف هایمان را مشخص کنیم. با این حساب شبکه grid بالا چهار ستون و سه ردیف خواهد داشت. با اجرای کد بالا نتیجه زیر را دریافت می کنید:

تعریف و استفاده از یک قالب برای شبکه
تعریف و استفاده از یک قالب برای شبکه

توجه داشته باشید که هر ردیف پاس داده شده به grid-template-areas (هر رشته ای که به این خصوصیت داده اید) باید دقیقا تعداد خانه های یکسانی داشته باشد. همچنین در این روش نکته مهمی وجود دارد: ما در حال نام گذاری خطوط نیستیم بلکه بخش هایی از شبکه را نام گذاری می کنیم و خطوط به صورت خودکار نام گذاری می شوند. مثلا اگر نام grid area شما foo باشد، نام خط شروع ردیف و خط شروع ستون، foo-start خواهد بود و همچنین نام خط پایان ردیف و خط پایان ستون foo-end در نظر گرفته می شود. این مسئله بدان معنی است که بعضی از خطوط چندین نام مختلف می گیرند. مثلا اولین خط عمودی از سمت چپ در مثال بالا به طور همزمان نام های header-start و main-start و footer-start را دارد.

grid-template برای خلاصه سازی

البته خصوصیتی به نام grid-template وجود دارد که دستور میانبری برای grid-template-rows و grid-template-columns و grid-template-areas است. مقادیر ممکن برای این خصوصیت دو حالت هستند: مقدار none که هر سه خصوصیت را روی مقادیر اولیه شان تنظیم می کند و حالت دوم که تعیین مقدار برای grid-template-columns و grid-template-rows است در حالی که grid-template-areas را روی none می گذارد. ساختار کلی استفاده از این خصوصیت به شکل زیر است:

.container {

  grid-template: none | <grid-template-rows> / <grid-template-columns>;

}

البته شما می توانید از روش زیر برای تعیین مقدار برای هر سه خصوصیت (بدون none کردن grid-template-areas) استفاده کنید. این روش کمی پیچیده است اما اگر آن را یاد بگیرید، کمک خوبی محسوب می شود:

.container {

  grid-template:

    [row1-start] "header header header" 25px [row1-end]

    [row2-start] "footer footer footer" 25px [row2-end]

    / auto 50px auto;

}

این کد به ظاهر پیچیده، دقیقا معادل کد زیر است:

.container {

  grid-template-rows: [row1-start] 25px [row1-end row2-start] 25px [row2-end];

  grid-template-columns: auto 50px auto;

  grid-template-areas:

    "header header header"

    "footer footer footer";

}

خصوصیات نگهدارنده: تعیین فاصله ها

ما در Grid خصوصیت هایی به نام های column-gap و row-gap و grid-column-gap و grid-row-gap را داریم که مسئولیت تعیین gap یا فاصله های بین عناصر و اندازه خطوط شبکه را دارند. البته باید بدانید که grid-column-gap و grid-row-gap خصوصیاتی قدیمی تر هستند و در ادامه در این باره توضیح خواهم داد. هر چه اندازه یک خط بزرگ تر باشد طبیعتا فاصله خانه های شبکه از هم بیشتر می شود. شما می توانید به این خصوصیات به چشم gutter ها در فریم ورک هایی مانند بوت استرپ نگاه کنید. ساختار کلی استفاده از این خصوصیات به شکل زیر است:

.container {

  /* روش استاندارد */

  column-gap: <line-size>;

  row-gap: <line-size>;




  /* روش قدیمی */

  grid-column-gap: <line-size>;

  grid-row-gap: <line-size>;

}

برای درک بهتر می توانید به مثال زیر توجه کنید:

.container {

  grid-template-columns: 100px 50px 100px;

  grid-template-rows: 80px auto 80px;

  column-gap: 10px;

  row-gap: 15px;

}

اجرای این کد چنین نتیجه ای را خواهد داشت:

تعیین فواصل و gutter ها در CSS Grid
تعیین فواصل و gutter ها در CSS Grid

column-gap اندازه فاصله بین ستون ها را مشخص می کند و row-gap اندازه فاصله بین ردیف ها را تعیین می کند. این موضوع در تصویر بالا به خوبی نمایش داده شده است. نکته مهم در رابطه با این دستورات این است که فواصل ایجاد شده در مثال بالا فقط بین ستون ها و بین ردیف ها اعمال می شوند و در حاشیه خارجی اعمال نخواهند شد (مانند margin نیستند).

نکته بسیار مهمی در استفاده از این خصوصیات وجود دارد. باید بدانید که  grid-column-gap و grid-row-gap (پیشوند grid) در آینده نزدیک منسوخ و حذف خواهد شد بنابراین بهتر است به جای این دو خصوصیت از همان column-gap و row-gap استفاده کنید. این خصوصیات در حال حاضر در گوگل کروم ۶۸ به بعد پشتیبانی می شود بنابراین مشکلی نخواهید داشت.

در صورتی که بخواهید خصوصیات column-gap و row-gap را به یک اندازه در نظر بگیرید یا اگر می خواهید کدهایتان را تمیز تر بنویسید، بهتر است از دستور خلاصه آن ها، یعنی gap و grid-gap استفاده کنید. تفاوت این دو دستور نیز در همان پیشوند grid است که در حال حاضر منسوخ شده است اما هنوز از مرورگرها حذف نشده است. با این حال بهتر است بدون پیشوند grip از آن استفاده کنید چرا که در مرورگرهای مدرن مانند نسخه ۶۸ گوگل کروم به بعد پشتیبانی می شود و اگر بعدا حذف شود برای سایتتان دردسر درست خواهد کرد. ساختار کلی استفاده از این دستورات به شکل زیر است:

.container {

  /* روش استاندارد */

  gap: <grid-row-gap> <grid-column-gap>;




  /* روش قدیمی و منسوخ شده */

  grid-gap: <grid-row-gap> <grid-column-gap>;

}

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

.container {

  grid-template-columns: 100px 50px 100px;

  grid-template-rows: 80px auto 80px;

  gap: 15px 10px;

}

در این کد فاصله بین ردیف ها ۱۵ پیکسل و فاصله بین ستون ها ۱۰ پیکسل در نظر گرفته شده است. در صورتی که مقدار row-gap را در این خصوصیت تعیین نکنید، مقدارش برابر با column-gap در نظر گرفته می شود.

خصوصیات آیتم: چینش آیتم ها

در این بخش دو خصوصیت بسیار مهم به نام های justify-self و align-self را داریم. justify-self مسئول تعیین تراز آیتم درون یک خانه از شبکه در محور افق (ردیف ها) است در حالی که align-self این ترازبندی را در محور عمود (ستون ها) انجام می دهد. هر دو خصوصیت نیز به یک آیتم در یک خانه از شبکه اضافه می شوند. بیایید با justify-self شروع کنیم.

مقادیر ممکن برای justify-self به صورت زیر هستند:

  • start: آیتم درون خانه را به ابتدای خانه می برد تا با گوشه اول شروع شود.
  • end: آیتم درون خانه را به انتهای خانه می برد تا با گوشه آخر شروع شود.
  • center: آیتم درون خانه را در وسط آن خانه قرار می دهد.
  • stretch: آیتم درون خانه را می کِشد تا کل عرض خانه را اشغال کند. این گزینه، مقدار پیش فرض برای خصوصیت justify-self است.

بنابراین ساختار کلی استفاده از این خصوصیت به شکل زیر است:

.item {

  justify-self: start | end | center | stretch;

}

یک مثال ساده از این خصوصیت را در کد زیر می بینید:

.item-a {

  justify-self: start;

}

با اجرای این کد نتیجه زیر را می گیریم:

تنظیمjustify-self روی start
تنظیمjustify-self روی start

مثال بعدی:

.item-a {

  justify-self: end;

}

با اجرای این کد نتیجه زیر را می گیریم:

تنظیم justify-self روی end
تنظیم justify-self روی end

مثال بعدی:

.item-a {

  justify-self: center;

}

با اجرای این کد نتیجه زیر را می گیریم:

تنظیم justify-self روی center
تنظیم justify-self روی center

و مثال آخر:

.item-a {

  justify-self: stretch;

}

با اجرای این کد نتیجه زیر را می گیریم:

تنظیم justify-self روی stretch
تنظیم justify-self روی stretch

همانطور که گفتم این خصوصیت روی یک آیتم خاص اعمال می شود اما اگر بخواهید این رفتار خاص را برای تمام آیتم های درون شبکه تنظیم کنیم باید از خصوصیتی به نام align-items استفاده کنیم که مخصوص container است و در ادامه مقاله در مورد آن توضیح خواهم داد.

خصوصیت بعدی ما align-self است که به جای ترازبندی در محور افقی (ردیف ها) این کار را در محور عمودی (ستون ها) انجام می دهد. این خصوصیت روی محتوای درون یک آیتم خاص در شبکه اعمال می شود. مقادیر ممکن برای آن نیز به شکل زیر است:

  • start: آیتم درون خانه را به ابتدای خانه می برد تا با گوشه اول (از محور عمود) شروع شود.
  • end: آیتم درون خانه را به انتهای خانه می برد تا با گوشه آخر (از محور عمود) شروع شود.
  • center: آیتم درون خانه را در وسط آن خانه (از محور عمود) قرار می دهد.
  • stretch: آیتم درون خانه را می کِشد تا کل ارتفاع خانه را اشغال کند. این گزینه، مقدار پیش فرض برای خصوصیت align-self است.

بهتر است هر چهار حالت را در قالب مثال ببینیم تا بهتر با آن ها آشنا شویم. مثال اول از start:

.item-a {

  align-self: start;

}

این کد باعث ترازبندی به شکل زیر می شود:

تنظیم align-self روی start
تنظیم align-self روی start

مثال دوم از end:

.item-a {

  align-self: end;

}

این کد باعث ترازبندی به شکل زیر می شود:

تنظیم align-self روی end
تنظیم align-self روی end

مثال سوم از center:

.item-a {

  align-self: center;

}

این کد باعث ترازبندی به شکل زیر می شود:

تنظیم align-self روی center
تنظیم align-self روی center

مثال چهارم از stretch:

.item-a {

  align-self: stretch;

}

این کد باعث ترازبندی به شکل زیر می شود:

تنظیم align-self روی stretch
تنظیم align-self روی stretch

این خصوصیت فقط روی محتویات یک آیتم اعمال می شود اما اگر بخواهیم محتویات کل شبکه را بدین شکل تنظیم کنیم باید از خصوصیتی به نام align-items استفاده کنیم که مخصوص container ها است و فعلا در موردش صحبت نکرده ایم.

در نهایت هر دو خصوصیت align-self و justify-self در یک خصوصیت به نام place-self خلاصه می شوند که دو مقدار ممکن می گیرد: auto که مقدار پیش فرض را برای ترازبندی قرار می دهد و مشخص کردن مقادیر به صورت دستی به طوری که مقدار اول align-self و مقدار دوم justify-self باشد. به مثال زیر توجه کنید:

.item-a {

  place-self: center;

}

همانطور که می بینید من فقط یک مقدار را مشخص کرده ام بنابراین هر دو خصوصیت align-self و justify-self برابر با همین مقدار center است. با اجرای این کد چنین نتیجه ای را می گیریم:

تنظیم place-self روی center
تنظیم place-self روی center

البته شما می توانید این مقادیر را به صورت جداگانه نیز مشخص کنید:

.item-a {

  place-self: center stretch;

}

در این حالت نتیجه به شکل زیر خواهد شد:

تنظیم place-self روی center و stretch
تنظیم place-self روی center و stretch

تمام مرورگرهای مدرن به جز Edge از این خصوصیت پشتیبانی می کنند.

خصوصیات نگهدارنده: justify-items و align-items

دو خصوصیت justify-items و align-items باعث چینش و ترازبندی آیتم ها در خانه های خود می شوند اما همانطور که در دو بخش قبلی توضیح دادم، تاثیر آن ها روی تمام آیتم های درون نگهدارنده است در حالی place-self و justify-self فقط روی یک آیتم خاص اعمال می شوند. بیایید با justify-items شروع کنیم.

خصوصیت justify-items مسئول ترازبندی آیتم ها در محور افقی (ردیف ها) است و می تواند یکی از مقادیر زیر را بگیرد:

  • start: تمام آیتم های درون شبکه را به ابتدای شبکه می برد تا با گوشه اول شروع شود.
  • end: تمام آیتم های درون شبکه را به انتهای شبکه می برد تا با گوشه آخر شروع شود.
  • center: تمام آیتم های درون شبکه را در وسط آن شبکه قرار می دهد.
  • stretch: تمام آیتم های درون شبکه را می کِشد تا کل عرض شبکه را اشغال کند. این گزینه، مقدار پیش فرض است.

بنابراین ساختار کلی استفاده از این دستور به شکل زیر خواهد بود:

.container {

  justify-items: start | end | center | stretch;

}

مثال اول از start:

.container {

  justify-items: start;

}

توجه کنید که این کلاس به container اضافه شده است و با آیتم ها کاری ندارد. این کد ترازبندی زیر را اجرا می کند:

تنظیم justify-items روی start
تنظیم justify-items روی start

همانطور که می بینید، فارغ از اندازه آیتم ها همه را به ابتدای خانه ها (از نظر محور افق) آورده ایم.

مثال دوم از end:

.container {

  justify-items: end;

}

این کد ترازبندی زیر را اجرا می کند:

تنظیم justify-items روی end
تنظیم justify-items روی end

مثال سوم از center:

.container {

  justify-items: center;

}

این کد ترازبندی زیر را اجرا می کند:

تنظیم justify-items روی center
تنظیم justify-items روی center

مثال چهارم از stretch:

.container {

  justify-items: stretch;

}

این کد ترازبندی زیر را اجرا می کند:

تنظیم justify-items روی stretch
تنظیم justify-items روی stretch

اگر می خواهید فقط ترازبندی یکی از آیتم ها را در این محور تغییر دهید باید از justify-self استفاده نمایید.

خصوصیت بعدی ما align-items است که باز هم روی نگهدارنده اعمال شده اما ترازبندی را در راستای محور عمود (ستون ها) اعمال می کند. مقادیر ممکن برای این خصوصیت به شرح زیر است:

  • start: تمام آیتم های درون شبکه را به بالای شبکه (ابتدای محور عمودی) می برد تا با گوشه اول شروع شود.
  • end: تمام آیتم های درون شبکه را به پایین شبکه (انتهای محور عمودی) می برد تا با گوشه آخر شروع شود.
  • center: تمام آیتم های درون شبکه را در وسط آن (وسط محور عمود) قرار می دهد.
  • stretch: تمام آیتم های درون شبکه را می کِشد تا کل عرض شبکه را اشغال کند. این گزینه، مقدار پیش فرض است.

مثال اول از start:

.container {

  align-items: start;

}

توجه کنید که این کلاس به container اضافه شده است و با آیتم ها کاری ندارد. این کد ترازبندی زیر را اجرا می کند:

تنظیم align-items روی start
تنظیم align-items روی start

همانطور که می بینید، فارغ از اندازه آیتم ها همه را به ابتدای خانه ها (از نظر محور افق) آورده ایم.

مثال دوم از end:

.container {

  align-items: end;

}

این کد ترازبندی زیر را اجرا می کند:

تنظیم align-items روی end
تنظیم align-items روی end

مثال سوم از center:

.container {

  align-items: center;

}

این کد ترازبندی زیر را اجرا می کند:

تنظیم align-items روی center
تنظیم align-items روی center

مثال چهارم از stretch:

.container {

  align-items: stretch;

}

این کد ترازبندی زیر را اجرا می کند:

تنظیم align-items روی stretch
تنظیم align-items روی stretch

اگر می خواهید فقط ترازبندی یکی از آیتم ها را در این محور تغییر دهید باید از align-self استفاده نمایید.

البته باید بدانید که دستوری به نام place-items نیز وجود دارد. این دستور خلاصه شده خصوصیات align-items و justify-items است بنابراین مقادیری که به آن می دهید به ترتیب برای همین دو خصوصیت خواهد بود. در صورتی که به جای دو مقدار، فقط یک مقدار را به place-items پاس بدهید، آن مقدار برای هر دو خصوصیات align-items و justify-items در نظر گرفته می شود. تمام مرورگرهای مدرن به غیر از Edge از این خصوصیت پشتیبانی می کنند.

خصوصیات نگهدارنده: نگهدارنده ای بزرگ تر!

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

برخی اوقات اندازه شبکه (اندازه تمام آیتم ها در کنار هم) از اندازه نگهدارنده (container) کوچک تر است. این موقعیت معمولا زمانی پیش می آید که تمام آیتم های شبکه شما با واحد های ثابت (مانند پیکسل) اندازه دهی شده باشند. در این حالت چطور می توانیم شبکه را درون نگهدارنده نمایش بدهیم؟ فاصله بین اعضای شبکه چطور باشد؟ در این حالت دو خصوصیت به نام های justify-content و align-content به کمک ما می آیند. در این بخش می خواهیم در رابطه با این دو خصوصیت صحبت کنیم. توجه کنید که بحث ما در رابطه با توزیع کل شبکه درون یک container است و دیگر در رابطه با توزیع آیتم ها درون خانه های شبکه صحبت نمی کنیم. تا قبل از این بخش، همه چیز درباره توزیع آیتم ها درون خانه ها بود اما این بخش در رابطه با توزیع خود خانه ها در نگهدارنده است.

خصوصیت justify-content مسئول پخش کردن شبکه درون نگهدارنده در محور افق (ردیف) است و می تواند مقادیر زیر را بگیرد. در نظر داشته باشید که کلمات «ابتدا» و «انتها» از منظر محور افق خواهد بود:

  • start: شبکه را در ابتدای نگهدارنده قرار می دهد.
  • end: شبکه را در انتهای نگهدارنده قرار می دهد.
  • center: شبکه را در وسط نگهدارنده قرار می دهد.
  • stretch: شبکه را آنقدر می کِشد تا تمام عرض نگهدارنده را بگیرد.
  • space-around: فضایی مساوی را بین خانه های شبکه قرار می دهد و همچنین نصف آن فضا را در فضای اطراف شبکه قرار می دهد.
  • space-between: فضایی مساوی را بین خانه های شبکه قرار می دهد اما برخلاف space-aroundهیچ فضایی به اطراف شبکه اضافه نمی کند.
  • space-evenly: فضایی مساوی را بین خانه های شبکه قرار می دهد، سپس عینا همان میزان فضا را در اطراف شبکه اضافه می کند.

مثال اول از start:

.container {

  justify-content: start;

}

این کد ترازبندی زیر را اجرا می کند:

تنظیم justify-content روی start
تنظیم justify-content روی start

همانطور که می بینید، شبکه (تمام خانه ها) به ابتدای نگهدارنده منتقل شده اند. یادتان باشد انگلیسی از چپ به راست است بنابراین ابتدا یعنی «چپ» و انتهای یعنی «راست»!

مثال دوم از end:

.container {

  justify-content: end;   

}

این کد ترازبندی زیر را اجرا می کند:

تنظیم justify-content روی end
تنظیم justify-content روی end

مثال سوم از center:

.container {

  justify-content: center;   

}

این کد ترازبندی زیر را اجرا می کند:

تنظیم justify-content روی center
تنظیم justify-content روی center

مثال چهارم از stretch:

.container {

  justify-content: stretch;   

}

این کد ترازبندی زیر را اجرا می کند:

تنظیم justify-content روی stretch
تنظیم justify-content روی stretch

مثال پنجم از space-around:

.container {

  justify-content: space-around;   

}

این کد ترازبندی زیر را اجرا می کند:

تنظیم justify-content روی space around
تنظیم justify-content روی space around

مثال ششم از space-between:

.container {

  justify-content: space-between;   

}

این کد ترازبندی زیر را اجرا می کند:

تنظیم justify-content روی space between
تنظیم justify-content روی space between

مثال هفتم از space-evenly:

.container {

  justify-content: space-evenly;   

}

این کد ترازبندی زیر را اجرا می کند:

تنظیم justify-content روی space evenly
تنظیم justify-content روی space evenly

از طرف دیگر خصوصیت align-content را داریم که دقیقا مانند خصوصیت justify-content است با این تفاوت که به جای محور افق (ردیف) محور عمود (ستون) را در نظر می گیرد و ترازبندی را در راستای این محور انجام می دهد. تمام مقادیر ممکن برای پاس دادن به این خصوصیت همان مقادیری است که برای خصوصیت justify-content توضیح دادم با این تفاوت که به جای محور افق باید محور عمود را در نظر بگیرید. به همین دلیل من توضیحات را بازنویسی نمی کنم و مستقیما به سراغ مثال ها می روم.

مثال اول از start:

.container {

  align-content: start;   

}

این کد ترازبندی زیر را اجرا می کند:

تنظیم align-content روی start
تنظیم align-content روی start

مثال دوم از end:

.container {

  align-content: end;   

}

این کد ترازبندی زیر را اجرا می کند:

تنظیم align-content روی end
تنظیم align-content روی end

مثال سوم از center:

.container {

  align-content: center;   

}

این کد ترازبندی زیر را اجرا می کند:

تنظیم align-content روی center
تنظیم align-content روی center

مثال چهارم از stretch:

.container {

  align-content: stretch;   

}

این کد ترازبندی زیر را اجرا می کند:

تنظیم align-content روی stretch
تنظیم align-content روی stretch

مثال پنجم از space-around:

.container {

  align-content: space-around;   

}

این کد ترازبندی زیر را اجرا می کند:

تنظیم align-content روی space around
تنظیم align-content روی space around

مثال ششم از space-between:

.container {

  align-content: space-between;   

}

این کد ترازبندی زیر را اجرا می کند:

تنظیم align-content روی space between
تنظیم align-content روی space between

مثال هفتم از space-evenly:

.container {

  align-content: space-evenly;   

}

این کد ترازبندی زیر را اجرا می کند:

تنظیم align-content روی space evenly
تنظیم align-content روی space evenly

مثل تمام دستورات اصلی قبلی، هر دو خصوصیت align-content و justify-content یک دستور معادل خلاصه نیز دارند که place-content نام دارد. این دستور دو مقدار قبول می کند که به ترتیب برای align-content و سپس برای justify-content هستند و در صورتی که فقط یک مقدار را پاس بدهید، آن مقدار برای هر دو حالت در نظر گرفته می شود. تمام مرورگرهای مدرن به جز Edge از این خصوصیت پشتیبانی می کنند.

خصوصیات نگهدارنده: شبکه ضمنی

شبکه ضمنی یا implicit grid به قسمت هایی از شبکه گفته می شود که به صورت خودکار و بدون دخالت ما ساخته شده اند. شیار ها یا track های ضمنی معمولا زمانی ایجاد می شوند که تعداد آیتم های شبکه از تعداد خانه های موجود در شبکه بیشتر باشد یا اینکه یکی از آیتم های شبکه خارج از شبکه قرار داده شده باشد. در این حالت CSS مجبور می شود چند بخش اضافه را به صورت خودکار بسازد.

شما می توانید با استفاده از خصوصیات grid-auto-columns و grid-auto-rows اندازه این شیار های ساخته شده را تنظیم کنید. ساختار کلی استفاده از این دستور به شکل زیر است:

.container {

  grid-auto-columns: <track-size> ...;

  grid-auto-rows: <track-size> ...;

}

برای اینکه بتوانیم یک مثال ساده از این دو خصوصیت را بررسی کنیم باید ابتدا حالتی را ایجاد کنیم که نیاز به شبکه ضمنی داشته باشیم بنابراین بیایید یک شبکه را تعریف کنیم:

.container {

  grid-template-columns: 60px 60px;

  grid-template-rows: 90px 90px;

}

با اجرای این کد چنین نتیجه ای را می گیرید که طبیعی است:

نمونه ی خروجی از کد های بالا برای تنظیم شبکه ی ضمنی
نمونه خروجی از کدهای بالا برای تنظیم شبکه ضمنی

همانطور که می بینید کد ما یک شبکه ۲ در ۲ ساخته شده است. حالا از دو خصوصیت grid-column و grid-row استفاده می کنیم تا آیتم های خود را درون این شبکه بچینیم:

.item-a {

  grid-column: 1 / 2;

  grid-row: 2 / 3;

}

.item-b {

  grid-column: 5 / 6;

  grid-row: 2 / 3;

}

با انجام این کار چینش آیتم ها بدین شکل خواهد بود:

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

احتمالا شما نیز متوجه شده اید که در کلاس item-b. از خطوط شماره ۵ و ۶ استفاده کرده ایم اما اصلا چنین خطوطی را تعریف نکرده ایم و این خطوط در شبکه ما وجود ندارند. CSS برای حل این مشکل شیار های ضمنی را با عرض صفر می سازد (یعنی شیار هایی که ما تعریف نکرده ایم بلکه به صورت خودکار ساخته شده اند). حالا اگر به تصویر بالا نگاه کنید متوجه دلیل آن خواهید شد.

عرض این شیارها به صورت پیش فرض صفر است اما با خصوصیاتی که در این بخش توضیح دادم می توانیم اندازه آن ها را تغییر بدهیم:

.container {

  grid-auto-columns: 60px;

}

با انجام این کار چنین نتیجه ای را دریافت می کنیم:

تغییر عرض ستون ها
تغییر عرض ستون ها

حالا که متوجه روش کار این خصوصیت شده اید باید به سراغ خصوصیت بعدی به نام grid-auto-flow برویم. اگر شما آیتم هایی را در شبکه خود داشته باشید اما خودتان مکان آن ها را مشخص نکرده باشید، CSS به صورت خودکار مکان آن ها در شبکه را تعیین خواهد کرد. خصوصیت grid-auto-flow به شما اجازه می دهد که فرآیند تعیین مکان خودکار را تا حدی کنترل کنید و آن را به سلیقه خودتان تنظیم کنید.

مقادیر ممکن برای پاس دادن به این خصوصیت به شرح زیر می باشد:

  • row: این مقدار به CSS می گوید هر آیتم به نوبت در ردیف مناسب قرار بگیرد و در صورت نیاز ردیف های جدید نیز اضافه شود. این گزینه، مقدار پیش فرض است.
  • column: این مقدار به CSS می گوید هر آیتم به نوبت در ستون مناسب قرار بگیرد و در صورت نیاز ستون های جدید نیز اضافه شود.
  • dense: این مقدار به CSS می گوید اگر آیتم های کوچک تر بعدا وارد شبکه شدند، ابتدا سعی در پُر کردن خانه های ابتدای شبکه کند. به زبان ساده تر این گزینه از هر خانه خالی برای پُر کردن استفاده می کند. این گزینه تنها حالت نمایش آیتم های شما را تغییر می دهد بنابراین ممکن است باعث شود ترتیب نمایش آیتم ها بهم بریزد.

به مثال HTML زیر توجه کنید:

<section class="container">

  <div class="item-a">item-a</div>

  <div class="item-b">item-b</div>

  <div class="item-c">item-c</div>

  <div class="item-d">item-d</div>

  <div class="item-e">item-e</div>

</section>

ما می خواهیم یک شبکه را تعریف کنیم که ۵ ستون و ۲ ردیف داشته باشد. من grid-auto-flow در این شبکه را روی همان حالت پیش فرض (row) می گذارم:

.container {

  display: grid;

  grid-template-columns: 60px 60px 60px 60px 60px;

  grid-template-rows: 30px 30px;

  grid-auto-flow: row;

}

حالا در هنگام چینش آیتم ها درون آن، فقط مکان دو آیتم را مشخص کرده و برای بقیه آیتم ها محلی را مشخص نمی کنیم:

.item-a {

  grid-column: 1;

  grid-row: 1 / 3;

}

.item-e {

  grid-column: 5;

  grid-row: 1 / 3;

}

از آن جهت که ما مقدار row را برای grid-auto-flow تنظیم کرده ایم، شبکه ما به شکل زیر در می آید. همچنین در کد بالا مشخص است که ما برای سه آیتم item-b و item-c و item-d محلی تعیین نکرده بودیم بنابراین به محل این سه آیتم در تصویر زیر به خوبی دقت کنید.

جریان خودکار در CSS Grid
جریان خودکار در CSS Grid

حالا اگر مقدار grid-auto-flow را روی column تنظیم کنیم چطور؟

.container {

  display: grid;

  grid-template-columns: 60px 60px 60px 60px 60px;

  grid-template-rows: 30px 30px;

  grid-auto-flow: column;

}

با انجام این کار نحوه چینش سه آیتم مورد نظرمان به شکل زیر خواهد بود:

نمونه ای دیگر از جریان خودکار در CSS Grid
نمونه ای دیگر از جریان خودکار در CSS Grid

دستوری میانبر برای تمام دستورات

در سیستم گرید CSS یک دستور اصلی و بزرگ وجود دارد که خلاصه ای از دستورات grid-template-rows, grid-template-columns, grid-template-areas, grid-auto-rows, grid-auto-columns,  و grid-auto-flow است! این خصوصیت بزرگ Grid نام دارد! البته در نظر داشته باشید که شما در این حالت فقط می توانید خصوصیت شبکه واقعی یا شبکه ضمنی را مشخص کنید. مقادیر ممکن برای پاس دادن به این خصوصیت به شرح زیر است:

None: این مقدار باعث می شود تمام خصوصیاتی که بالاتر نام بردم روی مقادیر پیش فرض و اولیه شان قرار بگیرند.

Grid template: در این بخش که مقدار دوم است باید دقیقا مانند grid-template عمل کنید. تمام مواردی که برای grid-template توضیح دادیم در این بخش نیز برقرار است.

مقدار سوم ساختاری پیشرفته دارد که شاید در نگاه اول کمی عجیب به نظر برسد به همین دلیل من آن را فقط توضیح می دهم تا زمانی که به بخش کدنویسی آن برسیم. در ابتدا باید grid-template-rows را به همان شکلی که در این مقاله توضیح داده شد، مشخص کنید. در مرحله بعدی علامت / را آورده و اگر auto-flow را مستقیما پس از آن بنویسید خصوصیت grid-auto-flow روی column قرار می گیرد اما اگر dense را بنویسید از همان حالت dense استفاده می شود. در نهایت باید خصوصیت grid-auto-columns را مقدار دهی کنید و اگر این کار را نکنید مقدارش به صورت خودکار auto در نظر گرفته می شود. ما می توانیم کل این ساختار را به شکل زیر مشخص کنیم:

<grid-template-rows> / [ auto-flow && dense? ] <grid-auto-columns>?

ظاهر این ساختار پیچیده است بنابراین نگران نباشید. زمانی که مثال ها را ببینید متوجه این موضوع می شوید.

مقدار چهارم نیز شبیه به مقدار سوم ساختاری پیچیده دارد. در این بخش و در حالت اول grid-template-columns را به همان شکلی که در این مقاله توضیح داده شد مشخص می کنیم. سپس یک علامت / را می نویسید. در صورتی که کلیدواژه auto-flow در سمت راست این علامت قرار داشته باشد، خصوصیت grid-auto-flow برابر با row در نظر گرفته می شود. از طرفی اگر کلیدواژه dense را نوشته باشید، مکانیسم چینش خودکار بر اساس حالت dense عمل می کند که قبلا توضیح داده شده است. در نهایت نیز باید خصوصیت grid-auto-rows را مقدار دهی کنید و در صورتی که این کار را انجام ندهید، مقدار آن به صورت پیش فرض برابر با auto در نظر گرفته می شود. ساختار کلی این بخش به شکل زیر است:

[ auto-flow && dense? ] <grid-auto-rows>? / <grid-template-columns>

حالا که با بخش های مختلف مقدار دهی برای این خصوصیت آشنا شده ایم باید به سراغ بررسی چند مثال برویم. بیایید با یک مثال ساده شروع کنیم:

.container {

  grid: 100px 300px / 3fr 1fr;

}




.container {

  grid-template-rows: 100px 300px;

  grid-template-columns: 3fr 1fr;

}

در این کد دو بار کلاس Container را تعریف کرده ایم. این دو بلوک کد دقیقا معادل یکدیگر هستند و از آنجایی که ساده می باشند فکر نمی کنم نیازی به توضیح اضافه داشته باشند.

همچنین هر دو بلوک کد زیر نیز برابر هستند:

.container {

  grid: auto-flow / 200px 1fr;

}




.container {

  grid-auto-flow: row;

  grid-template-columns: 200px 1fr;

}

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

.container {

  grid: auto-flow dense 100px / 1fr 2fr;

}




.container {

  grid-auto-flow: row dense;

  grid-auto-rows: 100px;

  grid-template-columns: 1fr 2fr;

}

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

.container {

  grid: 100px 300px / auto-flow 200px;

}




.container {

  grid-template-rows: 100px 300px;

  grid-auto-flow: column;

  grid-auto-columns: 200px;

}

امیدوارم متوجه این مثال ها شده باشید. در نهایت باید بگویم که یک حالت دیگر نیز وجود دارد که با استفاده از آن می توانید همه چیز را به صورت یکجا تنظیم کنید. به کد زیر توجه کنید:

.container {

  grid: [row1-start] "header header header" 1fr [row1-end]

        [row2-start] "footer footer footer" 25px [row2-end]

        / auto 50px auto;

}

این کد دقیقا معادل با کد زیر است:

.container {

  grid-template-areas:

    "header header header"

    "footer footer footer";

  grid-template-rows: [row1-start] 1fr [row1-end row2-start] 25px [row2-end];

  grid-template-columns: auto 50px auto;   

}

برخی از توابع مهم در CSS Grid

در این بخش می خواهم در رابطه با برخی از توابع کاربردی و برخی نکات تکمیلی در شبکه CSS صحبت کنم.

زمانی که در حال تعیین اندازه عناصر مختلف هستید می توانید از همان واحد های همیشگی خود مانند px (پیکسل) یا rem یا درصد و امثال آن استفاده کنید اما در عین حال به دستورات جدیدی مانند min-content و max-content و auto نیز دسترسی دارید. همچنین یکی از مهم ترین قابلیت ها استفاده از واحدی به نام fr است که در ابتدای مقاله به صورت خلاصه برایتان توضیح دادم.

این واحدهای انعطاف پذیر و نسبی چیز جدیدی در طراحی وب نیستند اما در CSS Grid توابعی معرفی می شوند که به شما اجازه می دهند برای آن ها حد نصاب خاصی را تعیین کنید. به طور مثال اگر بخواهیم اندازه یک ستون 1fr باشد اما هیچگاه از 200 پیکسل کوچکتر نشود از دستور زیر استفاده می کنیم:

grid-template-columns: 1fr minmax(200px, 1fr);

همچنین تابعی به نام repeat وجود دارد که یک مقدار را تکرار می کند و آن را نیز در همین مقاله توضیح دادیم.

مثالی از طراحی روان (fluid)

یکی از قابلیت های بسیار عالی آموزش CSS Grid این است که به شما اجازه طراحی fluid یا «روان» را می دهد. یعنی چه؟ طراحی روان نوعی طراحی واکنش گرا (responsive) است که در آن نیازی به استفاده از Media query ها نداریم! در این نوع طراحی، آیتم ها بر اساس فضای موجود و به صورت خودکار تغییر اندازه می دهند و رفتاری شبیه به آب دارند. آب را در هر ظرفی که بریزید به شکل همان ظرف در می آید و نام طراحی «روان» نیز از همین موضوع گرفته شده است (لغت fluid در حالت اسم به معنی «مایع» است).

این طراحی به وسیله توضیحات بخش قبل (توابع CSS Grid) ممکن است. به مثال زیر از یک طراحی روان دقت کنید:

.grid {

  display: grid;

  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));

  /* This is better for small screens, once min() is better supported */

  /* grid-template-columns: repeat(auto-fill, minmax(min(200px, 100%), 1fr)); */

  grid-gap: 1rem;

  /* This is the standardized property now, but has slightly less support */

  /* gap: 1rem */

}

شما می توانید نتیجه این کد را به صورت کامل در این صفحه از Code Pen مشاهده کنید.

امیدوارم آموزش CSS Grid برای شما مفید بوده باشد. تنها کاری که باقی می ماند کدنویسی و تمرین مسائلی است که در این مقاله برایتان توضیح داده شد.


منبع: وب سایت css-tricks

نویسنده شوید
دیدگاه‌های شما (1 دیدگاه)

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

حامد
03 مهر 1402
خیلی جامع و کامل بود و به نظر من خیلی هم روان و بدور از پیچیدگی توضیح داده شده. خدا قوت

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.