بستن

آموزش کامل باکس مدل CSS (Box Model)

باکس مدل CSS شامل چهار لایه Content، Padding، Border و Margin

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

آنچه در این مقاله می‌خوانید:

هر عنصر HTML، چه بخوای چه نخوای، توسط مرورگر مثل یه جعبه (Box) مستطیلی در نظر گرفته می‌شه. فهمیدن این جعبه و بخش‌هاش، کلید حل ۹۰٪ مشکلات چیدمان (Layout) در CSSه.

🎯 اهداف یادگیری این جلسه

  • چهار لایه‌ی Box Model (Content، Padding، Border، Margin) رو کامل بشناسی
  • بفهمی چرا گاهی عرض واقعی یه عنصر با چیزی که نوشتی فرق داره
  • با box-sizing این مشکل رو برای همیشه حل کنی
  • تمام سینتکس‌های نوشتن Margin، Padding و Border رو یاد بگیری
  • با Logical Properties (مثل margin-inline-start) برای پروژه‌های فارسی/RTL آشنا بشی
  • فرق Margin Collapsing رو با مثال درک کنی

📦 چهار لایه Box Model

هر عنصر از بیرون به داخل این‌طوری ساخته می‌شه:

  • Margin: فاصله‌ی بیرون از عنصر، بین اون و عناصر همسایه‌اش
  • Border: خط دور عنصر
  • Padding: فاصله‌ی داخلی، بین محتوا و border
  • Content: خود محتوای عنصر (متن، تصویر و غیره)

یه تشبیه ساده: یه عکس قاب‌شده رو تصور کن. خود عکس، Content‌ه. حاشیه‌ی سفید دور عکس قبل از قاب، Padding‌ه. خود قاب چوبی، Border‌ه. و فاصله‌ای که بین قاب و دیوار یا قاب‌های دیگه می‌ذاری، Margin‌ه.

✍️ مثال عملی کامل

.box {
  width: 200px;
  padding: 20px;
  border: 5px solid royalblue;
  margin: 30px;
}
<div class="box">این یه باکس ساده‌ست.</div>

حالا سوال مهم: این باکس چقدر فضای واقعی رو اشغال می‌کنه؟ width که نوشتیم فقط عرض Content رو مشخص می‌کنه، نه کل باکس! برای محاسبه‌ی عرض واقعی (تا لبه‌ی بیرونی Border)، باید همه‌چیز رو جمع بزنی:

200px (content) + 20px + 20px (padding چپ و راست) + 5px + 5px (border چپ و راست) = 250px

یعنی با اینکه نوشتی width: 200px، باکس واقعی روی صفحه ۲۵۰ پیکسل عرض داره (بدون احتساب Margin، چون Margin فضای بیرون باکسه، نه بخشی از خود باکس).

⚙️ box-sizing — راه‌حل این سردرگمی

این رفتار پیش‌فرض (که بهش content-box می‌گن) خیلی وقت‌ها باعث سردرگمی و باگ‌های چیدمان می‌شه. خوشبختانه یه راه‌حل ساده هست:

.box {
  box-sizing: border-box;
  width: 200px;
  padding: 20px;
  border: 5px solid royalblue;
}

با box-sizing: border-box، مرورگر Padding و Border رو داخل همون ۲۰۰ پیکسلی که گفتی حساب می‌کنه، نه اضافه بر اون.

توصیه‌ی استاندارد صنعت: تقریباً همه پروژه‌های حرفه‌ای امروز این خط رو در همون ابتدای فایل CSS، رو همه‌ی عناصر اعمال می‌کنن:

* {
  box-sizing: border-box;
}

📊 جدول مقایسه content-box و border-box

ویژگیcontent-box (پیش‌فرض)border-box
معنی widthفقط عرض Contentعرض کل باکس (Content+Padding+Border)
وقتی Padding اضافه می‌کنیعرض کل باکس بزرگ‌تر می‌شهعرض کل باکس ثابت می‌مونه
محبوبیت در پروژه‌های حرفه‌ایکم (رفتار پیش‌فرض قدیمی مرورگر)خیلی زیاد (استاندارد امروز)

