وسط قراردادن عناصر در سی اس اس

وسط قرار دادن عناصر در CSS

وسط قرار دادن عناصر در طراحی صفحات وب یکی از موارد رایج می باشد. در این مطلب قصد داریم تقریبا همه شرایطی که برای وسط قرار دادن عناصر بوجود می آیند را بررسی کنیم. این نوشته ترکیبی از مطلب عالی در سایت css-tricks.com و تجربه بنده است. چون موضوع از اهمیت زیادی برخوردار است از هرگونه سوال, نظر, پیشنهاد و انتقاد که به دوستان عزیز کمک کند به شدت استقبال می شود.

در ضمن اگر فرق عنصر بلاک و خطی را نمی دانید بهتر است اول این مطلب را بخوانید.

 

 

افقی

 

عنصر از نوع inline و یا از خانواده های inline است؟

عناصری مثل متن و لینک و یا دکمه ها بصورت پیشفرض از این نوع هستند. وقتی آنها درون یک عنصر از نوع بلاک (مثل <div> ) قرار می گیرند کافی است به عنصر پدر (یعنی همان عنصر بلاک) ویژگی و مقدار زیر را بدهیم. ( دعا کنید هیچ عنصری بی پدر نشه :) )

 


div.dad {
  text-align: center;
}

 

لطفا دموی زیر را بررسی کنید:

 

See the Pen Centering inline-* elements horizontally by Mojtaba Seyedi (@seyedi) on CodePen.


 

این روش برای عناصر inline, inline-block, inline-table, inline-flex هم بخوبی جواب می دهد.

 

عنصر از نوع block است؟

اگر عنصری که قرار است وسط قرار بگیرد از نوع بلاک است کافی است به ویژگی margin-left و margin-right آن مقدار auto بدهید. (البته عنصر باید عرض داشته باشد. که البته اگر عرض نداشته باشد از آنجایی که بلاک است کل عرض عنصر پدرش را می گیرد پس نیازی به وسط چین کردن آن نیست.)

نکته مهم اینکه عنصری که دارای ویژگی float هست را نمی توانید به این روش در وسط قرار دهید.

 


div.man-mikham-biam-vasat {
  width: 200px; /* عرض دلخواه */
  margin-left: auto;
  margin-right: auto;
}

 

لطفا دموی زیر را بررسی کنید:

 

See the Pen Centering block elements horizontally by Mojtaba Seyedi (@seyedi) on CodePen.


 

عنصر از نوع بلاک است ولی عرض مشخص ندارد؟

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

 


.element {
  display: table;
  margin-left: auto;
  margin-right: auto;
}

 

See the Pen Centering block elements horizontally by Mojtaba Seyedi (@seyedi) on CodePen.


 

بیشتر از یک عنصر بلاک وجود دارد؟

اگر چند عنصر دارید که از نوع بلاک هستند و در کنار هم قرار گرفتند و می خواهید همگی در کنار هم و در وسط صفحه قرار بگیرند. حداقل دو راه حل برای این کار وجود دارد. اول اینکه ویژگی display آنها را inline-block کنید و به عنصر پدرشان text-align: center; بدهید.
(یعنی همان روش اولی که بررسی شد)

 

See the Pen Centering blocks elements horizontally by Mojtaba Seyedi (@seyedi) on CodePen.


 

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


.dad-flex-center {
  display: flex;
  justify-content: center;
}

دموی زیر را در همین رابطه بررسی کنید:

 

See the Pen Centering blocks elements horizontally by Mojtaba Seyedi (@seyedi) on CodePen.


 

 

عمودی

 

عنصر از نوع inline و یا از خانواده های inline است؟

تک خط است؟

گاهی فقط استفاده از یک padding بالا و پایین جواب شما خواهد بود:
 


.element {
  padding-top: 30px;
  padding-bottom: 30px;
}

 

See the Pen Centering singleline inline elements vertically by Mojtaba Seyedi (@seyedi) on CodePen.


 

