با سلام به شما عزیزان ، صبحتون بخیر و شادی .یکی از مواردی که در طراحی زیاد با آن مواجه می‌شویم٬‌ در مرکز قراردادن یک box در طرح است. فکر نمی‌کنم از خوانندگان این مطلب کسی باشد که نداند چطور می‌توان یک باکس را در مرکز یک باکس دیگر یا در مرکز صفحه قرار داد. به جرات می‌توان گفت که محال است که طراحی انجام دهید و لازم نباشد که باکسی را در مرکز صفحه قرار دهید. انجام این کار تنها با یک خط CSS امکان پذیر است. مشکل زمانی بروز می‌کند که تصمیم می‌گیریم یک باکس را به شکل عمودی در مرکز صفحه قرار دهیم. شیوه‌های بسیار زیادی برای حل این مشکل وجود دارد که که اینجا همه را بررسی می‌کنیم. هر شیوه مزایا و معایب خاص خود را دارد و باید بنا به شرایط موجود یک شیوه را انتخاب کنید.

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

.container {
margin: 0 auto;
}

وقتی باکس ما position نداشته باشد٬ اگر از margin: auto; استفاده کنیم٬ مرورگر آن را صفر در نظر می‌گیرد. زمانی که یک باکس در جریان کلی صفحه قرار گرفته باشد٬ اگر از margin: auto; استفاده کنیم٬‌ مرورگر برای سمت بالا و پایین مقدار صفر را در نظر خواهد گرفت. نخست سراغ شیوه اول که راحت‌ترین راه است می‌رویم:
۱. استفاده از طول و عرض ثابت و margin منفی

همانطور که ذکر کردم٬‌ این شیوه راحت‌ترین راه است و بهترین ساپورت را هم دارد ولی ایراداتی دارد که در ادامه توضیح خواهم داد. برای رسیدن به این جلوه باید باکس مورد نظر ما position: absolute; داشته باشد. سپس از top: 50%; و left: 50%; استفاده می‌کنیم. از آنجاییکه مقدار %۵۰ از گوشه‌ی بالا و سمت چپ باکس حساب می‌شود در نتیجه باکس در مرکز قرار نمی‌گیرد. برای حل مشکل از margin منفی معادل نصف طول و عرض باکس استفاده می‌کنیم. به این شکل:

.box {
width: 300px;
height: 200px;
position: absolute;
top: 50%;
left: 50%;
margin-top: -100px;
margin-left: -150px;
}

از آنجاییکه هیچ پوزیشنی برای والد در نظر گرفته نشده. باکس نسبت به دیواره‌های مرورگر تنظیم شده و در مرکز قرار می‌گیرد ولی در صورت نیاز می‌توانید باکس را در داخل یک container قرار دهید که postion: relative; دارد. در اینجا باکس داخلی به نسبت دیواره‌های عنصر والدش منظم می‌شود. نمونه عملی بدین شکل خواهد بود:
مزایای این شیوه

آسان بودن و پیاده‌سازی بی دردسر
پشتیبانی خیلی خوب در مرورگرهای بسیار قدیمی مثل IE6,7

معایب این شیوه

احتیاج به تعریف عرض و ارتفاع ثابت برای باکس در نتیجه عدم پشتیبانی از طراحی Responsive
عدم پشتیبانی از max-width, max-height, min-width و min-height

۲. استفاده از CSS Transform برای Center کردن Box

این شیوه تقریبا جدید‌تر است و از تکنیک به روزتری استفاده می‌کند. اولین بار در سایت codrops در یکی از آموزش‌ها از این افکت استفاده شد. این شیوه نسبت به مدل قبل مزایایی هم دارد ولی در عین حال معایبی هم دارد که به آنها می‌پردازیم. در این شیوه باز هم باکس ما باید position: absolute; باشد و از top و right با مقدار %۵۰ استفاده می‌کنیم منتها به جای استفاده از margin با مقادیر منفی از transform و فانکشن translate با مقدار منفی برای محور افقی و عمودی استفاده می‌کنیم. کدی که در اینجا استفاده می‌‌شود مشابه این کد است:

