چگونه یک منو واکنشگرا با FlexBox ایجاد کنیم
ﺯﻣﺎﻥ ﻣﻄﺎﻟﻌﻪ: 6 دقیقه

چگونه یک منو واکنشگرا با FlexBox ایجاد کنیم

در این مطلب قصد دارم به شما شیوه ساخت یک نوار منو توسط FlexBox و قدرت Media queries را توضیح دهم. این نوار منو توانایی تطبیق یافتن با اندازه‌های مختلف صفحه نمایش را دارد.

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

پیاده‌سازی اولیه

برای شروع قصد داریم با استفاده از HTML یک نوار منو ساده را ایجاد کنیم. 

<nav>
  <ul class="container">
    <li>Home</li>
    <li>Profile</li>
    <li class="search">
      <input type="text" class="search-input" placeholder="Search">
    </li>
    <li>Logout</li>
  </ul>
</nav>

المان <ul> ما قسمت flex ما را شامل می‌شود و المان <li> نیز یکی از آیتم‌های این بخش به حساب می‌آید. برای اینکه این موارد را به صورت Flex دربیاوریم باید شیوه نمایش کلاس container را تغییر دهیم.

.container {
  display: flex;
}

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

در این مثال استایل‌های دیگری اضافه شده اما این موضوع هیچ ربطی به Flexbox ندارد.

همانطور که مشاهده می‌کنید ما به میزانی فضای خالی در سمت راست منوی‌مان داریم. این بدان دلیل است که لایه‌بندی Flexbox از سمت چپ به راست شروع می‌شود و هر مورد تنها به اندازه محتوای خود فضا را اشغال می‌کند.

جدای از آن قسمت container مربوط به Flexbox بزرگ‌تر از چهار آیتم است و به صورت المانی در حالت Block نمایش یافته است. در نهایت به این دلیل با یک فضای اضافی در انتها خواهیم داشت. 

اگر دقت کنید متوجه می‌شوید که آیتم مربوط به جستجو بزرگ‌تر از دیگر آیتم‌هاست این مورد بدان دلیل است که مقدار آن ورودی است و ورودی به صورت پیشفرض ورودی برابر با ۲۰ دارد (size="20"). البته این موضوع در مرورگرهای مختلف و سیستم‌عامل‌های گوناگون ممکن است تفاوت‌هایی نیز داشته باشد.

واکنشگرایی ۱

برای اینکه مقدمات واکنشگرایی را برای منوی‌مان ایجاد کنیم، با به سادگی مقدار flex مربوط به آیتم جستجو را برابر یک قرار می‌دهیم:

.search {
  flex: 1;
}

نتیجه انجام چنین کاری این خواهد بود که با تغییر اندازه برگه و بزرگ و کوچک شدن آن، ورودی نیز کوچک و بزرگ می‌شود. این بدان معناست که ما دیگر فضای اضافی در کنار برگه نخواهیم داشت.

در حالی که به سادگی می‌توان در تصویر بالا مشاهده کنید که با تغییرات دیگر المان‌ها ثابت می‌ایستند این موضوع به نظر ناخوشایند می‌رسد، به این دلیل که ممکن است ناهمخوانی بین المان‌ها بوجود بیاید. بنابراین برای اینکه بخواهید همراه با تغییرات اندازه مرورگر، تمام آیتم‌ها نیز واکنش نشان دهند، می‌توانید به سادگی استایل flex: 1 را به تمامی المان‌های container بدهید :

.container > li {
  flex: 1;
}

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

شما می‌توانید به آيتم‌های مختلف مقدار flex متفاوت بدهید که این کار باعث می‌شود سرعت تغییرات آن‌ها از همدیگر متفاوت باشد. بهتر است چندبار خودتان آزمایش کنید. 

واکنشگرایی ۲

منوی ما با صفحات نمایش عریض به خوبی کار می‌کند. اما همانطور که در تصویر زیر می‌بینید یک مشکل دیگر نیز وجود دارد:

