Ты задаёшь кнопке width: 200px, но она вдруг оказывается шириной 240px. Или добавляешь padding, и вёрстка разъезжается. Это классическая проблема блочной модели — и как только ты её поймёшь, такие ошибки исчезнут навсегда.
Каждый HTML-элемент — это прямоугольник из четырёх слоёв:
┌─────────────────────────────────┐
│ MARGIN │ Внешний отступ (прозрачный)
│ ┌───────────────────────────┐ │
│ │ BORDER │ │ Граница
│ │ ┌─────────────────────┐ │ │
│ │ │ PADDING │ │ │ Внутренний отступ
│ │ │ ┌───────────────┐ │ │ │
│ │ │ │ CONTENT │ │ │ │ Содержимое
│ │ │ └───────────────┘ │ │ │
│ │ └─────────────────────┘ │ │
│ └───────────────────────────┘ │
└─────────────────────────────────┘Это ключевое различие, которое всё объясняет.
width задаёт размер только содержимого. Padding и border добавляются сверху.
.box {
width: 200px;
padding: 20px;
border: 1px solid black;
/* Реальная ширина: 200 + 20 + 20 + 1 + 1 = 242px */
}width — это финальный размер. Padding и border вычитаются из содержимого.
.box {
box-sizing: border-box;
width: 200px;
padding: 20px;
border: 1px solid black;
/* Реальная ширина: ровно 200px. Содержимое = 200 - 20 - 20 - 1 - 1 = 158px */
}В начале каждого CSS-файла профессионального проекта:
*,
*::before,
*::after {
box-sizing: border-box;
}После этого width: 200px всегда означает финальные 200px. Так работают все CSS-фреймворки: Bootstrap, Tailwind, Material UI.
/* Одно значение — все стороны */
padding: 16px;
/* Два значения — вертикаль горизонталь */
padding: 8px 16px; /* верх/низ: 8px, лево/право: 16px */
/* Четыре значения — по часовой стрелке: верх право низ лево */
padding: 8px 16px 12px 16px;
/* Явные стороны */
padding-top: 8px;
padding-right: 16px;
padding-bottom: 12px;
padding-left: 16px;Вертикальные отступы между блоками схлопываются — берётся наибольший, а не сумма:
.block-1 { margin-bottom: 20px; }
.block-2 { margin-top: 30px; }
/* Расстояние между ними = 30px, а не 50px! */Горизонтальные margin НЕ схлопываются.
border: 1px solid #ddd; /* Сокращение: ширина стиль цвет */
border-radius: 8px; /* Скругление углов */
border-radius: 50%; /* Круг (для квадратного элемента) */
border-top: 2px solid #7b2ff7; /* Только сверху */
border: none; /* Убрать границу */Ошибка 1: Не включить border-box и удивляться размерам
/* Хочешь 3 колонки по 33.3%? Без border-box не получится */
.col { width: 33.33%; padding: 16px; } /* Суммарно > 100%, строчка ломается */
/* С border-box — всё точно */
* { box-sizing: border-box; }
.col { width: 33.33%; padding: 16px; } /* Работает */Ошибка 2: margin: auto не работает по вертикали
/* Горизонтальное центрирование — работает */
.container { width: 800px; margin: 0 auto; }
/* Вертикальное центрирование — не работает */
.box { height: 100px; margin: auto 0; } /* Нет эффекта по вертикали */
/* Для вертикального центрирования используй flexbox */Инструменты разработчика Chrome (DevTools) показывают блочную модель прямо в панели Elements — цветная диаграмма с margin (оранжевый), border (жёлтый), padding (зелёный), content (синий). Открой любой сайт, нажми F12, выдели элемент — увидишь его точные размеры.
content-box vs border-box: почему размеры не совпадают
// Добавляем глобальный сброс box-sizing
const resetStyle = document.createElement('style')
resetStyle.textContent = '*, *::before, *::after { box-sizing: border-box; }'
document.head.appendChild(resetStyle)
// === content-box (по умолчанию ДО сброса) ===
const contentBox = document.createElement('div')
contentBox.style.boxSizing = 'content-box' // явно указываем
contentBox.style.width = '200px'
contentBox.style.padding = '20px'
contentBox.style.border = '5px solid #7b2ff7'
contentBox.style.backgroundColor = '#f3e8ff'
contentBox.style.marginBottom = '16px'
contentBox.textContent = 'content-box: width=200px + padding + border'
document.body.appendChild(contentBox)
const cbStyle = window.getComputedStyle(contentBox)
// Реальная ширина = 200 + 20 + 20 + 5 + 5 = 250px
console.log('content-box — задано width:', '200px')
console.log('content-box — реальная ширина (offsetWidth):', contentBox.offsetWidth + 'px')
// 250px
// === border-box ===
const borderBox = document.createElement('div')
borderBox.style.boxSizing = 'border-box'
borderBox.style.width = '200px'
borderBox.style.padding = '20px'
borderBox.style.border = '5px solid #38a169'
borderBox.style.backgroundColor = '#f0fff4'
borderBox.textContent = 'border-box: width=200px включает всё'
document.body.appendChild(borderBox)
const bbStyle = window.getComputedStyle(borderBox)
// Реальная ширина = ровно 200px
console.log('border-box — задано width:', '200px')
console.log('border-box — реальная ширина (offsetWidth):', borderBox.offsetWidth + 'px')
// 200px
// Слои блочной модели
console.log('--- Слои блочной модели (border-box) ---')
console.log('padding:', bbStyle.padding) // 20px
console.log('border:', bbStyle.borderTopWidth) // 5px
console.log('width (финальный):', bbStyle.width) // 200px
// Схлопывание margin
const block1 = document.createElement('div')
block1.style.marginBottom = '20px'
block1.style.backgroundColor = '#fed7d7'
block1.style.padding = '8px'
block1.textContent = 'margin-bottom: 20px'
const block2 = document.createElement('div')
block2.style.marginTop = '30px'
block2.style.backgroundColor = '#bee3f8'
block2.style.padding = '8px'
block2.textContent = 'margin-top: 30px'
document.body.appendChild(block1)
document.body.appendChild(block2)
console.log('--- Схлопывание margin ---')
console.log('block1 margin-bottom: 20px, block2 margin-top: 30px')
console.log('Расстояние между ними = 30px (max), а не 50px (сумма)')Ты задаёшь кнопке width: 200px, но она вдруг оказывается шириной 240px. Или добавляешь padding, и вёрстка разъезжается. Это классическая проблема блочной модели — и как только ты её поймёшь, такие ошибки исчезнут навсегда.
Каждый HTML-элемент — это прямоугольник из четырёх слоёв:
┌─────────────────────────────────┐
│ MARGIN │ Внешний отступ (прозрачный)
│ ┌───────────────────────────┐ │
│ │ BORDER │ │ Граница
│ │ ┌─────────────────────┐ │ │
│ │ │ PADDING │ │ │ Внутренний отступ
│ │ │ ┌───────────────┐ │ │ │
│ │ │ │ CONTENT │ │ │ │ Содержимое
│ │ │ └───────────────┘ │ │ │
│ │ └─────────────────────┘ │ │
│ └───────────────────────────┘ │
└─────────────────────────────────┘Это ключевое различие, которое всё объясняет.
width задаёт размер только содержимого. Padding и border добавляются сверху.
.box {
width: 200px;
padding: 20px;
border: 1px solid black;
/* Реальная ширина: 200 + 20 + 20 + 1 + 1 = 242px */
}width — это финальный размер. Padding и border вычитаются из содержимого.
.box {
box-sizing: border-box;
width: 200px;
padding: 20px;
border: 1px solid black;
/* Реальная ширина: ровно 200px. Содержимое = 200 - 20 - 20 - 1 - 1 = 158px */
}В начале каждого CSS-файла профессионального проекта:
*,
*::before,
*::after {
box-sizing: border-box;
}После этого width: 200px всегда означает финальные 200px. Так работают все CSS-фреймворки: Bootstrap, Tailwind, Material UI.
/* Одно значение — все стороны */
padding: 16px;
/* Два значения — вертикаль горизонталь */
padding: 8px 16px; /* верх/низ: 8px, лево/право: 16px */
/* Четыре значения — по часовой стрелке: верх право низ лево */
padding: 8px 16px 12px 16px;
/* Явные стороны */
padding-top: 8px;
padding-right: 16px;
padding-bottom: 12px;
padding-left: 16px;Вертикальные отступы между блоками схлопываются — берётся наибольший, а не сумма:
.block-1 { margin-bottom: 20px; }
.block-2 { margin-top: 30px; }
/* Расстояние между ними = 30px, а не 50px! */Горизонтальные margin НЕ схлопываются.
border: 1px solid #ddd; /* Сокращение: ширина стиль цвет */
border-radius: 8px; /* Скругление углов */
border-radius: 50%; /* Круг (для квадратного элемента) */
border-top: 2px solid #7b2ff7; /* Только сверху */
border: none; /* Убрать границу */Ошибка 1: Не включить border-box и удивляться размерам
/* Хочешь 3 колонки по 33.3%? Без border-box не получится */
.col { width: 33.33%; padding: 16px; } /* Суммарно > 100%, строчка ломается */
/* С border-box — всё точно */
* { box-sizing: border-box; }
.col { width: 33.33%; padding: 16px; } /* Работает */Ошибка 2: margin: auto не работает по вертикали
/* Горизонтальное центрирование — работает */
.container { width: 800px; margin: 0 auto; }
/* Вертикальное центрирование — не работает */
.box { height: 100px; margin: auto 0; } /* Нет эффекта по вертикали */
/* Для вертикального центрирования используй flexbox */Инструменты разработчика Chrome (DevTools) показывают блочную модель прямо в панели Elements — цветная диаграмма с margin (оранжевый), border (жёлтый), padding (зелёный), content (синий). Открой любой сайт, нажми F12, выдели элемент — увидишь его точные размеры.
content-box vs border-box: почему размеры не совпадают
// Добавляем глобальный сброс box-sizing
const resetStyle = document.createElement('style')
resetStyle.textContent = '*, *::before, *::after { box-sizing: border-box; }'
document.head.appendChild(resetStyle)
// === content-box (по умолчанию ДО сброса) ===
const contentBox = document.createElement('div')
contentBox.style.boxSizing = 'content-box' // явно указываем
contentBox.style.width = '200px'
contentBox.style.padding = '20px'
contentBox.style.border = '5px solid #7b2ff7'
contentBox.style.backgroundColor = '#f3e8ff'
contentBox.style.marginBottom = '16px'
contentBox.textContent = 'content-box: width=200px + padding + border'
document.body.appendChild(contentBox)
const cbStyle = window.getComputedStyle(contentBox)
// Реальная ширина = 200 + 20 + 20 + 5 + 5 = 250px
console.log('content-box — задано width:', '200px')
console.log('content-box — реальная ширина (offsetWidth):', contentBox.offsetWidth + 'px')
// 250px
// === border-box ===
const borderBox = document.createElement('div')
borderBox.style.boxSizing = 'border-box'
borderBox.style.width = '200px'
borderBox.style.padding = '20px'
borderBox.style.border = '5px solid #38a169'
borderBox.style.backgroundColor = '#f0fff4'
borderBox.textContent = 'border-box: width=200px включает всё'
document.body.appendChild(borderBox)
const bbStyle = window.getComputedStyle(borderBox)
// Реальная ширина = ровно 200px
console.log('border-box — задано width:', '200px')
console.log('border-box — реальная ширина (offsetWidth):', borderBox.offsetWidth + 'px')
// 200px
// Слои блочной модели
console.log('--- Слои блочной модели (border-box) ---')
console.log('padding:', bbStyle.padding) // 20px
console.log('border:', bbStyle.borderTopWidth) // 5px
console.log('width (финальный):', bbStyle.width) // 200px
// Схлопывание margin
const block1 = document.createElement('div')
block1.style.marginBottom = '20px'
block1.style.backgroundColor = '#fed7d7'
block1.style.padding = '8px'
block1.textContent = 'margin-bottom: 20px'
const block2 = document.createElement('div')
block2.style.marginTop = '30px'
block2.style.backgroundColor = '#bee3f8'
block2.style.padding = '8px'
block2.textContent = 'margin-top: 30px'
document.body.appendChild(block1)
document.body.appendChild(block2)
console.log('--- Схлопывание margin ---')
console.log('block1 margin-bottom: 20px, block2 margin-top: 30px')
console.log('Расстояние между ними = 30px (max), а не 50px (сумма)')Напиши HTML-страницу, демонстрирующую разницу между content-box и border-box. Создай два одинаково стилизованных блока шириной 300px, padding 20px, border 5px solid. У первого box-sizing: content-box (реальная ширина больше 300px), у второго box-sizing: border-box (реальная ширина ровно 300px). Подпиши каждый блок.
padding: 20px, border: 5px solid #7b2ff7 (или другой цвет). box-sizing: content-box у первого — реальная ширина 350px. box-sizing: border-box у второго — реальная ширина ровно 300px. Это видно в DevTools в панели Elements справа.