درس 35 از دوره آموزش HTML و CSS ارومیا دیزاین
برای قرار دادن چند کارت کنار هم، فاصله های تصادفی و عرض ثابت انتخاب می کنید، اما در موبایل چیدمان به هم می ریزد؟ Flexbox در CSS ابزار مناسبی برای تنظیم اندازه و تراز عناصر در یک مسیر است. در این جلسه، یک منوی فارسی، ردیف کارت های خدمات و بخش معرفی می سازیم. هدف، درک رابطه والد و فرزند است تا بتوانید چیدمان را با تغییر محتوا و عرض صفحه کنترل کنید.
پروژه و پاسخ تمرین: دانلود ZIP پروژه درس 35؛ شامل index.html، style.css، solution.css و راهنمای آزمایش. فایل را استخراج کنید و index.html را باز کنید؛ پروژه بدون اینترنت و نصب ابزار اجرا می شود.
Flexbox چیست و کجا به کار می آید؟
Flexbox یک روش چیدمان تک محوری است. ابتدا یک محور اصلی انتخاب می کنیم و سپس فضای موجود، فاصله و تراز فرزندان را روی آن تنظیم می کنیم. منو، نوار ابزار، گروه دکمه و کارت های یک ردیف نمونه های خوبی هستند. تک محوری بودن به معنای ممنوع بودن چند ردیف نیست؛ هر خط فلکس فضای خودش را مستقل تقسیم می کند. بنابراین برای شبکه ای که باید ستون های تمام ردیف ها دقیقا روی هم بمانند، در ادامه دوره Grid را هم بررسی می کنیم.
پیش از شروع، درس display در CSS را مرور کنید. اینجا display: flex روش چیدمان فرزندان را تغییر می دهد؛ خود والد همچنان در جریان عادی صفحه قرار دارد. برای اتصال فایل استایل نیز آموزش مقدماتی CSS راهنمای خوبی است.
اول والد را فلکس کنید
<div class="cards"> <article class="card">کارت اول</article> <article class="card">کارت دوم</article> <article class="card">کارت سوم</article> </div>
.cards {
display: flex;
gap: 20px;
}
سه article فرزند مستقیم cards هستند و آیتم فلکس می شوند. عنوان و پاراگراف داخل هر article خودکار عضو فلکس والد بیرونی نیستند. اگر می خواهید اجزای داخل کارت هم با فلکس تنظیم شوند، روی خود کارت یک چیدمان مستقل بسازید. این همان فلکس تو در تو است که برای لینک انتهای کارت از آن استفاده می کنیم.
نام کلاس ها اختیاری است، اما باید با HTML تطبیق داشته باشد. اگر قانون اجرا نمی شود، درس انتخابگرهای CSS را ببینید و در Inspect بررسی کنید که کلاس را روی عنصر درست نوشته اید.
محور اصلی، محور فرعی و جهت فارسی
.cards {
display: flex;
flex-direction: row;
}
.vertical {
display: flex;
flex-direction: column;
}
flex-direction با مقدار row محور اصلی را در جهت خط متن قرار می دهد. در صفحه فارسی با dir=”rtl” و شیوه نوشتن افقی، شروع row از راست است. مقدار column محور اصلی را در راستای بلوک، معمولا از بالا به پایین، قرار می دهد. محور فرعی بر محور اصلی عمود است. پس justify-content را همیشه افقی و align-items را همیشه عمودی تصور نکنید؛ با تغییر direction نقش فیزیکی آن ها تغییر می کند.
برای یک منوی فارسی عادی، dir=”rtl” همراه row کافی است. row-reverse را فقط برای فارسی کردن منو اضافه نکنید. reverse و order ترتیب دیداری را تغییر می دهند، اما ترتیب HTML و پیمایش صفحه کلید را به همان شکل تغییر نمی دهند. از ابتدا عناصر را در ترتیب منطقی بنویسید تا خواندن و پیمایش قابل پیش بینی بماند.
تفاوت justify-content و align-items
.toolbar {
display: flex;
justify-content: space-between;
align-items: center;
gap: 16px;
}
justify-content فضای آزاد باقی مانده در محور اصلی را توزیع می کند. برای دو بخش هدر، space-between می تواند آن ها را به دو انتهای ردیف ببرد. اگر آیتم ها با flex-grow تمام فضای آزاد را مصرف کنند، ممکن است تفاوت محسوسی از این ویژگی نبینید. gap حداقل فاصله میان آیتم ها را تامین می کند و با فضای توزیع شده جمع می شود؛ فاصله تا لبه والد را padding تعیین می کند.
align-items تراز آیتم ها در محور فرعی را کنترل می کند. center مرکز آن ها را هم راستا می کند و stretch، در شرایط مناسب و وقتی اندازه فرعی خودکار است، آیتم ها را در آن محور می کشد. در ردیف کارت ها، stretch به هم ارتفاع شدن کارت های همان خط کمک می کند. align-content ویژگی دیگری است و توزیع چند خط را در فضای آزاد محور فرعی کنترل می کند؛ برای یک خط کاربردی ندارد.
ساخت منوی فارسی با امکان شکستن خط
<nav aria-label="منوی اصلی">
<ul class="menu">
<li><a href="#services">خدمات</a></li>
<li><a href="#practice">تمرین</a></li>
<li><a href="#contact">تماس</a></li>
</ul>
</nav>
.menu {
display: flex;
flex-wrap: wrap;
gap: 12px;
list-style: none;
padding: 0;
margin: 0;
}
مقدار پیش فرض flex-wrap برابر nowrap است. در این حالت آیتم ها برای ماندن در یک خط تلاش می کنند و ممکن است کوچک شوند یا سرریز بسازند. wrap اجازه ساخت خط تازه را می دهد. در پروژه، عرض پنجره را کم کنید و ببینید منو چگونه می شکند. این نمونه منوی چندخطی ساده است؛ باز و بسته شدن منوی همبرگری به تعامل دیگری نیاز دارد و در این پروژه وجود ندارد.
لینک واقعی با مقصد مشخص بسازید و نشانه فوکوس را حفظ کنید. برای مرور تفاوت هاور با پیمایش صفحه کلید، درس hover و focus-visible را بخوانید. ظاهر زیبا به تنهایی کافی نیست؛ با Tab هم باید بتوانید به تمام لینک ها برسید.
اندازه کارت با grow، shrink و basis
.cards {
display: flex;
flex-wrap: wrap;
gap: 20px;
align-items: stretch;
}
.card {
flex: 1 1 240px;
min-width: 0;
}
سه مقدار flex در این مثال به ترتیب grow، shrink و basis هستند. basis برابر 240px اندازه پایه کارت را پیشنهاد می کند. grow برابر 1 اجازه می دهد کارت سهمی از فضای اضافه بگیرد. shrink برابر 1 هم اجازه کوچک شدن هنگام کمبود فضا را می دهد؛ میزان واقعی کاهش فقط به این عدد وابسته نیست و اندازه پایه نیز اثر دارد. بنابراین این عبارت به معنی عرض ثابت 240 پیکسل نیست.
در ردیف کامل، کارت های هم پایه معمولا سهم برابر می گیرند. در آخرین خط، اگر فقط یک کارت باقی بماند، grow آن را در عرض موجود گسترش می دهد. اگر این رفتار را نمی خواهید، باید سیاست اندازه گذاری دیگری انتخاب کنید. برای یادگیری این تفاوت، یک کارت جدید اضافه کنید و عرض پنجره را چند بار تغییر دهید. با حدس یک عرض خاص برای همه دستگاه ها، انعطاف چیدمان را محدود نکنید.
min-width: 0 اجازه می دهد کارت از حداقل اندازه خودکار مبتنی بر محتوا کوچک تر شود. متن بدون فاصله همچنان به قانون شکستن نیاز دارد؛ برای پاراگراف از overflow-wrap: anywhere استفاده کنید. درس مدیریت overflow تفاوت شکستن متن با پنهان کردن سرریز را توضیح می دهد.