وقتی که container ما محدود می‌شود، آیتم‌ها منطقا نباید در یک ردیف باقی بمانند. برای حل این مشکل ما قصد داریم از Media query استفاده کنیم. قصد داریم که این چهار آیتم را در دو ردیف جداگانه قرار دهیم. در این مثال قصد داریم که اگر صفحه نمایش به مقدار ۶۰۰ پیکسل رسید، ردیف‌ها به درستی ظاهر شوند.

@media all and (max-width: 600px) {
  
  .container {
    flex-wrap: wrap;
  }
  
  .container > li {
    flex-basis: 50%;
  }
}

اول از همه باید اجازه بدهیم که لایه بندی flexbox فضای container ما را درست بسته بندی کند، برای این کار از flex-wrap استفاده می‌کنیم. به صورت پیشفرض مقدار این استایل nowrap است اما می‌توانیم مقدار آن را به wrap تغییر دهیم.

کار بعدی که باید انجام دهیم این است که مقدار flex-basis را برابر با 50٪ قرار دهیم. این حالت به Flexbox می‌گوید که 50٪ عرض را در اختیار آیتم‌ها قرار بده. انجام چنین کاری سبب می‌شود که دو ردیف از آیتم‌ها را داشته باشیم.

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

مشکلی که در اینجا پیش می‌آید این است که ردیف دومی نمی‌تواند به درستی آیتم‌ها را در کنار هم قرار دهد. دکمه مربوط به Logout و ورودی Search دارای عرض بیشتری هستند و نمی‌توانند در کنار یکدیگر قرار بگیرند.  اما آیتم‌های ردیف اول به درستی در کنار یکدیگر قرار گرفته‌اند، این موضوع بدان دلیل است که مقدار ورودی فیلد جستجو با دیگر آیتم ها متفاوت است. به نظر می‌رسد که انتظار داشتن برای داشتن یک نتیجه در هر دو ردیف کاری غیرمنطقی است. 

واکنشگرایی ۳

مشکلی که داشتیم این بود که نمی توانستیم چند المان را در یک ردیف داشته باشیم و این موضوع نیز در صفحات کوچک‌تر منطقی نیست. به همین دلیل قصد داریم که شیوه نمایش منو را از حالت افقی به حالت عمودی تغییر دهیم. در این حالت هر آیتم در زیر آیتمی بالایی قرار می‌گیرد. 

برای پیاده‌سازی چنین حالتی به سادگی تنها نیاز به این داریم که مقدار عرض ۵۰٪ را برابر ۱۰۰٪ قرار دهیم. در این صورت هر ردیف تنها یک آیتم را در بر می‌گیرد. برای این کار ما یک نقطه شکست در ۴۰۰ پیکسل قرار می‌دهیم.

@media all and (max-width: 400px) {
  .container > li {
    flex-basis: 100%;
  }
  .search {
    order: 1;
  }
}

در چنین حالتی من دوست دارم که فیلد جستجو را در زیر تمام آیتم‌ها قرار دهم، به همین دلیل باید مقدار order را برابر ۱ قرار دهم. نتیجه کار به صورت زیر خواهد بود:

دلیلی که order: 1; باعث می‌شود آیتم به پایین‌ترین مکان بیاید این است که مقدار هر آیتم برابر با صفر است و در نتیجه المانی زودتر نمایش می‌یابد که در قسمت HTML دارای اولویت بالاتری باشد. برای اینکه نتیجه نهایی را به درستی متوجه شویم می‌توانید Gif زیر را نگاه کنید. 

تبریک می‌گویم حال شما می‌توانید یک منو واکنشگرای بسیار خوب را با استفاده از Flexbox و Media query ایجاد کنید. 

منبع

چه امتیازی برای این مقاله میدهید؟

خیلی بد
بد
متوسط
خوب
عالی
5 از 1 رای

/@arastoo
ارسطو عباسی
کارشناس تولید و بهینه‌سازی محتوا

کارشناس ارشد تولید و بهینه‌سازی محتوا و تکنیکال رایتینگ - https://arastoo.net

دیدگاه و پرسش

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

در حال دریافت نظرات از سرور، لطفا منتظر بمانید

در حال دریافت نظرات از سرور، لطفا منتظر بمانید