Flexbox را یاد بگیریم!

وقتی ریدیزاین و پیاده سازی وبلاگ جدیدم را شروع کردم (که به زودی راه اندازی میشه) قبلا به خاطر مشغله کاری فرصت نشده بود Flexbox را مطالعه کنم تصمیم گرفتم وبلاگم را با استفاده از این ساختار جدید css پیاده سازی کنم و از طرفی طی یک مقاله نحوه کار و یادگیری آن را آرشیو کنم.

انگیزه یادگیری Flexbox از ویدیو‌های آموزشی Jeffrey Way با عنوان
Learn Flexbox Through Examples
ایجاد شد و با مثال‌های جذابی که دیدم تصمیم گرفتم کامل این مبحث را یاد بگیرم.

در این مقاله در رابطه با موضوعات مختلف Flexbox صحبت می‌کنیم در مورد تگ‌های والد (the flex container) و آیتم‌های زیر مجموعه آنها (the flex items) نکات مختلف را می‌نویسیم.

هدف Flexbox Layout مهیا کردن یک روش کارآمد و موثر برای مدیریت Box Layoutها است روشی برای تراز و توزیع آیتم‌ها در باکس‌هایی که طول و عرض آنها یا درحال تغییر است و یا نامشخص است. (واژه Flex در واقع به همین معنای انعطاف‌پذیری است)

ایده‌ای که برای flex مطرح است این است که قابلیتی را به container می‌دهد تا عرض/ارتفاع آیتم‌ها را به نحوی تغییر دهد که بهترین استفاده را از فضاهای خالی در دسترس داشته باشد. ( نمایش آنها را با صفحه نمایش تطبیق می‌دهد) یک flex container آیتم‌ها را برای استفاده از فضاهای خالی توزیع می‌کند و یا برای پیشگیری از سرریز شدن سایز آنها را کاهش می‌دهد.

نکته بسیار مهم در Flexbox این است که بر خلاف طراحی و سبک معمولی که باکس‌ها در ردیف‌های افقی کنارهم قرار می‌گیرند و یا در حالت inline به صورت ستونی در کنارهم قرار می‌گیرند، کاملا انعطاف پذیر است.( مخصوصا برای حالتهای مختلف جابجایی، ریسپانسیو، توزیع یکسان در حالتهای عمودی و افقی و … )

Flexbox تنها یک property نیست بلکه مجموعه‌ای از propertyهاست که با استفاده از آنها می‌توانیم انعطاف پذیری زیادی را به پروژه خود اضافه کنیم. برخی از این ویژگی‌ها به container اعمال می‌شوند ( parent element, known as “flex container” ) و برخی از آنها به زیرمجموعه آنها یعنی childrenهای یک تگ اعمال می‌شوند. (flex items)

در حالت معمولی المان‌هایی که در صفحه‌ داریم به صورت یکی از دو حالت block یا inline هستد (block and inline flow directions) ولی در حالت flexbox این المان‌ها بر اساس flex-flow directions هستند. برای درک flexbox در ادامه مقاله تصویر زیر کمک زیادی میکند.

Flexbox Attributes

بعد از توضیحاتی که تا الان ذکر کردیم شروع به توضیح بخش‌های مختلف flexbox میکنیم.

display

با استفاده از display به صورت نمونه کد زیر container را آماده می‌کنیم که فرزندهای مستقیم آن felx itemهای آن قرار گیرند.( It enables a flex context for all its direct children)

.container {
  display: flex; /* or inline-flex */
}

flex-direction

با استفاده از این ویژگی یک main-axis ایجاد می‌شود که direction آیتم‌های داخل container را مشخص می‌کند. به این فکر کنید که میخواهید آیتم‌های داخل container به صورت افقی یا عمودی قرار بگیرند و direction آنها به چه صورت باشد.

.container {
  flex-direction: row | row-reverse | column | column-reverse;
}

row: افقی چپ به راست وقتی که direction: ltr باشد. (پیشفرض) وقتی که direction:rtl باشد راست به چپ است.

row-reverse: افقی راست به چپ وقتی که direction:ltr باشد. در حالتیکه direction:rtl باشد آیتم‌ها چپ به راست هستند.

column: مشابه row است با این تفاوت که آیتم‌ها به صورت ستونی از بالا به پایین هستند.

column-reverse: مشابه row-reverse است با این تفاوت که آیتم‌ها به صورت ستونی از پایین به بالا قرار می‌گیرند.