🎯 outline با border قاطی نشه

خیلی از مبتدی‌ها فکر می‌کنن outline بخشی از Box Model‌ه، ولی این‌طور نیست:

.box {
  border: 2px solid black;
  outline: 2px solid red;
}

outline دور border کشیده می‌شه، ولی هیچ فضایی اشغال نمی‌کنه و اصلاً وارد محاسبات Box Model نمی‌شه. برای همین خیلی جاها (مثل استایل :focus) از outline استفاده می‌شه؛ چون بدون اینکه اندازه‌ی عنصر رو به‌هم بریزه، یه نشونه بصری واضح ایجاد می‌کنه.

📊 نکته‌ی پیشرفته: درصد در Padding و Margin چطور محاسبه می‌شه؟

این یکی از عجیب‌ترین رفتارهای CSS‌ه: وقتی برای padding یا margin از درصد (٪) استفاده می‌کنی — حتی برای بالا و پایین — درصد همیشه نسبت به عرض عنصر والد محاسبه می‌شه، نه ارتفاعش!

.parent {
  width: 400px;
  height: 200px;
}

.child {
  padding-top: 10%; /* یعنی 40px (10% از عرض 400px)، نه 20px */
}

این رفتار از اول طراحی CSS همین بوده و می‌تونه باعث باگ‌های عجیب بشه، مخصوصاً وقتی می‌خوای یه باکس رو با نسبت تصویر خاص با درصد بسازی.

🔍 چطور Box Model یه عنصر رو تو مرورگر ببینیم؟

  1. رو هر عنصری از صفحه راست‌کلیک کن و Inspect رو بزن
  2. تو پنل باز‌شده، برو تب Computed یا Layout
  3. پایین همون پنل، یه نمودار جعبه‌ای با اعداد دقیق Margin، Border، Padding و Content می‌بینی

این ابزار برای دیباگ کردن مشکلات چیدمان خیلی حیاتیه؛ همین الان رو یه عنصر از همین صفحه امتحانش کن.

📏 تمام روش‌های نوشتن Margin

1 تا 4 مقدار

.box {
  margin: 20px;                   /* هر چهار طرف */
  margin: 10px 20px;              /* عمودی افقی */
  margin: 10px 20px 30px;         /* بالا افقی پایین */
  margin: 10px 20px 30px 40px;    /* بالا راست پایین چپ (ساعت‌گرد) */
}

ترتیب چهار مقداری همیشه ساعت‌گرده و از بالا شروع می‌شه. ترفند یادآوری: TRBL (Top, Right, Bottom, Left).

مقادیر مجزا

.box {
  margin-top: 10px;
  margin-right: 20px;
  margin-bottom: 30px;
  margin-left: 40px;
}

Auto — برای وسط‌چین کردن

.container {
  width: 600px;
  margin: 0 auto;
}

وقتی چپ/راست رو auto می‌ذاری، مرورگر فضای باقی‌مونده رو مساوی تقسیم می‌کنه و عنصر وسط والدش قرار می‌گیره. ⚠️ فقط با width مشخص (نه auto) کار می‌کنه.

مقدار منفی

.box {
  margin-top: -20px;
}

باعث می‌شه عنصر به‌جای دور شدن از همسایه‌هاش، بهشون نزدیک‌تر یا حتی روشون سوار بشه؛ برای افکت‌های همپوشانی عمدی کاربرد داره.

واحدهای مختلف و calc()

.box {
  margin: 2rem;
  margin: 5%;
  margin: 3vw;
  margin-top: calc(2rem + 10px);
}

🆕 Logical Properties — جدیدترین روش

.box {
  margin-block: 20px;         /* معادل margin-top + margin-bottom */
  margin-inline: 15px;        /* معادل margin-left + margin-right (در LTR) */

  margin-block-start: 10px;
  margin-block-end: 20px;
  margin-inline-start: 15px;  /* در فارسی (RTL) = margin-right */
  margin-inline-end: 25px;    /* در فارسی (RTL) = margin-left */
}

