تالار گفتگوی کیش تک/ kishtech forum
مقایسه کاربردی بین css grid و flexbox - نسخه‌ی قابل چاپ

+- تالار گفتگوی کیش تک/ kishtech forum (http://forum.kishtech.ir)
+-- انجمن: پردیس فناوری کیش (http://forum.kishtech.ir/forumdisplay.php?fid=1)
+--- انجمن: فناوری اطلاعات و ارتباطات (http://forum.kishtech.ir/forumdisplay.php?fid=6)
+--- موضوع: مقایسه کاربردی بین css grid و flexbox (/showthread.php?tid=29767)



مقایسه کاربردی بین css grid و flexbox - nooshin88 - 10-04-2019

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

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

اما دیری نگذشت که Flexbox که تا مدت‌ها یکی از بهترین سیستم‌های لایه بندی‌ صفحات Html بشمار می‌رفت با یک رقیب سرسخت مواجه شد. این رقیب سرسخت Css Grid بود که توانست با  ارائه نسخه های موفقی از خود که توسط اکثر مرورگرها پشتیبانی می‌شود به محبوبت بالایی در میان طراحان سایت دست یابد.

یک لایه بندی پایه آزمایشی

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

ابتدا این‌کار را با flexbox و در نهایت با Cssgrid انجام خواهیم داد.

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

[تصویر:  CssGrid_vs_Flexbox_1.jpg]

طرحی که برای این مقایسه در نظر گرفته‌ایم یک طراحی ساده و پایه‌ایست. این طرح از یک نگهدارنده محتوای (container) مرکزی تشکیل می‌شود که خود شامل هدر (Header)، بخش اصلی (Main Content)، بخش کناری (Sidebar) و فوتر (Footer) می‌باشد. اما چالش‌های اصلی در این پروژه که ما باید از عهده آن‌ها برآییم و آن را حل کنیم عبارتند از:

قراردادن این چهاربخش بدرستی در کنار یکدیگر و ایجاد یک لایه بندی درست
ایجاد یک صفحه ریسپانسیو (واکنشگرا)
ترازبندی محتویات هدر (منوها) در سمت راست و قرارگیری دکمه قرمز رنگ هدر در سمت چپ.
همانطور که می‌بینید ما در این مثال همه چیز را به ساده‌ترین شکل ممکن در نظر گرفته‌ایم.

آماده‌اید؟

اول از همه می‌خواهیم به سراغ بررسی چالش اول برویم:

چالش اول: قراردهی بخش‌های مختلف یک صفحه 

راه حل flexbox

ما راه حل چالش نخست را ابتدا با flexbox آغاز کردیم. به این منظور ویژگی display:flex را به container اضافه کرده و چیدمان مربوط به فرزندان آن را عمودی درنظر گرفتیم. با اینکار هر بخش سایت یکی پس از دیگری در پایین یکدیگر قرار گرفتند.
[code]
.container {
 display: flex;
 flex-direction: column;
}
[/code]
اکنون احتیاج داریم تا با یک ترفند محتوای اصلی و محتوای کناری را در کنار یکدیگر قراردهیم. از آنجایی که هر المان با ویژگی flex تنها یک جهت می‌تواند بگیرد ما بخش اصلی و کناری را درون یک دربرگیرنده (wrapper) جدید قرار دادیم. 
[code]
<header></header>
<div class="main-and-sidebar-wrapper">
 <section class="main"></section>
 <aside class="sidebar"></aside>
</div>
<footer></footer>
[/code]
حالا به آن دربرگیرنده جدید که در اینجا با کلاس main-and-sidebar-wrapper مشخص شده‌است ویژگی‌های display:flex و flex-direction:row را اضافه می‌کنیم.
[code]
.main-and-sidebar-wrapper {
 display: flex;
 flex-direction: row;
}
[/code]
آخرین مرحله در طراحی این صفحه، تنظیم اندازه بخش اصلی و بخش کناری سایت است. ما درنظر داریم که اندازه بخش اصلی سایت (Main Content) سه برابر بخش کناری (Sidebar) باشد. برای این کار کافی است کدهای زیر را به کدهای خود اضافه کنید و براحتی به اندازه‌های دلخواه خود برسید. این کار را می‌توانید با ویژگی‌های flex همانند کد زیر و یا حتی با درصد انجام دهید.
[code]
.main {
 flex: 3;
 margin-right: 60px;
}
.sidebar {
 flex: 1;
}
[/code]
همانطور که میبینید flex توانسته به خوبی از عهده این چالش ما بر بیاید اما خب در کنار آن میبینید که آشنایی با ویژگی‌های css و یا اضافه کردن المان Html، مورد نیاز شما خواهد بود. اجازه بدهید تا به شما نشان دهیم css grid چگونه از عهده این چالش بر می‌آید.

راه حل css grid

در‌ واقع با css grid شما با مجموعه‌ای از راه حل‌های متفاوت مواجه خواهیدبود که ما در میان آن‌‌ها grid-template-areas  را انتخاب کردیم چرا که بنظر می‌رسد مناسب‌ترین راه حل برای چالش پیش‌رو است. در گام اول ما برای هر بخش صفحه، grid-area را مشخص می‌کنیم.
[code]
<header></header>
<!-- Notice there isn't a wrapper this time -->
<section class="main"></section>
<aside class="sidebar"></aside>
<footer></footer>
header {
    grid-area: header;
}
.main {
    grid-area: main;
}
.sidebar {
    grid-area: sidebar;
}
footer {
    grid-area: footer;
}
[/code]
اکنون باید تنظیمات مربوط به grid و مکان هر بخش را بدرستی مشخص کنیم. تکه کد زیر ممکن است در نگاه اول کمی پیچیده بنظر برسد اما نگران نباشید، همین که با سیستم grid آشنا شدید درک آن برای شما بسیار راحت خواهد شد.
[code]
.container {
 display: grid;

 /* Define the size and number of columns in our grid. 
 The fr unit works similar to flex:
 fr columns will share the free space in the row in proportion to their value.
 We will have 2 columns - the first will be 3x the size of the second. */
 grid-template-columns: 3fr 1fr;

 /* Assign the grid areas we did earlier to specific places on the grid. 
 First row is all header.
 Second row is shared between main and sidebar.
 Last row is all footer. */
 grid-template-areas: 
 "header header"
 "main sidebar"
 "footer footer";

 /* The gutters between each grid cell will be 60 pixels. */
 grid-gap: 60px;
[/code]
و فقط همین!

لایه‌های ما از ساختار بالا پیروی خواهند کرد و ما را به طرح دلخواهمان خواهند رسانید بدون آنکه کمترین دغدغه‌ای بابت حاشیه ها و فاصله ها (padding – margin) داشته باشیم.

چالش ۲: طراحی صفحه ریسپانسیو

راه حل flex:

تحلیل و چگونگی اجرای این مرحله به شدت به مرحله قبل وابسته است. در راه حل ارائه شده توسط flex کافی است برای المان های دربردارنده، flex-direction را مشخص کنید و برخی تنظیمات مربوط به marginها را انجام دهید.

[code]
@media (max-width: 600px) {
 .main-and-sidebar-wrapper {
 flex-direction: column;
 }

 .main {
 margin-right: 0;
 margin-bottom: 60px;
 }
}
[/code]

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

راه حل css grid

از آنجایی که ما در گام نخست grid-area ها را تعریف کرده‌بودیم، در اینجا تنها نیاز داریم در بخش کدهای ریسپانسیومان، ترتیب آن‌ها را کمی عوض کنیم و برای همه ردیف‌ها یا به عبارتی بخش‌های خود تنها یک ستون درنظر بگیریم.

[code]
@media (max-width: 600px) {
 .container {
 /* Realign the grid areas for a mobile layout. */
 grid-template-areas: 
 "header header"
 "main main"
 "sidebar sidebar"
 "footer footer";
 }
}
[/code]

یا حتی می‌توانیم در بخش کدهای ریسپانسیو، مجدداً لایه‌ها و ستون‌های مربوط به هریک را تعریف کنیم.

[code]
@media (max-width: 600px) {
 .container {
 /* Redefine the grid into a single column layout. */
 grid-template-columns: 1fr;
 grid-template-areas: 
 "header"
 "main"
 "sidebar"
 "footer";
 }
}
[/code]

چالش سوم: ترازبندی بخش‌های اصلی هدر

راه حل fexbox

همانطور که می‌بینید بخش هدر شامل یک سری لینک‌های منو و یک دکمه است. ما قصد داریم تا لینک‌های منو را در سمت راست صفحه و دکمه را در بخش چپ صفحه قرار دهیم . لینک های بخش منو هم باید همگی کناریکدیگر در یک ردیف قرار گیرند.

[code]
<header>
 <nav>
 <li><a href="#"><h1>Logo</h1></a></li>
 <li><a href="#">Link</a></li>
 <li><a href="#">Link</a></li>
 </nav>
 <button>Button</button>
</header>
[/code]

تکنیک آن بسیار ساده است:

[code]
header {
 display: flex;
 justify-content: space-between;
}
[/code]

اکنون منو و دکمه در یک ترازبندی درست قرار گرفته‌اند. برای آنکه تمام لینک های منو نیز بصورت افقی کنار یکدیگر قراربگیرند کافی است آن‌ها را درون یک المان html برای مثال nav قرار دهیم. می‌توانیم ویژگی display همه آن‌ها را inline-block قرار دهیم اما از آنجایی که در اینجا از ویژگی flex استفاده کرده‌ایم و می‌خواهیم سیستم صفحه‌آرایی ما کاملاً از flex تبعیت کند پس می‌توانیم راه حل flexیی زیر را به کدهایمان اضافه کنیم.

[code]
header nav {
 display: flex;
 align-items: baseline;
}
[/code]

تنها ۲ خط!

در کل راه حل بدی نبود. حالا بگذارید عملکرد css grid را در برخورد با این چالش ببینیم:

راه حل css grid

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

[code]
header{
    display: grid;
    grid-template-columns: 1fr 1fr;
}
header nav {
    justify-self: start;
}
header button {
    justify-self: end;
}
[/code]

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

[تصویر:  CssGrid_vs_Flexbox_2.jpg]

لینک ها به صورت inline هستند اما بدرستی ترازبندی نشده‌اند. از آنجایی که مانند ویژگی flex خصوصیتی برای ترازبندی محتویات align-items وجود ندارد شما مجبور خواهید بود تا یک grid داخلی یا بعبارتی دیگر یک subgrid تعریف کنید.

[code]
header nav {
 display: grid;
 grid-template-columns: auto 1fr 1fr;
 align-items: end; 
}
[/code]

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

نتیجه گیری:

اگر تا اینجا با دقت مقاله را دنبال کرده باشید بخش نتیجه‌گیری شما را متعجب نخواهد کرد. واقعیت آن است که بین این دو سیستم هیچ برتری خاصی وجود ندارد بلکه هر دوی آن‌ها flexbox و css grid سیستم‌های متفاوتی هستند که باید در کنار یکدیگر استفاده شوند نه به جای یکدیگر.

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

css grid برای ساخت لایه بندی‌های بزرگ‌تر هستند. آن‌ها بخوبی می‌توانند لایه بندی یک صفحه را مدیریت کنند و طرح‌های نامتقارن را ایجاد کنند.
flexbox سیستمی قدرتمند برای ترازبندی محتوای داخلی المان‌ها می‌باشند، می‌توانید از flexbox استفاده کنید تا بتوانید قرارگیری المان‌های جزئی را مدیریت کنید.
از css grid برای لایه بندی‌های ۲ بعدی استفده می‌شود (ردیف ها و ستون ها).
flex box در طراحی یک بعدی بهتر عمل می‌کند (یا ردیف و یا ستون).
 هیچ دلیل موثقی وجود ندارد که شما را مجبور کند از یکی از این دو سیستم استفاده کنید( css grid یا flexbox )، هر دوی آن‌ها را یاد بگیرید و در کنار یکدیگر بکار ببرید.

منبع: طراحی سایت خلاقانه