flex-wrap

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

.container{
  flex-wrap: nowrap | wrap | wrap-reverse | initial | inherit;
}

flex-flow

یک shortkey برای اعمال ویژگی‌های flex-direction و flex-wrap است. به صورت پیشفرض مقدار row nowrap را می‌گیرد. flex-flow برای parent یعنی flex-container اعمال می‌شود.

flex-flow: <‘flex-direction’> || <‘flex-wrap’>

justify-content

این property وضعیت قرارگیری المان‌ها در main-axis را مشخص می‌کند. این ویژگی کمک می‌کند تا فضاهای خالی موجود در container به صورت مناسب برای قرارگیری آیتم‌ها توزیع شود و در برخی موارد کنترل بیشتری روی آیتم‌ها اعمال می‌کند در مواقعی که از یک ردیف خارج می‌شوند.

.container {
  justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly;
}

flex-start: آیتم‌ها در ابتدای ردیف قرار می‌گیرند. (پیشفرض)

flex-end: آیتم‌ها در انتهای ردیف قرار می‌گیرند.

center: آیتم‌ها در مرکز ردیف موردنظر قرار می‌گیرند.

space-between: آیتم‌ها با فاصله مساوی در یک ردیف توزیع می‌شوند. آیتم اول در ابتدای ردیف و آیتم آخر در انتهای ردیف قرار می‌گیرد.

space-around: آیتم‌ها با ایجاد فاصله‌های مساوی در اطرافشان، در یک ردیف توزیع می‌شوند. توجه کنید که وقتی به تصویر نگاه کنید متوجه می‌شوید که فاصله بین آیتم‌ها یکسان نیست چونکه هر آیتم در اطراف خود یک فاصله مشخص دارد و وقتی دو آیتم در کنار هم قرار میگیرند هر کدام یک فاصله برای خود دارند و آیتمی که در ابتدا و انتهای ردیف قرار دارند از ابتدا و انتها فقط یک فاصله دارند.

space-evenly: آیتم‌ها با فاصله‌های کاملا مساوی در یک ردیف توزیع می‌شوند. در این حالت فاصله‌ها در تمام بخش‌ها یکسان است.

align-items

با استفاده از این property رفتار آیتم‌ها در ردیف موردنظر را در حالت cross axis تعریف می‌کنیم. align-items در واقع شبیه به justify-content است با این تفاوت که align-items در حالت عمودی(cross axis) اعمال می‌شود ولی justify-content در حالت افقی (main axis) اعمال می‌شود.

.container {
  align-items: stretch | flex-start | flex-end | center | baseline;
}

stretch: آیتم‌ها را به اندازه‌ای که container را پر کند تغییر می‌دهد.(پیشفرض)

flex-start: آیتم‌ها را در ابتدای ستون در مکان cross-start قرار می‌دهد.

flex-end: آیتم‌ها را در انتهای ستون در مکان cross-end قرار می‌دهد.

center: آیتم‌ها بر اساس cross-axis در مرکز ستون قرار می‌گیرند.

baseline: آیتم‌ها بر اساس خطوط اصلی آنها در یک راستا قرار می‌گیرند.

align-content

این property تمام آیتم‌ها را بر اساس ردیف‌هایی که در container وجود دارد (فضاهای خالی اضافی) در حالت cross-axis بر اساس مقدار آن تنظیم می‌کند.

نکته: در حالتی که ما برای آیتم‌های موجود یک ردیف داشته باشیم این property بی‌تاثیر است.

.container {
  align-content: flex-start | flex-end | center | space-between | space-around | stretch;
}

تا به اینجا در رابطه با ویژگی‌هایی که برای flex-container تعریف می‌شود صحبت کردیم، اکنون ویژگی‌هایی که برای flex-items تعریف می‌شوند را مورد بررسی قرار می‌دهیم.

order

به صورت پیشفرض آیتم‌هایی که در flex-container قرار می‌گیرند به ترتیبی که ایجاد می‌شوند قرار می‌گیرند ولی با این وجود می‌توان برای آنها ترتیب اولویت تعریف کرد.

.item {
  order: ; /* default is 0 */
}

flex-grow

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

در صورتیکه همه آیتم‌های flex-container مقدار flex-grow:1 داشته باشند در واقع تمام آیتم‌های به میزان کاملا یکسان در فضای خالی توزیع می‌شوند. اگر یکی از آیتم‌ها مقدار ۲ داشته باشد دوبرابر بقیه فضا را در اختیار خواهد داشت.(عدد منفی نامعتبر است.)

