فلکسباکس پیشرفته و حرکت نرم
در فصل قبل ویژگیهای ظرف را دیدیم. حالا نوبت ویژگیهایی است که روی خود آیتمها نوشته میشوند، و در پایان یاد میگیریم تغییرها را نرم و تدریجی کنیم.
۱. gap: فاصله بین آیتمها
در فصل قبل برای فاصله دادن به کارتها از margin استفاده کردیم. این کار جواب میدهد اما یک عیب دارد: به لبههای بیرونی ظرف هم فاصله اضافه میکند و برای درست کردنش باید ترفندهایی بزنید. gap این مشکل را کاملاً حل میکند.
.container {
display: flex;
gap: 20px; /* فاصله یکسان بین همه آیتمها */
}
.container2 {
display: flex;
flex-wrap: wrap;
gap: 15px 30px; /* فاصله بین سطرها، سپس بین ستونها */
}
gap: نمونه 01-gap
شرح مثال
gapتنها بین آیتمها فاصله میگذارد، نه در لبههای بیرونی ظرف. یعنی دقیقاً همان چیزی که معمولاً میخواهیم.-
اگر دو مقدار بدهید، اولی فاصله عمودی بین سطرها و
دومی فاصله افقی بین ستونهاست. این حالت وقتی
flex-wrap: wrapدارید معنی پیدا میکند. -
gapروی ظرف نوشته میشود، نه روی آیتمها.
از این پس برای فاصله دادن به آیتمهای داخل یک ظرف فلکس، همیشه gap را انتخاب کنید. کد کوتاهتر میشود، نیازی به حذف margin آخرین آیتم ندارید و نتیجه دقیقاً همانی است که انتظار دارید. gap در گرید هم کار میکند و در فصل یازدهم بار دیگر میبینیمش.
۲. رشد و کوچک شدن آیتمها
تا اینجا آیتمها عرض ثابتی داشتند. حالا سه ویژگی میبینیم که روی خود آیتم نوشته میشوند و تعیین میکنند هر آیتم چقدر از فضای موجود را بگیرد.
.container {
display: flex;
gap: 10px;
}
.sidebar {
flex-basis: 250px; /* اندازه شروع */
flex-grow: 0; /* رشد نکن */
flex-shrink: 0; /* کوچک هم نشو */
}
.content {
flex-grow: 1; /* تمام فضای باقیمانده را بگیر */
}
.item-a { flex-grow: 1; }
.item-b { flex-grow: 2; } /* دو برابر item-a رشد میکند */
رشد و کوچک شدن: نمونه 02-flex-grow-shrink-basis
شرح مثال
| ویژگی | معنی | پیشفرض |
|---|---|---|
flex-basis |
اندازه اولیه آیتم پیش از تقسیم فضای اضافه | auto |
flex-grow |
اگر فضای اضافه بود، چقدر از آن را بگیرد | 0 یعنی رشد نکن |
flex-shrink |
اگر فضا کم بود، چقدر کوچک شود | 1 یعنی کوچک شو |
flex-grow یک نسبت است، نه یک اندازه.
اگر آیتم اول عدد ۱ و آیتم دوم عدد ۲ داشته باشد، فضای اضافه
به نسبت یک به دو بینشان تقسیم میشود. اگر همه عدد ۱ بگیرند،
فضا مساوی تقسیم میشود و همه همعرض میشوند.
چیدمان «نوار کناری بهعلاوه محتوای اصلی» را با همین دو خط میسازید: به نوار کناری flex-basis ثابت و flex-shrink: 0 بدهید تا هرگز فشرده نشود، و به محتوای اصلی تنها flex-grow: 1 بدهید تا هر چه باقی ماند را بگیرد. دیگر لازم نیست هیچ درصدی حساب کنید.
هر سه ویژگی را میشود در یک خط نوشت:
flex: 1 0 250px; که به ترتیب یعنی
grow، سپس shrink، سپس basis.
نوشتن flex: 1; هم میانبر بسیار رایجی است
و یعنی «رشد کن و فضای اضافه را بگیر».
۳. ترتیب نمایش
.item {
order: 0; /* پیشفرض همه آیتمها */
}
.first {
order: -1; /* برو اول همه */
}
.last {
order: 10; /* برو آخر همه */
}
ترتیب نمایش: نمونههای 03-order و 03-order-flags
شرح مثال
order ترتیب نمایش آیتمها را عوض میکند،
بدون اینکه ترتیبشان در فایل HTML تغییر کند.
همه آیتمها به طور پیشفرض عدد صفر دارند و مرورگر آنها را
از کوچک به بزرگ مرتب میکند. آیتمهایی با عدد یکسان،
به ترتیب نوشته شدنشان در HTML میمانند.
عدد منفی کاملاً مجاز است و سادهترین راه فرستادن یک آیتم به ابتداست، بدون اینکه لازم باشد عدد بقیه را عوض کنید.
در فصل دوازدهم میبینید که روی موبایل گاهی میخواهیم ترتیب
قسمتها فرق کند. مثلاً روی دسکتاپ تصویر سمت راست باشد
و روی موبایل تصویر بالای متن بیاید. با order
این کار بدون دست زدن به HTML انجام میشود.
order تنها ترتیب دیداری را عوض میکند. صفحهخوانها و کلید Tab همچنان ترتیب اصلی HTML را دنبال میکنند. اگر بسیار از آن استفاده کنید، تجربه کاربران نابینا و کسانی که با صفحهکلید کار میکنند به هم میریزد.
۴. align-self
align-items که در فصل قبل دیدیم، روی ظرف نوشته میشود و
همه آیتمها را با هم جابهجا میکند.
align-self همان کار را برای یک آیتم انجام میدهد.
.container {
display: flex;
align-items: center; /* قانون کلی برای همه */
height: 250px;
}
.special {
align-self: flex-start; /* استثنا: فقط این یکی بالا بماند */
}
.other {
align-self: flex-end; /* و این یکی پایین */
}
align-self: نمونه 04-align-self
شرح مثال
مقدارهای align-self دقیقاً همان مقدارهای
align-items هستند: flex-start،
center، flex-end و stretch.
تنها تفاوت این است که align-self روی
آیتم نوشته میشود و قانون ظرف را برای همان آیتم
نادیده میگیرد.
الگوی فکری این است: قانون کلی را روی ظرف بنویسید و استثناها را روی آیتمها. این همان کاری است که همیشه در CSS بهترین نتیجه را میدهد؛ کد کوتاه میماند و استثناها هم مشخص و خوانا هستند.
۵. حرکت نرم با transition
در فصل پنجم hover: را یاد گرفتیم، اما تغییر رنگ ناگهانی و پرشی اتفاق میافتاد. transition این تغییر را نرم و تدریجی میکند و ظاهر سایت را به شکل چشمگیری حرفهایتر.
.btn {
background-color: #2f4f4f;
color: white;
padding: 12px 28px;
border-radius: 8px;
transition: background-color 0.3s;
}
.btn:hover {
background-color: #ff6347;
}
.card {
border: 1px solid #dddddd;
transition: all 0.3s ease;
}
.card:hover {
border-color: #ff6347;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
}
حرکت نرم: نمونه 05-hover-transition
شرح مثال
transition سه بخش دارد و معمولاً دو تای اول کافی است:
- چه چیزی. نام ویژگیای که باید نرم تغییر کند، مانند
background-color. اگر بنویسیدall، هر چیزی که عوض شود نرم عوض میشود. - چقدر طول بکشد. مانند
0.3sیعنی سه دهم ثانیه. واحدsثانیه است وmsمیلیثانیه. - با چه سرعتی. مانند
easeکه پیشفرض است: آرام شروع میشود، تند میشود و آرام تمام میشود.linearیعنی سرعت ثابت.
transition را روی حالت عادی بنویسید، نه روی hover:. اگر آن را داخل hover: بگذارید، رفتن نرم میشود اما برگشتن ناگهانی. نوشتنش در حالت عادی باعث میشود هر دو جهت نرم باشند.
بین ۰.۲ تا ۰.۴ ثانیه بهترین محدوده است. کمتر از آن دیده نمیشود و بیشتر از آن کاربر را منتظر میگذارد و حس کندی به سایت میدهد.
۶. نمونه نهایی فصل
<body>
<div class="layout">
<aside class="sidebar">
<h3>دستهبندی</h3>
<p>وب</p>
<p>شبکه</p>
<p>گرافیک</p>
</aside>
<main class="content">
<h2>دورههای ما</h2>
<div class="cards">
<div class="card">
<h3>طراحی وب</h3>
<p>پانزده جلسه</p>
</div>
<div class="card">
<h3>جاوااسکریپت</h3>
<p>بیست جلسه</p>
</div>
<div class="card featured">
<h3>دوره ویژه</h3>
<p>ثبتنام محدود</p>
</div>
</div>
</main>
</div>
</body>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: Tahoma, sans-serif;
}
body {
background-color: #f5f5f5;
line-height: 1.9;
padding: 30px;
}
/* چیدمان کلی: نوار کناری ثابت، محتوا کشسان */
.layout {
display: flex;
gap: 25px;
}
.sidebar {
flex-basis: 220px;
flex-shrink: 0;
background-color: #2f4f4f;
color: white;
padding: 20px;
border-radius: 10px;
}
.content {
flex-grow: 1;
}
.content h2 {
color: #2f4f4f;
margin-bottom: 20px;
}
/* کارتها */
.cards {
display: flex;
flex-wrap: wrap;
gap: 20px;
align-items: flex-start;
}
.card {
flex-grow: 1;
flex-basis: 200px;
background-color: white;
padding: 22px;
border-radius: 10px;
border: 1px solid #dddddd;
transition: all 0.3s ease;
}
.card:hover {
border-color: #ff6347;
transform: translateY(-4px);
}
.card h3 {
color: #2f4f4f;
margin-bottom: 8px;
}
/* استثنا: کارت ویژه اول بیاید و کشیده شود */
.featured {
order: -1;
align-self: stretch;
border-top: 4px solid #ff6347;
}
نمونه نهایی فصل: نمونه 06-final-example
شرح مثال
این مثال یک چیدمان واقعی سایت است و هر پنج مفهوم فصل در آن نقش دارد:
-
gap. هم بین نوار کناری و محتوا و هم بین کارتها.
هیچ
marginای در کل فایل نیست. -
basis و grow و shrink. نوار کناری همیشه ۲۲۰ پیکسل
میماند چون
flex-shrink: 0دارد. محتوا باflex-grow: 1هر چه باقی ماند را میگیرد. کارتها همflex-basis: 200pxدارند و باflex-grow: 1فضای خالی سطر آخر را پر میکنند تا لبهها ناهموار نماند. - order. کارت ویژه در HTML آخرین کارت است، اما با
order: -1اول نمایش داده میشود. ترتیب محتوا در فایل دستنخورده مانده است. - align-self. ظرف کارتها
align-items: flex-startدارد، پس کارتها به اندازه محتوایشان کوتاه میمانند. اما کارت ویژه باalign-self: stretchتا ته کشیده میشود و بیشتر جلب توجه میکند. - transition. روی حالت عادی کارت نوشته شده، پس هم رفتن و هم برگشتن نرم است.
در hover: کارتها یک ویژگی تازه هم آمده است:
transform: translateY(-4px) که کارت را چهار پیکسل
به بالا میبرد و حس «بلند شدن» میدهد. این ویژگی را
در فصل سیزدهم کامل توضیح میدهیم.
پوشه 08-flexbox-advanced شامل نمونههای
01-gap تا 06-final-example.
خلاصه فصل
| ویژگی | روی چه | کارش |
|---|---|---|
gap | ظرف | فاصله بین آیتمها، بدون فاصله لبهها |
flex-basis | آیتم | اندازه اولیه |
flex-grow | آیتم | سهم از فضای اضافه، به صورت نسبت |
flex-shrink | آیتم | اجازه کوچک شدن. صفر یعنی هرگز. |
flex: 1 | آیتم | میانبر رایج برای رشد کردن |
order | آیتم | ترتیب نمایش. منفی هم مجاز است. |
align-self | آیتم | استثنا زدن به align-items ظرف |
transition | هر عنصر | نرم کردن تغییر. در حالت عادی بنویسید. |
تمرینهای فصل هشت
- چیدمان نوار کناری و محتوا را بسازید، طوری که با تغییر عرض پنجره تنها محتوا کم و بسیار شود.
- سه دکمه بسازید که رنگ و اندازهشان با
transitionنرم عوض شود. - در یک فهرست پنجتایی، با
orderکاری کنید آخرین مورد اول نمایش داده شود. - یک ظرف با
align-items: centerبسازید و یک آیتم را باalign-selfاستثنا کنید. - یک بار
transitionرا داخلhover:بنویسید و ببینید چرا برگشت ناگهانی میشود. - مقدار
gapرا از ۵ تا ۵۰ پیکسل عوض کنید و بهترین حالت را برای طرح خودتان پیدا کنید.