اما اگر این روش مناسب شما نیست یک ترفند هم وجود دارد و آن هم برابر قرار دادن line-height و ارتفاع عنصر است:

 


.center-text-trick {
  height: 100px;
  line-height: 100px;
  white-space: nowrap;
}

 

See the Pen Centering singleline inline elements vertically by Mojtaba Seyedi (@seyedi) on CodePen.


 

 

بیشتر از یک خط است؟

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

اما می توان از تکنیک جدول ها و ویژگی vertical-align هم در شرایط خودش استفاده کرد:

 

See the Pen Centering multi-line inline elements vertically by Mojtaba Seyedi (@seyedi) on CodePen.


 

راه بعدی استفاده از Flexbox است, البته باید توجه داشته باشید که عنصر پدر باید ارتفاع مشخص داشته باشد و کافی است به عنصر پدر این ویژگی ها تعلق بگیرند:

 


.flex-center-vertically {
  display: flex;
  justify-content: center;
  flex-direction: column;
  height: 400px;
}

 

دموی زیر این روش را به نمایش می گذارد:

 

See the Pen Centering multi-line inline elements vertically by Mojtaba Seyedi (@seyedi) on CodePen.


 

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

 

See the Pen Centering multi-line inline elements vertically by Mojtaba Seyedi (@seyedi) on CodePen.


 

 

عنصر از نوع بلاک است؟

ارتفاع عنصر مشخص است؟

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

 


.parent {
  position: relative;
}

.child {
  position: absolute;
  height: 100px;
  top: 0%;
  bottom: 0%;
  margin-top: auto;
  margin-bottom: auto;
}

 

توجه داشته باشید که در مثال بالا اگر برای عنصر فرزند از border-box استفاده نمی کنید باید مقادیر border و padding در راستای عمود هم به مقدار margin-top اضافه شود.

 

See the Pen Centering block-know-height elements vertically by Mojtaba Seyedi (@seyedi) on CodePen.


 

ارتفاع عنصر نامعلوم است؟

در این روش عنصر فرزند را بوسیله ویژگی top به اندازه نصف ارتفاع پدر پایین می آوریم, حال کافی است تا به اندازه نصف ارتفاع خود عنصر به بالا برگردیم که این کار را با استفاده از ویژگی transform انجام می دهیم:

 


.element {
  position: relative;
  top: 50%;
  transform: translateY(-50%);
}

 

گفته شده که در برخی از مرورگرها این تکنیک باعث می شود تا عنصر بطور صحیح ترسیم نشود, برای رفع این مشکل در آن معدود مرورگرها, کافی است تا ویژگی زیر را به عنصر پدر بدهیم:

 


.parent-element {
  transform-style: preserve-3d;
}

پیشوند گذاری برای مرورگرهای قدیمی فراموش نشود!

 

See the Pen Centering block-unknow-height elements vertically by Mojtaba Seyedi (@seyedi) on CodePen.


 

می توانید از فلکس باکس استفاده کنید؟

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

 


.parent {
  display: flex;
  flex-direction: column;
  justify-content: center;
}

 

See the Pen Centering block elements vertically by Mojtaba Seyedi (@seyedi) on CodePen.


 

 

افقی و عمودی

با ترکیب روش های بالا می توانید به نتیجه مطلوب برای وسط قرار دادن عنصر برسید. ما در اینجا سه حالت را بررسی می کنیم:

 

عرض و ارتفاع ثابت هستند؟

در این روش کافی است به عنصر مورد نظر و پدر آن ویژگی های زیر تعلق بگیرد:


.parent {
  position: relative;
}

.child {
  width: 300px;
  height: 100px;

  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;

  margin: auto;
}

 

عرض و ارتفاع مشخص نیست؟

در این روش کافی است به عنصر مورد نظر و پدر آن ویژگی های زیر را بدهید:


.parent {
  position: relative;
}