.box {
width: 60%;
top: 50%;
left: 50%;
position: absolute;
overflow: auto;
transform: translate(-50%, -50%);
}

این شیوه شباهت‌هایی با شیوه قبل دارد ولی در اینجا ما از transform برای جابجایی باکس استفاده کردیم. در حالت عادی transform-origin در مرکز باکس است به همین خاطر زمانی که از مقدار %۵۰ برای translate استفاده می‌کنیم٬ مرکز باکس برای محاسبه این مقدار مورد استفاده قرار می‌گیرد و باکس کاملا در مرکز نمایش داده می‌شود. این شیوه مزایای دیگری هم دارد. یکی از مزایای خوبش پشتیبانی از طراحی ریسپانسیو است. نمونه کد را ببینید:

در این شیوه می‌توانید به باکس خود min-width یا max-width و یا min-height و max-height هم بدهید که باکس از نظر عرض و ارتفاع از حد خاصی بزرگتر و یا کوچکتر نشود. همینطور اگر از خصوصیت resize: both بر روی باکس مورد نظر استفاده کنید٬‌ باکس را می ‌توانید با کمک handler گوشه باکس کشیده و بزرگ و کوچک کنید و در همه حال باکس در دو جهت عمودی و افقی در مرکز می‌ماند.
مزایای این شیوه

پشتیبانی از طراحی واکنش‌گرا (Responsive)
پشتیبانی از ارتفاع و عرض متغییر برای باکس (تعریف مقدار درصدی برای عرض و ارتفاع باکس امکان‌پذیر است)
ساده بودن در پیاده سازی
پشتیبانی از overflow: auto برای جلوگیری از بیرون زدن متن از باکس در زمانی که محتوا بیشتر از عرض و ارتفاع باکس است.
عدم نیاز به تعریف height برای باکس مورد نظر

معایب این شیوه

عدم پشتیبانی از مرورگرهای قدیمی مانند IE8
استفاده از transform برای دادن افکت‌های دیگر به این باکس ممکن است باعث تداخل و به هم ریختن آن شود.

۳. استفاده از position: absolute و چهار خصوصیت top, bottom, right و left

این شیوه امکانات زیادی در اختیار شما قرار می‌دهد ولی از طرفی یک مشکل خاص دارد که شاید نتوان در همه جا از آن استفاده کرد و آن هم این است که حتما باید برای باکس مورد نظرمان height تعریف کنیم. در این شیوه باز هم از همان position: absolute; استفاده می‌کنیم ولی در کنار آن از top, left, bottom و right با مقدار صفر استفاده می‌کنیم. هر زمان که شما باکسی را با دستور position: absolute; موقعیت‌دهی کنید و از مقادیر top, bottom, right و left با مقدار صفر استفاده کنید٬‌ اگر باکس مورد نظر شما هیچ عرض و ارتفاع تعریف‌شده ای نداشته باشد٬‌ باکس مورد نظر کش آمده و از چهار طرف به دیواره‌های والد خود می‌چسبد. حال برای اینکه باکس کش نیاید می‌توانیم طول و عرض دلخواه خود را به آن بدهیم تا باکس‌مان در مرکز صفحه نمایش داده شود. نتیجه چیزی شبیه به کد زیر است:

.box {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
width: 60%;
height: 50%;
margin: auto;
overflow: auto;
}

در اینجا چون باکس ما position: absolute; است در نتیجه از جریان کلی صفحه خارج شده و به شکل مستقل نمایش داده می‌شود از این رو اگر از دستور margin: auto; استفاده کنیم باکس ما از هر چهار سمت فاصله خود را با دیواره‌های والد حفظ کرده در نتیجه در مرکز قرار می‌گیرد. از خوبی‌های این شیوه این است که از طراحی ریسپانسیو پشتیبانی می‌کند و با کم شدن عرض صفحه٬ عرض باکس هم کاهش می‌یابد (به شرطی که به شکل درصدی تعیین شده باشد) و همینطور می‌توانیم از -min و -max را برای height و width استفاده کنیم تا باکس ما از عرض و ارتفاعی خاص٬ بزرگتر و یا کوچکتر نشود.
مزایای این شیوه

پشتیبانی از مرورگرهای قدیمی مانند IE8
آسان بودن و پیاده سازی سریع
پشتیبانی از طراحی Responsive
عدم بروز مشکل در زمانی که مستقیما به خود باکس padding بدهید
از همین تکنیک برای تصاویر هم می‌توان استفاده کرد

معایب این شیوه

حتما باید باکس مورد نظر ما height مشخص داشته باشد
این شیوه بر روی ویندوز فون کار نمی‌کند.

۴. استفاده از دستور table-cell

این شیوه از دستورات قدیمی CSS استفاده می‌کند و یکی از بهترین پشتیبانی‌ها را دارد ولی در کنار پشتیبانی خوب ایرادی هم دارد و آن هم این است که برای استفاده از این شیوه باید تگ HTML ای را به عنوان wrapper به باکس خود اضافه کنید. البته اغلب این اتفاق به شکل کلی در طراحی می‌افتد. کدی که برای این تکنیک می‌شود بدین شکل است:

.container {
display: table;
}

.box-wrapper {
display: table-cell;
vertical-align: middle;
}

.box {
width: 50%;
margin: 0 auto;
}

اولین بار با دستور display: table; و display: table-cell; در کتاب everything you know about CSS is wrong آشنا شدم. این کتاب را سال‌ها قبل انتشارات سایت‌پوینت منتشر کرد و نویسندگان سعی داشتند که قابلیت‌های این دو دستور و متعلقات آن را توضیح بدهند و طراحان را به این سمت سوق بدهد که به جای استفاده از float از این دستور برای طراحی ساختار صفحه استفاده کنند که البته موفق نبودند و این کتاب هم با استقبال زیادی مواجه نشد. این تکنیک از این جهت جالب توجه است که پشتیبانی خوبی از مرورگرهای قدیمی دارد و از طراحی ریسپانسیو هم پشتیبانی می‌کند. نمونه عملی کد را اینجا می‌توانید ببینید:
مزایای این شیوه

پشتیبانی از طراحی Responsive
پشتیبانی خیلی خوب از مرورگرهای قدیمی
عدم نیاز به تعریف عرض و یا ارتفاع ثابت برای باکس

معایب این شیوه

نیاز به اضافه کردن کد HTML به صفحه

۵. استفاده از display: inline-block

این شیوه در سایت CSS-Tricks توضیح داده شده است. این متد شباهت‌های زیادی به متد قبلی دارد ولی مانند متد قبل احتیاجی به اضافه کردن کد HTML اضافه به محتوای صفحه ندارد. در این تکنیک از display: inline-block; استفاده می‌شود. زمانی که از دستور فوق استفاده کنید و width: 100%; تنظیم کنید٬ باکس شما مانند عناصر block دیگر کل عرض صفحه را اشغال نخواهد کرد و تنها به اندازه عرض محتوا کش خواهد آمد. برای حل این مشکل به جای استفاده از table از inline-block استفاده می‌کنیم و با استفاده از یک pseudo element «بخوانیم سودو المنت» یک عنصر به داخل container اضافه می‌کنیم و ارتفاعش را %۱۰۰ تنظیم می‌کنیم که ارتفاع والد را کاملا اشغال کند سپس هم به این pesudo element و هم به باکس داخل container دستور display: inline-block; و vertical-align: middle; را می‌دهیم. کد ما چیزی شبیه به این خواهد بود:

.container {
text-align: center;
}

.container:before {
content: “”;
height: 100%;
display: inline-block;
vertical-align: middle;
}

.box {
width: 50%;
display: inline-block;
vertical-align: middle;
text-align: right;
}

البته در مقاله‌ی سایت CSS-Tricks پیشنهاد شده که margin-right: -0.25em; را هم به سودو المنت اضافه کنیم تا باکس کاملا در مرکز قرار بگیرد ولی در کدی که من به عنوان sample آماده کرده‌ام به نظر می‌رسد که باکس در مرورگر کروم بدون نیاز به دستور بالا کاملا در مرکز قرار گرفته است.
مزایای این شیوه