این جدیدترین روش نوشتن margin‌ه که به‌جای جهت فیزیکی ثابت، بر اساس جهت نوشتار صفحه عمل می‌کنه. برای پروژه‌های فارسی خیلی مهمه: اگه از margin-inline-start استفاده کنی، مرورگر خودش بر اساس dir="rtl" یا dir="ltr" تصمیم می‌گیره کدوم طرف فیزیکی رو اعمال کنه، بدون نیاز به هیچ تغییری تو کد.

📊 جدول خلاصه Margin

سینتکسمثالکاربرد
تکیmargin: 20px;هر چهار طرف یکسان
چهارتاییmargin: 10px 20px 30px 40px;هر طرف جدا
Automargin: 0 auto;وسط‌چین افقی
منفیmargin-top: -20px;نزدیک‌سازی/همپوشانی
Logicalmargin-inline-start: 15px;سازگار با RTL/LTR

📐 تمام روش‌های نوشتن Padding

دقیقاً همون سینتکس‌های Margin، با یه فرق اساسی: Padding هیچ‌وقت مقدار منفی و auto قبول نمی‌کنه.

.box {
  padding: 20px;
  padding: 10px 20px;
  padding: 10px 20px 30px;
  padding: 10px 20px 30px 40px;

  padding-top: 10px;
  padding-right: 20px;
  padding-bottom: 30px;
  padding-left: 40px;

  padding: 1.5rem;
  padding: 4%;
  padding: calc(1rem + 5px);
}

🆕 Logical Properties برای Padding

.box {
  padding-block: 20px;
  padding-inline: 15px;

  padding-block-start: 10px;
  padding-block-end: 20px;
  padding-inline-start: 15px;  /* در فارسی (RTL) = padding-right */
  padding-inline-end: 25px;    /* در فارسی (RTL) = padding-left */
}

🖼️ تمام روش‌های نوشتن Border

Shorthand کامل

.box {
  border: 2px solid royalblue;
}

ترتیب همیشه: ضخامت، نوع خط، رنگ. نکته: style اجباریه؛ بدون تعیین یه style، حتی با width و color، border نمایش داده نمی‌شه.

تعیین هر طرف جداگانه

.box {
  border-top: 3px solid red;
  border-right: 1px dashed gray;
  border-bottom: 3px solid red;
  border-left: 1px dashed gray;
}

تفکیک هر ویژگی

.box {
  border-width: 2px;
  border-style: solid;
  border-color: royalblue;
}

انواع border-style

.solid  { border-style: solid; }
.dashed { border-style: dashed; }
.dotted { border-style: dotted; }
.double { border-style: double; }

border-radius

.box {
  border-radius: 8px;
  border-radius: 8px 16px;
  border-radius: 8px 16px 24px 32px;
  border-radius: 50%; /* دایره کامل رو عنصر مربعی */
}

🆕 Logical Properties برای Border

.box {
  border-block-start: 2px solid royalblue;  /* = border-top */
  border-inline-start: 2px solid royalblue; /* در فارسی (RTL) = border-right */
  border-inline-end: 2px solid royalblue;   /* در فارسی (RTL) = border-left */
}

📋 مقایسه نهایی: Margin، Padding و Border در یک نگاه

ویژگیMarginPaddingBorder
مقدار منفی✅ مجاز❌ غیرمجاز❌ غیرمجاز
مقدار auto✅ (وسط‌چین)❌ غیرمجاز❌ غیرمجاز
سینتکس 1-4 مقداری✅ (radius/width)
Logical Propertiesmargin-inline-startpadding-inline-startborder-inline-start
Margin Collapsing✅ فقط این دارهنداردندارد

🔀 Margin Collapsing — یه رفتار عجیب که باید بدونی

وقتی دو تا عنصر با Margin عمودی (بالا/پایین) کنار هم قرار می‌گیرن، مرورگر این دو Margin رو با هم جمع نمی‌زنه؛ به‌جاش فقط بزرگ‌ترینشون رو اعمال می‌کنه:

