Найти в Дзене

Чем отличается box-sizing: border-box от content-box?

В 1996 году W3C в спецификации CSS предложил модель, в которой ширина элемента — это ширина его content-области.
Пограничные случаи этой модели начали сыпаться уже к 2002-му:
— дизайнер просит блок шириной 300px с 10px padding и 1px border;
— вы пишете width: 300px; padding: 10px; border: 1px solid;
— браузер выдаёт блок шириной 322px и ломает макет. Это не баг — это content-box в действии.
А border-box — это патч, который выправляет поведение. Давайте разберёмся детально. Что происходит внутри?
— width: 200px задаёт ширину только контентной области;
— padding и border добавляются снаружи;
— итоговая занимаемая ширина = 200 + 2×20 + 2×5 = 250px. 🎯 Представьте, что вы заказываете рамку для картины размером 200×200 мм.
Мастер делает холст размером 200 мм, а потом прибивает вокруг него багет шириной 25 мм.
Итоговая рамка — 250 мм. Вы удивлены — ведь вы же просили «200 мм»! Итог: ширина визуального блока ≠ та, что вы указали в width. Что происходит теперь?
— width: 200px задаёт ширину все
Оглавление

🔍 Проблема, которую решает box-sizing

В 1996 году W3C в спецификации CSS предложил модель, в которой ширина элемента — это ширина его content-области.
Пограничные случаи этой модели начали сыпаться уже к 2002-му:
— дизайнер просит блок шириной 300px с 10px padding и 1px border;
— вы пишете width: 300px; padding: 10px; border: 1px solid;
— браузер выдаёт блок шириной
322px и ломает макет.

Это не баг — это content-box в действии.
А border-box — это патч, который выправляет поведение. Давайте разберёмся детально.

📏 Модель content-box — поведение по умолчанию

-2

Что происходит внутри?
— width: 200px задаёт ширину
только контентной области;
— padding и border
добавляются снаружи;
— итоговая занимаемая ширина = 200 + 2×20 + 2×5 = 250px.

🎯 Представьте, что вы заказываете рамку для картины размером 200×200 мм.
Мастер делает
холст размером 200 мм, а потом прибивает вокруг него багет шириной 25 мм.
Итоговая рамка — 250 мм. Вы удивлены — ведь вы же просили «200 мм»!

Итог: ширина визуального блока ≠ та, что вы указали в width.

📦 Модель border-box — поведение, которого хотят все

-3

Что происходит теперь?
— width: 200px задаёт ширину
всего блока от края border до края border;
— padding и border
вычитаются изнутри;
— размер контентной области = 200 − 2×5 − 2×20 = 150px.

🎯 Теперь вы говорите: «Мне нужна рамка ровно 200 мм в габаритах».
Мастер берёт багет (5 мм), отмеряет внутренний зазор для паспарту (20 мм), и уже под это подгоняет сам холст.
Размер холста уменьшается, но внешние габариты — строго 200 мм.

Итог: ширина визуального блока = значению width.
Это предсказуемо. Это стабильно. Это то, что использует 99% современных фреймворков.

⚙️ Как использовать border-box — и почему это must-have

Просто вставьте это в начало стилей:

-4

⚠️ Зачем *::before и *::after?
Псевдоэлементы тоже участвуют в layout. Без этого правила — они останутся на content-box, и вы поймаете глюк в попапе через полгода.

💡 Профессиональный лайфхак:
Не переопределяйте box-sizing в каждом компоненте — это технический долг.
Глобальный reset — единственный честный способ.

📊 Сравнение в таблице

-5

❓ Почему же content-box до сих пор дефолт?

Исторически — потому что CSS1 (1996) не предвидел сложных layout-ов с padding и border.
Позже, когда border-box появился (IE5 for Mac, 2000), W3C не стал менять дефолт — из-за
обратной совместимости.

💬 Цитата из спецификации CSS UI Level 3:
«Changing the initial value would be web-incompatible. Authors are encouraged to use border-box explicitly.»

Другими словами: «Да, content-box — плохой выбор. Но мы не можем его убрать, иначе взорвётся весь интернет 1998 года».

✅ Выводы — кратко и по делу

  1. content-box — width = только контент. Padding и border — как налог сверху.
  2. border-box — width = весь блок целиком. Padding и border «съедают» контент изнутри.
  3. Всегда применяйте *, *::before, *::after { box-sizing: border-box }.
  4. Это не «хак», это стандарт де-факто — как normalize.css или rem вместо px.