پشتیبانی از عرض و ارتفاع متغیر در نتیجه پشتیبانی از طراحی Responsive
پشتیبانی تقریبا خوب از مرورگرهای قدیمی (IE8 و بالاتر)

معایب این شیوه

احتیاج به وجود یک container برای استفاده از این تکنیک

۶. استفاده از flexbox

این متد مدرن‌ترین متد محسوب می‌شود و پشتیبانی از آن در مرورگرهای قدیمی بسیار ضعیف است. البته flexbox چیزی فرای در مرکز قرار دادن یک باکس است و با استفاده از flexbox می‌توان چینش‌های پیچیده‌ای ایجاد کرد که قبلا ممکن نبود و flexbox و CSS Regions آینده طراحی layout با CSS محسوب می‌شوند. برای آشنایی بیشتر با flexbox پیشنهاد می‌کنم این مطلب از سایت smashing magazine را بخوانید یا فیلم آموزشی CSS Flexbox First Look از شرکت لیندا را ببینید. کدی که برای استفاده از flexbox استفاده می‌کنیم بدین شکل است:

.container {
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-webkit-box-align: center;
-moz-box-align: center;
-ms-flex-align: center;
-webkit-align-items: center;
align-items: center;
-webkit-box-pack: center;
-moz-box-pack: center;
-ms-flex-pack: center;
-webkit-justify-content: center;
justify-content: center;
}

همانطور که می‌بینید تعداد زیادی دستور به همراه vendor prefix در این تکه کد وجود دارد. flexbox از جمله استانداردهایی بود که در طول زمان بارها تغییر کرد و هر بار تعدادی از مرورگرها یکی از این ساختارها را پشتیبانی کردند. در مجموع برای flexbox یک فرمت قدیمی وجود دارد که نسخه‌های قدیمی فایرفاکس و سافاری و نسخه های قدیمی iOS از آن پشتیبانی می‌کنند. سپس نسخه ای دیگر از آماده شد که به نسخه tweener معروف است و این نسخه توسط IE10 پشتیبانی شده است و بعد از آن نسخه نهایی که به شکل استاندارد درآمده ارائه شد که تمامی مرورگرهای مدرن از این الگوی سوم استفاده می‌کنند. در مجموع برای استفاده از flexbox باید تمامی این دستورات را در کنار هم داشته باشید تا مطمئن شوید که نسخه‌های قدیمی مرورگرها نیز می‌توانند سایت شما را درست نمایش دهند.
مزایای این شیوه

انعطاف پذیری بالا و اجازه داده به طراح برای ایجاد جلوه های پیچیده تر
عدم نیاز به تعیین عرض و ارتفاع برای باکس و در نتیجه پشتیبانی از طراحی ریسپانسیو

معایب این شیوه

این تکنیک فقط در مرورگرهای جدید پشیبانی می‌شود (عدم پشتیبانی در IE9 و پایین تر)
الگوی قدیمی و tweener از نظر سرعت می‌توانند گاهی کند باشد.
دستورات CSS زیاد و گیج کننده برای پشتیبانی از تمامی مرورگرهای موجود

کدام شیوه را انتخاب کنم؟

همانطور که می‌بینید هیچ شیوه کاملی وجود ندارد. باید بر اساس نیاز خود و شرایط پروژه بسنجید که کدام بیشتر برای شما مناسب است. اگر بخواهید مرورگرهای قدیمی را پشتیبانی کنید باید به سمت استفاده از ترفند های ۱٬۳٬۴٬۵ بروید و اگر دنبال شیوه‌های مدرن تر هستید و یا انعطاف بیشتری نیاز دارید شیوه‌های ۲٬۶ می‌توانند گزینه‌های خوبی باشند. اگر عرض و ارتفاع ثابت برایتان اهمیتی نداشته باشد می‌توانید از ترفند‌های ۱و ۳ استفاده کنید و در صورتی که ریسپانسیو بودن برایتان اهمیت دارد متدهای ۲٬۴٬۵٬۶ برایتان مناسب تر است.