p {
  margin-bottom: 20px;
}

h2 {
  margin-top: 30px;
}
<p>پاراگراف اول</p>
<h2>عنوان بعدی</h2>

نتیجه: فاصله‌ی واقعی بین این دو عنصر ۳۰ پیکسل می‌شه، نه ۵۰ پیکسل. این رفتار فقط برای Margin عمودی صادقه و فقط زمانی اتفاق می‌افته که هیچ Padding یا Border بینشون نباشه.

📐 Display و تاثیرش رو Box Model

  • Block (مثل div, p): کل عرض والدش رو می‌گیره و Margin/Padding عمودی کامل اثر می‌ذاره
  • Inline (مثل span, a): فقط به اندازه‌ی محتواش عرض می‌گیره؛ Margin/Padding عمودی روش اثر بصری کامل نداره
  • Inline-block: مثل Inline کنار عناصر دیگه قرار می‌گیره، ولی مثل Block به Margin/Padding عمودی هم احترام می‌ذاره

این تفاوت رو تو جلسه بعد، وقتی به Display و Layout می‌رسیم، کامل‌تر باز می‌کنیم.

🧪 تمرین این جلسه

یه <div> با کلاس box بساز. توش:

  • width: 300px
  • padding: 15px
  • border: 3px solid black
  • margin: 20px

اول بدون box-sizing: border-box تستش کن و عرض واقعی رو با DevTools اندازه بگیر. بعد box-sizing: border-box رو اضافه کن و ببین عرض واقعی چطور تغییر می‌کنه. در پایان، یه نسخه از همون باکس رو با margin-inline-start به‌جای margin-left بازنویسی کن.

❓ سوالات متداول

چرا عرض واقعی عنصرم با چیزی که نوشتم فرق داره؟

چون به‌طور پیش‌فرض، width فقط عرض Content رو مشخص می‌کنه، و Padding و Border جدا بهش اضافه می‌شن. برای رفع این مشکل از box-sizing: border-box استفاده کن.

چرا outline من رو layout صفحه اثر نمی‌ذاره؟

چون outline اصلاً بخشی از Box Model نیست و هیچ فضایی اشغال نمی‌کنه؛ برخلاف border، outline فقط یه لایه‌ی بصریه، بدون اینکه اندازه‌ی عنصر رو تغییر بده.

آیا باید همیشه از border-box استفاده کنم؟

تقریباً همیشه بله؛ این تبدیل به یه استاندارد غیررسمی صنعت شده چون محاسبه‌ی اندازه‌ها رو خیلی قابل پیش‌بینی‌تر می‌کنه.

Margin Collapsing فقط بین عناصر مختلف اتفاق می‌افته؟

نه؛ ممکنه بین Margin پایین یه والد و Margin بالای اولین فرزندش هم اتفاق بیفته، اگه هیچ Border یا Padding بینشون نباشه.

🎯 جمع‌بندی و قدم بعدی

حالا می‌دونی هر عنصر HTML از چهار لایه Content، Padding، Border و Margin ساخته می‌شه، چطور با box-sizing: border-box محاسبه‌ی اندازه‌ها رو قابل پیش‌بینی کنی، و چطور با Logical Properties کدت رو برای RTL/LTR آماده کنی. جلسه بعد می‌ریم سراغ display و انواعش.

جلسه ششم: آموزش کامل Display در CSS ←

💬 نوبت توئه!

تا حالا با مشکل «عرض عجیب عنصر» مواجه شده بودی؟ Logical Properties رو می‌شناختی؟ همین پایین برامون بنویس 🚀

شهرام نجفی

شهرام نجفی

شهرام نجفی — بیش از ۱۵ سال طراحی و توسعهٔ وب به‌صورت فریلنس. قالب اختصاصی آوای وب را از صفر نوشته‌ام. مطالب این سایت را بر پایهٔ مستندات رسمی MDN و WHATWG می‌نویسم و قبل از انتشار در مرورگرهای واقعی تست می‌کنم. نمونه‌کارهایم در shahramnajafi.com است.

نظر شما در این مورد چیه؟