هم راستا کردن لینک انتهای کارت ها
.card {
display: flex;
flex-direction: column;
flex: 1 1 240px;
min-width: 0;
padding: 24px;
}
.card a {
margin-block-start: auto;
align-self: flex-start;
}
هر کارت در کنار عضویت در فلکس بیرونی، یک والد فلکس ستونی هم هست. margin-block-start: auto فضای آزاد بالای لینک را می گیرد و لینک را به انتهای کارت می برد. این روش وقتی مفید است که کارت های یک خط ارتفاع مشترک و متن های متفاوت دارند. هم ترازی را برای همان خط بررسی کنید؛ خطوط جدا ارتفاع یکسان تضمین شده ندارند.
برای زیبایی کارت، از کادر و گوشه گرد در CSS استفاده کنید. padding فضای داخلی را می سازد و gap فاصله کارت ها را. با مدل جعبه CSS نیز می توانید اثر border و box-sizing را روی اندازه نهایی بررسی کنید.
ساخت بخش معرفی با دو قسمت انعطاف پذیر
.hero {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 24px;
}
.hero > * {
flex: 1 1 280px;
min-width: 0;
}
در پروژه، یک قسمت متن معرفی و قسمت دیگر یادداشت آموزشی است. هر دو از پایه 280px شروع می کنند و وقتی جا کافی نیست، به خط بعد می روند. این یک نمونه سازگاری با عرض صفحه بدون نقطه شکست ثابت است. در طراحی واقعی ممکن است با توجه به محتوا و اهداف صفحه، media query هم لازم باشد؛ فلکس نیاز به تمام قواعد واکنش گرایی را حذف نمی کند.
عیب یابی چیدمان Flexbox
اگر آیتم ها کنار هم قرار نمی گیرند، ابتدا display والد و مستقیم بودن فرزندان را بررسی کنید. اگر فاصله ایجاد نمی شود، gap را روی همان والد بنویسید. اگر center نتیجه ندارد، محور اصلی و فضای آزاد را ببینید. برای وسط چین عمودی، والد باید فضای عمودی بیشتری از محتوا داشته باشد؛ یک والد هم ارتفاع با محتوا فضای اضافه ای برای جابه جایی ندارد.
اگر صفحه در موبایل اسکرول افقی دارد، سراغ عرض ثابت، رشته بدون فاصله و حداقل اندازه آیتم بروید. overflow: hidden روی body دلیل مشکل را برطرف نمی کند. در ابزار توسعه، حالت نمایش Flex را فعال کنید و مرز والد، فاصله و تعداد خطوط را ببینید. سپس فقط قانونی را تغییر دهید که علت را توضیح می دهد.
تمرین مستقل همراه پاسخ
در بخش practice پروژه، سه مورد عمدا زیر هم هستند. آن ها را با فاصله 12px کنار هم بگذارید، امکان رفتن به خط بعد بدهید و اندازه پایه هر مورد را 180px انتخاب کنید. ابتدا خودتان قانون را بنویسید؛ بعد فایل solution.css را با افزودن خط زیر، پس از style.css در head فعال کنید.
<link rel="stylesheet" href="solution.css">
.practice {
display: flex;
flex-wrap: wrap;
gap: 12px;
}
.practice > span {
flex: 1 1 180px;
min-width: 0;
}
پاسخ فقط بخش تمرین را تغییر می دهد. برای آزمایش نهایی، پنجره را در عرض های 320، 768 و 1280 پیکسل ببینید. متن یک کارت را بلند کنید و کارت چهارم را اضافه کنید. تمام لینک ها را با Tab دنبال کنید. صفحه نباید اسکرول افقی ناخواسته داشته باشد و هیچ محتوای ضروری نباید پشت برش پنهان بماند.
پرسش های متداول
آیا display: flex تمام عناصر داخلی را فلکس می کند؟
خیر؛ فرزندان مستقیم وارد چیدمان فلکس والد می شوند. برای اجزای داخل هر کارت، روی خود کارت چیدمان جدا تعریف کنید.
آیا justify-content همیشه تراز افقی است؟
خیر؛ این ویژگی با محور اصلی کار می کند. در column محور اصلی معمولا عمودی است.
چرا آخرین کارت تمام عرض را می گیرد؟
در مثال این درس، flex-grow برابر 1 است و کارت تنها، فضای آزاد خط خود را می گیرد.
برای صفحه فارسی row-reverse لازم است؟
معمولا خیر؛ dir برابر rtl و جهت row، شروع ردیف را با جهت فارسی هماهنگ می کنند.
آیا پروژه پاسخ آماده هم دارد؟
بله؛ فایل solution.css و راهنمای فعال سازی آن داخل ZIP هستند. پاسخ در حالت اولیه فعال نیست.
دانلود پروژه کامل و پاسخ تمرین درس 35
منبع فنی برای مطالعه بیشتر: مشخصات رسمی CSS Flexible Box Layout در W3C. مثال های این درس برای تمرین چیدمان منو و کارت نوشته شده اند؛ با تغییر محتوا و عرض صفحه، رفتار هر قانون را جدا مشاهده کنید.


بدون دیدگاه