.item {
  flex-grow: ; /* default 0 */
}

flex-shrink

این property این قابلیت را تعریف می‌کند که بتوانیم آیتم‌های flex-container را در صورت لزوم به میزانی که لازم است فضایی که اشغال می‌کنند را کوچکتر کند. (عدد منفی نامعتبر است.)

.item {
  flex-shrink: ; /* default 1 */
}

flex-basis

این property مقدار سایز پیشفرض یک آیتم را تعریف می‌کند قبل از آنکه فضای باقی مانده بین آیتم‌ها توزیع شود. مقادیر این property میتواند عدد (۱۵%, ۴rem, etc) و یا یکسری از کلمات کلیدی باشند. کلمه کلیدی auto تعیین می‌کند که بر اساس عرض و ارتفاع آیتم به آن فضا داده شود.

.item {
  flex-basis:  | auto; /* default auto */
}

در صورتیکه مقدار آن را ۰ قرار دهیم فضای خالی که اطراف content وجود دارد حذف می‌شود و در صورتیکه مقدار آن را auto قرار دهیم فضای خالی اطراف آن به اندازه flex-grow توزیع خواهد شد.

https://www.w3.org/TR/css-flexbox-1/images/rel-vs-abs-flex.svg

flex

این property در واقع shortkey برای قرار دادن مقادیر flex-grow, flex-shrink و flex-basis است. مقادیر flex-shrink و flex-basis اختیاری است. و مقدار پیشفرض آن ۰ ۱ auto است.

.item {
  flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
}

align-self

این property این اجازه را می‌دهد که یک آیتم مقدار پیشفرضی که برای آن تعریف شده است را overrideکند و مقدار جدیدی را بگیرد. مقادیری که میگیرد به صورت زیر است.

.item {
  flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
}

توجه کنید که clear, float و vertical-align هیچ تاثیری روی flex-item ندارند.

در نهایت پیشنهاد میکنم سایت bennettfeely را برای تست حالتهای مختلف flexbox مشاهده کنید.

مطالعه بیشتر:

طراحی ریسپانسیو ( Responsive ) از ایده تا اجرا !

با شنیدن نام ریپسپانسیو ( responsive ) یا واکنش گرا این تصویر برای ما تداعی میشود که وب سایتی که واکنش‌گراست از طریق موبایل و سایر دیوایس‌ها در دسترس است، ولی واقعا چند درصد از این وب سایتهای ریسپانسیو قابل استفاده هستند؟!

یکی از مشکلات عمده اشخاصی که در حوزه UI/UX و فرانت‌اند کار می‌کنند پیاده سازی وبسایتی ریسپانسیو و کارا مطابق نظر مشتری یا صاحب پروژه است که با وجود عدم آشنایی با این مفهوم قصد دارد همه موارد داخل وبسایت که از طریق دسکتاپ قابل دسترس است روی موبایل و تبلت هم وجود داشته باشد!

قبلا در مقاله نوشته بودم که همیشه حق با مشتری نیست!

نکته : پروژه‌ای که ما برای کارفرما پیاده‌سازی می‌کنیم قطعا باید مورد پسند کارفرما باشد ولی این به این معنا نیست که هر چیزی که کارفرما درخواست داشت درست است، باید این اعتماد را ایجاد کنیم که کاری که انجام می‌شود بر اساس تجربه و دانشی است که در نهایت به نفع کارفرما تمام می‌شود و رابطه‌ی کاری برد-برد را مدنظر داریم در واقع این هنر توسعه دهنده است که چطور کارفرما را قانع کند.

پرسش و پاسخ برای درک یک واقعیت!

بیایید با طرح دو سوال به سبکی بهتر به موضوع بپردازیم :

  • چرا هنگام چک کردن و یا انتقال وجه از حساب بانکی خود از  وب‌سایت اصلی بانک موردنظر استفاده نمی کنید؟
  • چرا اپلیکیشن بانک مورد نظر را دانلود و از آن برای بررسی موجودی و …. استفاده می‌کنید؟

پاسخ ۱ : به این‌خاطر که فقط اطلاعات کاربردی و موردنیاز نمایش داده میشود و کار کردن با آن بسیار راحتتر از وب سایت برروی موبایل است.

