وقتی ریدیزاین و پیاده سازی وبلاگ جدیدم را شروع کردم قبلا به خاطر مشغله کاری فرصت نشده بود 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 توزیع خواهد شد.

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 مشاهده کنید.