مدل جعبه

پادکست CSS - 001: مدل جعبه‌ای

فرض کنید این تکه HTML را دارید:

<p>I am a paragraph of text that has a few words in it.</p>

سپس این CSS را برای آن می‌نویسید:

p {
  width: 100px;
  height: 50px;
  padding: 20px;
  border: 1px solid;
}

محتوا به جای ۱۰۰ پیکسلی که شما تعیین کرده‌اید، ۱۴۲ پیکسل عرض خواهد داشت و از عنصر شما خارج می‌شود. چرا اینطور است؟

مدل جعبه‌ای (box model) یکی از پایه‌های اصلی CSS است. درک نحوه‌ی عملکرد مدل جعبه‌ای، چگونگی تأثیرپذیری آن از سایر جنبه‌های CSS و مهم‌تر از آن، نحوه‌ی کنترل آن، می‌تواند به شما در نوشتن CSS قابل پیش‌بینی‌تر کمک کند.

درک مدل جعبه‌ای CSS به شما کمک می‌کند تا بفهمید چرا محتوای شما درون یک عنصر قرار نمی‌گیرد.

مهم است به یاد داشته باشید که هر چیزی که توسط CSS نمایش داده می‌شود، یک کادر است، حتی اگر فقط متن باشد، یا دارای border-radius باشد که آن را شبیه دایره می‌کند.

محتوا و اندازه

جعبه‌ها بسته به مقدار display ، ابعاد تعیین‌شده و محتوایی که در خود دارند، رفتار متفاوتی دارند. این محتوا می‌تواند متن ساده یا جعبه‌های بیشتری باشد که توسط عناصر فرزند ایجاد می‌شوند. در هر صورت، محتوا به طور پیش‌فرض بر اندازه جعبه تأثیر می‌گذارد.

شما می‌توانید این را با استفاده از اندازه‌گذاری بیرونی کنترل کنید، یا می‌توانید از اندازه‌گذاری درونی استفاده کنید تا مرورگر بر اساس اندازه محتوا برای شما تصمیم‌گیری کند.

در اینجا یک نسخه آزمایشی اساسی وجود دارد که تفاوت را توضیح می‌دهد:

وقتی جعبه اندازه بیرونی دارد، محدودیتی در میزان محتوایی که می‌توانید اضافه کنید وجود دارد، قبل از اینکه از جعبه سرریز شود. این باعث می‌شود کلمه "عالی" سرریز شود.

این دمو شامل کلمات "CSS is awesome" در یک کادر با ابعاد ثابت و یک حاشیه ضخیم است. از آنجا که این کادر عرض مشخصی دارد، اندازه بیرونی آن تعیین شده است. این بدان معناست که اندازه محتوای فرزند خود را کنترل می‌کند. با این حال، کلمه "awesome" برای کادر خیلی بزرگ است، بنابراین از کادر حاشیه کادر والد سرریز می‌شود (بعداً در این مورد بیشتر صحبت خواهیم کرد). یک راه برای جلوگیری از این سرریز، این است که اجازه دهیم کادر به صورت ذاتی اندازه داشته باشد، یا با تنظیم نکردن عرض، یا در این مورد، تنظیم width روی min-content . کلمه کلیدی min-content به کادر می‌گوید که فقط به اندازه حداقل عرض ذاتی محتوای آن (کلمه "awesome") عرض داشته باشد. این کار باعث می‌شود کادر کاملاً در اطراف متن قرار گیرد.

در اینجا یک مثال پیچیده‌تر آورده شده است که تأثیر اندازه‌های مختلف بر محتوای واقعی را نشان می‌دهد:

اندازه‌گذاری بیرونی به شما امکان کنترل اندازه یک عنصر را می‌دهد. اندازه‌گذاری درونی از سرریز شدن متن جلوگیری می‌کند.

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

به طور پیش‌فرض، این عنصر دارای width و height تعیین‌شده‌ی 400px برای هر کدام است. این ابعاد، محدودیت‌های دقیقی را برای هر چیزی که درون عنصر قرار دارد، تعیین می‌کنند، مگر اینکه محتوا برای کادر خیلی بزرگ باشد. می‌توانید این را در عمل با تغییر عنوان زیر تصویر گل به چیزی که از ارتفاع کادر بیشتر باشد، مشاهده کنید.

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

تغییر به اندازه‌بندی ذاتی به مرورگر اجازه می‌دهد تا بر اساس اندازه محتوای کادر، برای شما تصمیم‌گیری کند. این امر احتمال سرریز شدن را بسیار کمتر می‌کند زیرا کادر با محتوایش تغییر اندازه می‌دهد.

مهم است به یاد داشته باشید که اندازه‌گذاری ذاتی، رفتار پیش‌فرض مرورگر است و معمولاً انعطاف‌پذیری بسیار بیشتری نسبت به اندازه‌گذاری بیرونی ارائه می‌دهد.

نواحی مدل جعبه‌ای

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

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

کادر محتوا ناحیه‌ای است که محتوا در آن قرار می‌گیرد. محتوا می‌تواند اندازه والد خود را کنترل کند، بنابراین این معمولاً متغیرترین اندازه را در بین تمام قسمت‌ها دارد.

کادر padding کادر محتوا را احاطه کرده و فضایی است که توسط ویژگی padding ایجاد می‌شود. از آنجا که padding درون کادر قرار دارد، پس‌زمینه کادر در فضایی که ایجاد می‌کند قابل مشاهده است. اگر قواعد سرریز روی کادر تنظیم شده باشد، مانند overflow: auto یا overflow: scroll ، نوارهای پیمایش نیز این فضا را اشغال می‌کنند.

نوارهای پیمایش در کادر padding قرار دارند.

کادر حاشیه ، کادر فاصله‌گذاری (padding) را احاطه کرده است و فضای آن توسط مقدار border تعریف می‌شود که یک قاب بصری برای عنصر ایجاد می‌کند. لبه حاشیه عنصر، حد چیزی است که می‌توانید ببینید.

ناحیه آخر، کادر حاشیه ، فضای اطراف کادر شماست که توسط قانون margin کادر تعریف می‌شود. ویژگی‌هایی مانند outline و box-shadow نیز این فضا را اشغال می‌کنند زیرا روی عنصر نقاشی می‌شوند و بر اندازه کادر تأثیری ندارند. تغییر outline-width کادر به اندازه 200px در یک کادر، چیزی را در داخل لبه حاشیه تغییر نمی‌دهد.

یک خط بیرونی پهن، اندازه بقیه عنصر را تحت تأثیر قرار نمی‌دهد.

یک تشبیه مفید

درک مدل جعبه‌ای پیچیده است، بنابراین در اینجا یک تشبیه برای آنچه تاکنون آموخته‌اید، آورده شده است.

تصویرسازی مدل جعبه با قاب عکس.

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

  • جعبه محتوا، اثر هنری است.
  • جعبه‌ی پدینگ، تخته‌ی نصب سفید رنگی است که بین قاب و اثر هنری قرار می‌گیرد.
  • کادر حاشیه، قابی است که یک حاشیه‌ی واقعی برای اثر هنری فراهم می‌کند.
  • کادر حاشیه، فضای بین فریم‌ها است.
  • سایه همان فضای کادر حاشیه را اشغال می‌کند.

اشکال‌زدایی مدل جعبه‌ای

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

برای امتحان کردن این در کروم:

  1. ابزار توسعه (DevTools) را باز کنید .
  2. یک عنصر را انتخاب کنید .
  3. اشکال‌زدای مدل جعبه را نمایش دهید.
اشکال‌زدای مدل جعبه‌ای برای نسخه نمایشی outline.

مدل جعبه‌ای را کنترل کنید

برای درک نحوه کنترل مدل جعبه‌ای، ابتدا باید بفهمید که در مرورگر شما چه اتفاقی می‌افتد.

هر مرورگری یک شیوه‌نامه‌ی عامل کاربر (user agent style sheet) را به اسناد HTML اعمال می‌کند. شیوه‌نامه نحوه‌ی ظاهر و رفتار عناصر را تعریف می‌کند، البته اگر عناصر CSS تعریف‌شده‌ای نداشته باشند. CSS موجود در شیوه‌نامه‌های عامل کاربر (user agent style sheets) بسته به مرورگر متفاوت است، اما هر مرورگری پیش‌فرض‌هایی دارد که خواندن محتوا را آسان‌تر می‌کند.

شیوه‌نامه‌ی عامل کاربر مقدار پیش‌فرض را برای عناصری که قابلیت display دارند، تعیین می‌کند. برای مثال، مقدار پیش‌فرض display یک عنصر <div> block است، یک <li> مقدار پیش‌فرض display list-item دارد و یک <span> مقدار پیش‌فرض display inline دارد.

یک عنصر inline دارای حاشیه بلوکی (block margin) است، اما سایر عناصر آن را رعایت نمی‌کنند. با inline-block ، سایر عناصر حاشیه بلوکی را رعایت می‌کنند، اما عنصر اول بیشتر رفتارهای مشابه عنصر inline را حفظ می‌کند. یک آیتم block به طور پیش‌فرض فضای درون‌خطی موجود را پر می‌کند، در حالی که عناصر inline و inline-block فقط به اندازه محتوای خود بزرگ هستند.

برگه سبک عامل کاربر همچنین مقادیر پیش‌فرضی را برای box-sizing تعیین می‌کند، که به یک box می‌گوید چگونه اندازه‌اش را محاسبه کند. به طور پیش‌فرض، همه عناصر روی box-sizing: content-box; تنظیم شده‌اند. این بدان معناست که وقتی ابعادی مانند width و height را تنظیم می‌کنید، آن ابعاد به content box اعمال می‌شوند. اگر سپس padding و border تنظیم کنید، این مقادیر به اندازه content box اضافه می‌شوند.

درک خود را بررسی کنید

دانش خود را در مورد ویژگی‌های تأثیرگذار بر اندازه مدل جعبه‌ای بیازمایید.

.my-box {
  width: 200px;
  border: 10px solid;
  padding: 20px;
}

فکر می‌کنی .my-box چقدر پهنا خواهد داشت؟

۲۰۰ پیکسل
از آنجا که مقدار پیش‌فرض برای box-sizing برابر با content-box است، padding و borderها به عرض اضافه می‌شوند. اگر box دارای box-sizing: border-box باشد، 200px صحیح خواهد بود.
۲۶۰ پیکسل
اندازه پیش‌فرض کادر، content-box است، به این معنی که padding و borderها به کل کادر اضافه می‌شوند.

عرض واقعی این کادر ۲۶۰ پیکسل است. از آنجا که CSS از box-sizing: content-box استفاده می‌کند، عرض اعمال شده برابر با عرض محتوا است و padding و border در دو طرف به آن اضافه می‌شوند. ۲۰۰ پیکسل برای محتوا + ۴۰ پیکسل padding + ۲۰ پیکسل border، عرض قابل مشاهده کل را ۲۶۰ پیکسل می‌کند.

شما می‌توانید این را با مشخص کردن اندازه border-box تغییر دهید:

.my-box {
  box-sizing: border-box;
    width: 200px;
    border: 10px solid;
    padding: 20px;
}

این مدل جعبه جایگزین به CSS می‌گوید که width به کادر حاشیه به جای کادر محتوا اعمال کند. این بدان معناست که border و padding ما به داخل فشار داده می‌شوند، بنابراین وقتی .my-box را روی عرض 200px تنظیم می‌کنید، در واقع با عرض 200px رندر می‌شود.

نحوه‌ی کار این قابلیت را در دموی تعاملی زیر بررسی کنید. وقتی مقدار box-sizing را تغییر می‌دهید، ناحیه‌ی آبی نشان می‌دهد که کدام CSS درون کادر اعمال می‌شود.

اثرات اندازه کادر محتوا و کادر حاشیه را با هم مقایسه کنید.
*,
*::before,
*::after {
  box-sizing: border-box;
}

این قانون CSS تمام عناصر موجود در سند و تمام شبه عناصر ::before و ::after را انتخاب می‌کند و box-sizing: border-box را اعمال می‌کند. این بدان معناست که اکنون هر عنصر از این مدل جعبه‌ای جایگزین استفاده می‌کند.

از آنجا که مدل جعبه‌ای جایگزین می‌تواند قابل پیش‌بینی‌تر باشد، توسعه‌دهندگان اغلب این قانون را به بازنشانی‌ها و نرمال‌سازها، مانند A (more) Modern CSS Reset، اضافه می‌کنند.

منابع

شیوه‌نامه‌های عامل کاربر