پاسخ ۲ : به این خاطر که وب‌سایت فونت ریزی داره و اطلاعات اضافی زیادی وجود دارد.

پاسخ ۳ : سرعت بارگذاری پایین است، امکان انتخاب منو‌ها و آیتم‌ها سخت است و….

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

لازم است تاکید کنم هر پروژه ای بر اساس ماهیتی که دارد سبک اجرای آن متفاوت است، برای مثال وقتی پروژه مورد نظر ما یک وبلاگ است که درآمد این وبلاگ از تبلیغ هایی است که قرار می‌دهد قطعا ساختار طرح ریسپانسیو آن متفاوت خواهد بود با پروژه‌‌های دیگر.

یک سوال که اینجا مطرح می‌شود این است که این نیاز کاربران را از کجا تشخیص دهیم؟

 

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

در واقع ما وب‌سایت و پروژه را باید برای مشتری طراحی کنیم نه کارفرما! چونکه مشتری کارفرما رو به هدفی که می‌خواهد می‌رساند که این هدف می‌تواند پول و درآمد بیشتر باشد.

برای مثال یکی از دوستان من که در یکی از شرکت‌های بزرگ فروشگاهی فعالیت داشت، اظهار داشت که فروش محصولات فروشگاهی نسبت به بازدید صفحات محصول کمتر از مقدار مورد انتظار بود. بعد از تحلیل و بررسی رفتار کاربران و تغییر رنگ دکمه خرید و مکان دکمه خرید فروش محصولات را به میزان ۲۰ درصد افزایش دادند و این یعنی موفقیت در پروژه.

در نهایت لازم است تاکید کنم راه تشخیص اینکه کدام مورد بهتر و بهینه‌تر است تست و تحلیل نتایج است، یکی از راههایی که خیلی میتواند کمک کند A/B Testing است که مثلا به صورت رندم برای برخی کاربران استایل به یک سبکی نمایش داده شود و نتایج بررسی شود. این مورد مخصوصا در ایمیل مارکتینگ بسیار کاربردی و تاثیرگذار است که با استفاده از ابزارهایی همچون میل چیمپ و میلرلایت و … میتوان این موارد را تست کرد.

معرفی ابزارهایی برای آنالیز و تحلیل وب‌سایت و رفتار کاربران :

شما می‌توانید از ابزارهایی که وب‌سایت‌های زیر ارائه می‌دهند استفاده نمائید تا روند بهبود و رشد وب‌سایت خود را فرآهم کنید.

۱. گوگل آنالیتیک –  Google Analytics

۲. هات‌جار – Hotjar

۳. کریزی اِگ – Crazy Egg

در صورت تمایل می‌توانید کلمه Heat Map را در گوگل جستجو نمائید تا در رابطه با این موارد بیشتر مطالعه کنید.

 

استفاده از css preprocessor برای توسعه وب سایت

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

هرچقدر کدهای بخش فرانت‌اند را ماژولار و منظم بنویسیم باز دستمون برای ساختاری منظم برای توسعه راحتتر بسته است به همین دلیل استفاده از css preprocessor ها کار ما را خیلی راحت‌تر میکند به طوریکه حتی بتوانیم در سایر پروژه‌ها از بخشی از کدها استفاده کنیم.

استفاده از Sass

sass

Sass یکی از قدرتمندترین css preprocessor های موجود است که بهتون توصیه میکنم در استفاده از آن شک نکنید. لازم است تاکید کنم Sass هیچ چیزی به css اضافه نمی کند ولی قابلیت‌هایی به شما می‌دهد که بتوانید از کدنویسی سمت فرانت‌اند هم بیشتر لذت ببرید و هم امکاناتی را در اختیار شما قرار میدهد که تاثیر بسیار مثبتی روی پروژه‌ی شما می‌گذارد.

برای مثال ‌قابلیت‌هایی همچون تعریف متغیر، ایجاد فانکشن و … را در اختیار شما قرار میدهد.

Sass is an extension of CSS that adds power and elegance to the basic language. It allows you to use variables, nested rules, mixins , inline imports, and more, all with a fully CSS-compatible syntax. Sass helps keep large stylesheets well-organized, and get small stylesheets up and running quickly, particularly with the help of the Compass style library.

