مقالات › CSS و طراحی وب
آموزش Flexbox و CSS Grid؛ راهنمای کاربردی چیدمان مدرن صفحات وب
یاد بگیرید کِی از Flexbox و کِی از CSS Grid استفاده کنید؛ با الگوهای آماده برای منو، کارت، چیدمان کل صفحه، گرید واکنشگرا، وسطچین کردن و طراحی راستچین.
Flexbox و CSS Grid جای یک دهه ترفندهای Float و Clearfix را گرفتند. این دو با هم تقریباً هر چیدمانی را با چند خط CSS میسازند. پرتکرارترین سؤال توسعهدهندهها این است که از کدام استفاده کنم؟ این راهنما با قوانین روشن و الگوهای آمادهی کپی به همین سؤال جواب میدهد.
تفاوت در یک جمله
- Flexbox یکبعدی است: آیتمها را در یک ردیف یا یک ستون میچیند و فضا را در طول همان خط تقسیم میکند.
- Grid دوبعدی است: سطرها و ستونها را همزمان تعریف میکند و آیتمها را در آن ساختار قرار میدهد.
یک قاعدهی کاربردی: Flexbox از محتوا به بیرون فکر میکند (آیتمها اندازهی خودشان را تعیین میکنند و ظرف فضای باقیمانده را پخش میکند)؛ Grid از چیدمان به داخل (ظرف مسیرها را تعریف میکند و آیتمها آنها را پر میکنند).
مفاهیم اصلی Flexbox
.toolbar {
display: flex;
flex-direction: row; /* row | column */
justify-content: space-between; /* محور اصلی */
align-items: center; /* محور عمودی (فرعی) */
gap: 12px;
flex-wrap: wrap;
}
مفهوم کلیدی، دو محور است:
| ویژگی | محور | مقادیر رایج |
|---|---|---|
justify-content |
محور اصلی | flex-start، center، space-between، space-around |
align-items |
محور فرعی | stretch، center، flex-start، baseline |
align-self |
محور فرعی (یک آیتم) | مثل align-items |
خلاصهنویسی flex
هر فرزند میتواند رشد کند، کوچک شود و اندازهی پایه داشته باشد:
.item { flex: 1 1 200px; } /* grow, shrink, basis */
flex: 1— فضای باقیمانده را مساوی تقسیم کن.flex: none— اندازهی طبیعی را حفظ کن.flex: 0 0 280px— یک سایدبار با عرض ثابت.
نکته: اگر یک آیتم Flex با متن طولانی کوچک نمیشود،
min-width: 0اضافه کنید. آیتمهای Flex بهطور پیشفرضmin-width: autoدارند که اجازه نمیدهد از اندازهی محتوایشان کوچکتر شوند.
الگوهای Flexbox
منو با دکمهای که به انتها هل داده میشود:
.nav { display: flex; align-items: center; gap: 16px; }
.nav__actions { margin-inline-start: auto; } /* به انتها میرود — سازگار با RTL */
وسطچین کامل:
.center { display: flex; justify-content: center; align-items: center; min-height: 100vh; }
کارتهایی که دکمهشان به پایین میچسبد:
.card { display: flex; flex-direction: column; }
.card__footer { margin-top: auto; }
مفاهیم اصلی Grid
.dashboard {
display: grid;
grid-template-columns: 240px 1fr;
grid-template-rows: 64px 1fr auto;
gap: 16px;
min-height: 100vh;
}
واحد fr یعنی «کسری از فضای آزاد». 1fr 2fr به ستون دوم دو برابر ستون اول فضا میدهد.
نواحی نامدار (Template Areas)
نواحی Grid چیدمانهای پیچیده را خوانا میکنند؛ CSS عملاً نقشهی صفحه را میکشد:
.page {
display: grid;
grid-template-columns: 260px 1fr;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.footer { grid-area: footer; }
@media (max-width: 768px) {
.page {
grid-template-columns: 1fr;
grid-template-areas: "header" "main" "sidebar" "footer";
}
}
برای تغییر چیدمان در موبایل فقط کافی است نواحی را دوباره بکشید.
گرید واکنشگرا بدون Media Query
همین یک خط، یک گرید کارت میسازد که با هر عرضی سازگار است:
.cards {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
gap: 20px;
}
minmax(260px, 1fr)— هر ستون حداقل ۲۶۰ پیکسل است و میتواند بزرگتر شود.auto-fill— به تعدادی که جا میشود ستون میسازد.auto-fit— مثلauto-fill، اما مسیرهای خالی را جمع میکند تا آیتمهای موجود کشیده شوند.
گستردن و جایگذاری آیتمها
.featured {
grid-column: span 2;
grid-row: span 2;
}
.full-width { grid-column: 1 / -1; } /* از اولین تا آخرین خط */
چیدمانهای «Bento» با یک کارت شاخص بزرگ اینطور ساخته میشوند.
Flexbox یا Grid؟ جدول تصمیمگیری
| موقعیت | انتخاب |
|---|---|
| منو، نوار ابزار، گروه دکمه | Flexbox |
| وسطچین کردن یک المان | هر دو (در Grid: place-items: center) |
| آیتمهایی با اندازهی نامشخص که خودبهخود میشکنند (تگها، چیپها) | Flexbox |
| گالری کارت با ستونهای مساوی | Grid |
| چیدمان کل صفحه (هدر/سایدبار/محتوا/فوتر) | Grid |
| تراز محتوای داخل یک کارت | Flexbox |
| آیتمهایی که باید هم در سطر و هم در ستون همتراز باشند | Grid |
در پروژههای واقعی این دو را ترکیب میکنید: Grid برای صفحه و گالری کارتها، Flexbox داخل هر کارت و برای منو.
نوشتن چیدمانی که در RTL درست کار کند
سایتهای فارسی، عربی و عبری راستبهچپ هستند. از ویژگیهای منطقی (Logical Properties) استفاده کنید تا با dir="rtl" چیدمان خودکار برعکس شود:
| فیزیکی | منطقی |
|---|---|
margin-left |
margin-inline-start |
padding-right |
padding-inline-end |
left: 0 |
inset-inline-start: 0 |
border-left |
border-inline-start |
text-align: left |
text-align: start |
Flexbox و Grid خودشان از جهت نوشتار پیروی میکنند: در RTL، justify-content: flex-start یعنی «راست». برای RTL از ترفند row-reverse استفاده نکنید؛ ویژگیهای منطقی راه تمیزتری هستند.
Subgrid و Container Query
دو قابلیت جدیدتر که حالا در همهی مرورگرهای مدرن پشتیبانی میشوند:
Subgrid اجازه میدهد المانهای تودرتو با گرید والد همتراز شوند؛ عالی برای کارتهایی که عنوان، متن و دکمهشان باید در یک ردیف همتراز باشد:
.cards { display: grid; grid-template-columns: repeat(3, 1fr); }
.card {
display: grid;
grid-row: span 3;
grid-template-rows: subgrid;
}
Container Query اجازه میدهد یک کامپوننت بر اساس عرض ظرف خودش تغییر کند، نه عرض صفحه:
.card-wrapper { container-type: inline-size; }
@container (min-width: 420px) {
.card { display: grid; grid-template-columns: 140px 1fr; }
}
اشتباهات رایج
- استفاده از
width: 33.33%همراه با margin بهجایgap. - فراموش کردن
min-width: 0برای آیتمهای Flex با متن یا کد طولانی. - ساخت چیدمان کل صفحه با ردیفهای تودرتوی Flex بهجای Grid.
- استفاده از ویژگیهای فیزیکی (
left،margin-right) در سایتهای دوزبانه. - Breakpointهای زیاد —
auto-fillهمراه باminmaxاغلب نیاز به آنها را از بین میبرد.
جمعبندی
از Flexbox برای تراز و توزیع آیتمها در طول یک خط و از Grid برای تعریف ساختارهای دوبعدی استفاده کنید. آنها را آزادانه ترکیب کنید، به gap، fr، minmax و نواحی نامدار تکیه کنید و ویژگیهای منطقی بنویسید تا چیدمانتان هم در LTR و هم در RTL درست کار کند. با این ابزارها بهندرت برای چیدمان به یک فریمورک CSS نیاز پیدا میکنید.
پرسشهای متداول
آیا Grid از Flexbox کندتر است؟
در صفحات واقعی تفاوت معناداری ندارند. بر اساس مسئلهی چیدمان انتخاب کنید، نه کارایی.
آیا هنوز برای گرید به فریمورکی مثل Bootstrap نیاز دارم؟
فقط برای چیدمان، نه. Grid بومی قدرتمندتر است و Markup کمتری لازم دارد. فریمورکها همچنان برای سیستم طراحی و کامپوننتها مفیدند.
آیا Flexbox میتواند جای Grid را بگیرد؟
برای ردیفهای ساده بله. اما چیدمانهای دوبعدی با Flexbox به Wrapperهای اضافه و عرضهای شکننده نیاز دارند؛ Grid مستقیماً حلشان میکند.