.child {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

/* و یا */

/*
.child {
  position: absolute;
  bottom: 50%;
  right: 50%;
  transform: translate(50%, 50%);
}
*/

 

می توانید از فلکس باکس استفاده کنید؟

کافی است تا از دو ویژگی وسط ساز فلکس باکس برای عنصر پدر (عنصر نگهدارنده) استفاده کنید:


.parent {
  display: flex;
  justify-content: center;
  align-items: center;
}

نتیجه اخلاقی

وسط آوردن عناصر در سی اس اس کاملا شدنی است :)

31 دیدگاه برای “وسط قرار دادن عناصر در CSS

  1. مجتبی جان،
    بنده یه مشکلی دارم، اونم این که نمیدونم که عرض و ارتفاع عنصرم رو می دونم یا نمی دونم که بخام از کدوم یک از روش های ذکر شده استفاده کنم؟
    مثلا واسه درصد ها، یا عناصری که با عناصر داخلی شون اندازه می گیرند، یا غیره.
    اگه لازم بود اشاره کن تا مثال های بیشتر و مشخص تری بیارم.

    مرسی.

  2. برای مثال:
    https://jsbin.com/rakume/ed

    لطفا مشخص کن این ul چه ارتفاعی داره؟ و چطور میاد وسط عمودی؟
    و این رو هم فرض کن که ممکنه حتی li ها هم عرض مشخص نداشته باشند و مثلا یه فایل عکس با ارتفاع نا معلوم درونشون قرار داده بشه.
    امیدوارم رسونده باشم مساله رو.

    مرسی.

  3. درخصوص clearfix، بله حق با شماست، چون موضوع موردنظرم نبود صرف راه افتادن قضیه نوشته بودم. چراکه حتی روش استفاده از شبه عناصر هم مشکلاتی، از همون جنس رو، داره. البته خودت خیلی بهتر میدونی.

    در مورد مساله، پس به عبارتی به عنوان یه block element که ارتفاع نامعلومی داره ، باهاش برخورد کردی. درسته؟
    یعنی ظاهرا ما با دونستن عرض li ها میدونیم عرض ul چیه(ظاهرا)، ولی طوری برخورد باید بکنیم که انگار نمیدونیم.

    بازهم مسائلی در همین مورد، از انواع دیگه، دارم اما همونطور که فکرش رو میکردم گویا درک کامل این مبحث، نیاز به تجربه بیشتر و دانش عمیق تری داره.
    لذا بنده فعلا هستم در خدمتتون :)

    مرسی مجتبی جان.

    1. از لحاظ عمودی که واضحه چه اتفاقی افتاده. ولی از لحاظ افقی:

      همیشه display:table باعث میشه تا عنصر حداقل عرض رو به خودش بگیره, یعنی همون عرض محتوا حالا اون محتوا میخواد هر چی باشه. توی این مثال, می خواد یه li باشه یا 10 تا. liها عرض داشته باشند یا نداشته باشند. فرقی نمیکنه. ul عرض محتواش رو می گیره.

      مشکل clearfix با after چیه؟ من نمی دونم.

  4. آقا من میخوام با فلکس باکس، یه دایو رو وسط(افقی و عمودی) بادی قرار بدم ولی نمیشه! چرا؟
    یه سوال دیگه: به body ارتفاع 100% میدم و انتظار دارم وقتی به دابو ـم ارتفاع 100% میدم به اندازه کل بادی کش بیاد ولی نمیشه چرا؟

  5. خیلی کارت درسته آقا مجتبی
    کیف کردم… هم با این مطلب هم با کل سایتت هم با خودت
    حتی جمله هایی هم که داخل مثالهات میاری قشنگ و خوندنیَن
    از این به بعد برای یاد گرفتن و حل هر مشکل css میام اینجا
    موفق باشی

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

  6. الان دوباره داشتم این پست رو میخوندم.مگهjustify-content از نظز افقی تراز بندی نمیکرد؟پس چرا برای وسط قرار دادن عمودی استفاده شده؟

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *