Пошук уроків, статей та іншого контенту
Порівняйте режими content-box і border-box та навчіться передбачати фактичний розмір елементів.
box-sizingВластивість box-sizing визначає, як браузер обчислює значення width і height елемента:
.element {
box-sizing: content-box;
}або:
.element {
box-sizing: border-box;
}Це особливо важливо, коли елемент має внутрішні відступи (padding) і рамку (border). Від режиму залежить, чи входять вони у вказані width і height.
content-boxcontent-box — значення за замовчуванням для більшості елементів.
У цьому режимі width і height задають розмір лише області вмісту. Внутрішні відступи та рамки додаються до цього розміру.
Нехай маємо такі стилі:
.card {
width: 300px;
padding: 20px;
border: 5px solid;
}Фактична ширина елемента обчислюється так:
width = ширина вмісту + лівий padding + правий padding
+ ліва border + права border
width = 300px + 20px + 20px + 5px + 5px
width = 350pxОтже, хоча в CSS вказано width: 300px, зовнішня ширина елемента становить 350px.
Якщо задано:
.card {
height: 150px;
padding: 10px;
border: 2px solid;
}то фактична висота буде:
height = 150px + 10px + 10px + 2px + 2px
height = 174pxСхематично модель content-box виглядає так:
зовнішній розмір
┌──────────────────────────────┐
│ border │
│ ┌────────────────────────┐ │
│ │ padding │ │
│ │ ┌──────────────────┐ │ │
│ │ │ content │ │ │
│ │ └──────────────────┘ │ │
│ └────────────────────────┘ │
└──────────────────────────────┘Значення width і height стосуються лише області content.
border-boxУ режимі border-box задані width і height включають:
область вмісту;
padding;
border.
.card {
box-sizing: border-box;
width: 300px;
padding: 20px;
border: 5px solid;
}Тепер зовнішня ширина елемента дорівнює саме 300px.
Внутрішня ширина вмісту обчислюється так:
ширина вмісту = загальна ширина - padding - border
ширина вмісту = 300px - 20px - 20px - 5px - 5px
ширина вмісту = 250pxУ такому режимі браузер зменшує область вмісту, щоб умістити в задану ширину також відступи й рамку.
заданий зовнішній розмір
┌──────────────────────────────┐
│ border │
│ ┌────────────────────────┐ │
│ │ padding │ │
│ │ ┌──────────────────┐ │ │
│ │ │ content │ │ │
│ │ └──────────────────┘ │ │
│ └────────────────────────┘ │
└──────────────────────────────┘Розглянемо два однакові елементи:
<div class="box content-box">content-box</div>
<div class="box border-box">border-box</div>.box {
width: 300px;
height: 120px;
padding: 20px;
border: 5px solid #2563eb;
margin-bottom: 16px;
background-color: #dbeafe;
}
.content-box {
box-sizing: content-box;
}
.border-box {
box-sizing: border-box;
}Фактичні розміри:
.content-box має ширину 350px і висоту 170px;
.border-box має ширину 300px і висоту 120px.
Для content-box:
ширина = 300 + 20 + 20 + 5 + 5 = 350px
висота = 120 + 20 + 20 + 5 + 5 = 170pxДля border-box:
зовнішня ширина = 300px
зовнішня висота = 120pxУявімо контейнер завширшки 600px із двома колонками по 50%. Кожна колонка також має внутрішні відступи.
<div class="layout">
<div class="column">Перша колонка</div>
<div class="column">Друга колонка</div>
</div>.layout {
width: 600px;
display: flex;
}
.column {
width: 50%;
padding: 24px;
border: 2px solid #475569;
}За замовчуванням використовується content-box. Ширина вмісту кожної колонки дорівнює 300px, але фактична ширина:
300px + 24px + 24px + 2px + 2px = 352pxДві колонки разом займають 704px, тому вони не помістяться в контейнер завширшки 600px.
Додамо border-box:
.column {
box-sizing: border-box;
width: 50%;
padding: 24px;
border: 2px solid #475569;
}Тепер кожна колонка має зовнішню ширину 300px, а дві колонки разом займають рівно 600px.
border-boxНа практиці часто задають border-box усім елементам:
*,
*::before,
*::after {
box-sizing: border-box;
}Це означає, що ширина та висота звичайних елементів, а також псевдоелементів ::before і ::after, включатимуть padding і border.
Такий підхід робить розрахунок розмірів передбачуванішим:
*,
*::before,
*::after {
box-sizing: border-box;
}
.panel {
width: 100%;
padding: 32px;
border: 1px solid #cbd5e1;
}Ширина .panel не стане більшою за ширину батьківського елемента через padding і border.
box-sizingbox-sizing не наслідується автоматично від батьківського елемента. Якщо потрібно використовувати значення батьківського елемента, можна явно вказати:
html {
box-sizing: border-box;
}
*,
*::before,
*::after {
box-sizing: inherit;
}У цьому варіанті:
для html встановлюється border-box;
усі елементи наслідують це значення;
псевдоелементи також отримують таку саму модель.
Для більшості макетів достатньо короткого варіанта:
*,
*::before,
*::after {
box-sizing: border-box;
}Перед розрахунком потрібно визначити:
який режим box-sizing використовується;
чи задано width або height;
розмір padding з кожного боку;
товщину border з кожного боку.
content-boxзовнішня ширина =
width + padding-left + padding-right + border-left + border-rightзовнішня висота =
height + padding-top + padding-bottom + border-top + border-bottomborder-boxзовнішня ширина = width
зовнішня висота = heightА розмір області вмісту:
ширина вмісту =
width - padding-left - padding-right - border-left - border-rightвисота вмісту =
height - padding-top - padding-bottom - border-top - border-bottomНаприклад:
.element {
box-sizing: border-box;
width: 240px;
padding: 16px 24px;
border: 3px solid;
}Для скороченого запису padding: 16px 24px:
вертикальний padding — 16px;
горизонтальний padding — 24px.
Ширина вмісту:
240px - 24px - 24px - 3px - 3px = 186pxЗовнішня ширина залишається 240px.
heightbox-sizing працює не лише з шириною, а й із висотою.
.box {
height: 200px;
padding: 30px;
border: 4px solid;
}За content-box фактична висота:
200px + 30px + 30px + 4px + 4px = 268pxЗа border-box зовнішня висота буде 200px, а доступна висота вмісту:
200px - 30px - 30px - 4px - 4px = 132pxЯкщо текст не поміщається у доступну область, він може вийти за межі елемента або спричинити прокручування — залежно від властивості overflow.
Фактичний зовнішній розмір елемента можна перевірити через getBoundingClientRect().
<div class="box content-box">Content box</div>
<div class="box border-box">Border box</div>
<script>
const boxes = document.querySelectorAll('.box');
boxes.forEach((box) => {
const rect = box.getBoundingClientRect();
console.log({
text: box.textContent,
width: rect.width,
height: rect.height,
});
});
</script>.box {
width: 200px;
height: 100px;
padding: 20px;
border: 5px solid #2563eb;
margin: 12px;
background-color: #dbeafe;
}
.content-box {
box-sizing: content-box;
}
.border-box {
box-sizing: border-box;
}У консолі браузера приблизно будуть такі значення:
Content box: width 250, height 150
Border box: width 200, height 100getBoundingClientRect() повертає фактичні геометричні розміри елемента, включно з його padding і border, але не включає зовнішні відступи margin.
width завжди є зовнішньою шириноюЗа замовчуванням це не так:
.box {
width: 100%;
padding: 20px;
}У режимі content-box елемент може стати ширшим за батьківський, тому що до 100% додасться горизонтальний padding.
Для передбачуваного результату:
.box {
box-sizing: border-box;
width: 100%;
padding: 20px;
}padding: 20px додає по 20px зліва і справа, а не 20px загалом.
Так само border: 2px solid додає по 2px з кожного боку.
margin із частиною розміру елементаmargin не входить у розмір, який контролює box-sizing.
Наприклад:
.box {
box-sizing: border-box;
width: 300px;
margin: 20px;
}Ширина самого елемента — 300px, але простір, який він займає разом із горизонтальними зовнішніми відступами, може становити 340px.
box-sizing лише одному елементуЯкщо частина компонентів використовує content-box, а частина — border-box, однакові правила ширини можуть давати різні результати.
Для узгодженої поведінки часто використовують:
*,
*::before,
*::after {
box-sizing: border-box;
}border-box збільшує область вмістуborder-box не збільшує внутрішній простір. Навпаки, за фіксованої ширини padding і border займають частину цієї ширини, тому доступна область вмісту стає меншою.
content-box є типовим режимом.
У content-box значення width і height задають лише область вмісту.
У border-box значення width і height включають вміст, padding і border.
margin не входить до жодного з цих розмірів.
Для content-box відступи й рамки додаються до заданої ширини або висоти.
Для border-box ширина та висота залишаються заданими, а область вмісту зменшується.
Глобальне встановлення border-box допомагає уникати несподіваного переповнення та спрощує розрахунок макета.