شما میتوانید متغیرهایی را تعریف کنید و در بخش‌های مختلف پروژه از آن استفاده نمایید. همچنین میتوانید فایلهای جامعی برای تعریف فانکشن داشته باشید و برای بخش های مختلف پروژه از آن استفاده نمائید و یا قابلیت nesting برای تگ ها داشته باشید و در نهایت Sass  به css کانورت میکند.

برای مثال :

sass to css

نصب Sass

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

نصب Sass  بر روی مک

gem install sass

برای اینکه مطمئن شوید که Sass  نصب شده است می‌توانید کد زیر را در ترمینال اجرا کنید که ورژن Sass  نصب شده را نمایش می دهد.

sass -v

استفاده از Compass

compass style

در صورتیکه میخواهید از Sass  استفاده کنید بدون Compass  از آن استفاده نکنید! در واقع در بالا اشاره کردیم که شما میتوانید mixinهایی را تعریف کنید تا بتوانید راحت‌تر کدهای سمت فرانت‌اند  را توسعه دهید اما زمان بسیار زیادی لازم است تا شما تمام فانکشن‌هایی که لازم دارید را بنویسید به همین خاطر استفاده از Compass  که براساس Sass  به صورت متن‌باز نوشته شده است را توصیه میکنم.

برای استفاده از Compass  میتوانید توی ترمینال کد زیر را اجرا کنید :

 gem install compass

بعد از نصب آن، داخل فایل های Sass  ابتدا Compass  را import  کنید و سپس از امکانات آن استفاده می‌کنید.

@import "compass/css3"

 

@import "compass/css3";
 
@import "compass/utilities";
 
#demo {
  @include clearfix;
}
 
.border-radius-example {
  width: 125px;
  height: 125px;
  background: red;
  margin: 20px;
  float: left;
  padding: 5px;
}
 
#border-radius {
  @include border-radius(25px);
}
 
#border-radius-top-left {
  @include border-top-left-radius(25px);
}

استفاده از Susy

Susy

در صورتیکه با فریمورک‌هایی همچون FoundationBootstrap کار کرده باشید قطعا با طراحی واکنش‌گرا ( responsive ) و گریدبندی آشنا هستید. نقطه قوت این فریم‌ورک‌ها ریسپانسیو بودن و کامپوننت‌هایی است که میتوان استفاده کرد.

برای اینکه شما با استفاده از Sass این ساختار را ایجاد کنید میتوانید خودتون برای گریدبندی و حالتهای مختلف کدنویسی کنید و یا از ابزارهایی همچون Susy استفاده کنید.

با استفاده از Susy شما میتوانید برای هر پروژه و بسته به نیازتون گریدبندی‌های مختلف داشته باشید.

برای نصب آن کافی است داکیومنتیشن آن را مطالعه نمایید، برای نصب آن بر روی مک می توانید کد زیر را اجرا نمایید :

gem install susy

برای استفاده از آن باید همچون Compass آن را import  نمایید.

@import "compass/css3";
@import "susy";

$susy: (
    columns: 12,
    container: 1200px,
    gutters: 1/4,
    global-box-sizing: border-box,
    debug: (image: hide)
);

در کد بالا شما تنظیمات Susy را برای پروژه می بینید که ۱۲ ستونه است و عرض تگ container آن ۱۲۰۰ پیکسل است و همچنین فضای خالی ( margin ) بین هر ستون است که میتوانیم مشخص کنیم قبل یا بعد از هر ستون قرار بگیرد.

gutter after in susy
منبع :  zellwk.com/blog/susy-gutter-positions

در صورتیکه حالت debug  را روی حالت نمایش قرار دهید بر روی پروژه مکان هر گرید را میتوانید ببینید.

تنظیمات کلی و پیشفرض susy به صورت زیر است که میتوانید هر کدام را تغییر دهید :

$susy: (
  flow: ltr,
  math: fluid,
  output: float,
  gutter-position: after,
  container: auto,
  container-position: center,
  columns: 4,
  gutters: .25,
  column-width: false,
  global-box-sizing: content-box,
  last-flow: to,
  debug: (
    image: hide,
    color: rgba(#66f, .25),
    output: background,
    toggle: top right,
  ),
  use-custom: (
    background-image: true,
    background-options: false,
    box-sizing: true,
    clearfix: false,
    rem: true,
  )
);

در نهایت یک نمونه کد یکی از کاربران که این ساختار را نوشته است می توانید ببینید و تست کنید :

See the Pen Susy Grid Example 1A by Michelle Barker (@michellebarker) on CodePen.