CSS: ГЛОБАЛЬНАЯ УСТАНОВКА BOX-SIZING
box-sizing (читается «бокс-сайз») — CSS-свойство, определяющее способ подсчёта браузером итоговых размеров блочного элемента. На практике существуют два основных значения, полностью исключающие друг друга: content-box и border-box
- Значения свойства box-sizing
- Как задаётся значение свойства box-sizing
- Наследование свойства box-sizing
- Паттерн: Наследование через корень
- Паттерн: Прямое назначение
- «Авторитетное сравнение»
- Сравнение вариантов
- Заключение
- Как это работает
- Итог
- Суперитог
Значения свойства box-sizing
- content-box
- Значение «box-sizing» по умолчанию. Мерим внутреннее содержимое блока (content), без учета отступов и рамок-бордеров:
«Размер блока» = content. - border-box
- Складываем размеры: содержимое (content) + внутренние отступы (padding) + толщина рамки (border).
«Размер блока» = content + padding + border.
border-box, популярное ныне значение свойства box-sizing — учитывает размеры блока по внешнему краю элемента
Как задаётся значение свойства box-sizing
- Явно и непосредственно, в CSS-свойстве элемента: content-box или border-box
- Наследование от родителя: inherit
- Сброс к начальному значению: initial (вернёт значение по умолчанию: box-sizing: content-box;)
Наследование свойства box-sizing
- По умолчанию: Свойство box-sizing не наследуется
- Явное наследование: box-sizing: inherit; — наследует значение родителя при явном указании box-sizing: inherit; в дочернем элементе и создает цепочку наследования с исключительно переопределяемыми свойствами
Особенности наследования.
Включение наследования необратимо. Включенное однажды наследование свойства box-sizing: inherit; нельзя остановить или отменить. Наследование действует по цепочке вниз и НЕ! прекращается никогда. Доступно лишь переопределение (изменение) значения свойства для потомков. Механизм inherit не отключается. В CSS нет правила или команды, которая отключает наследование box-sizing: inherit;, как, например, text-decoration: none;
Паттерн: Наследование через корень
Популярный способ глобальной установки box-sizing получил название «Паттерн: Наследование через корень» и реализует каскадную CSS-логику: задаём box-sizing: border-box на корневой элемент html и inherit-распространяем значение на все элементы, включая псевдоэлементы.
/* Паттерн: Наследование через корень [inheritance-based] */
html {
/* Задаём корню (корневому элементу)
стартовое базовое значение */
box-sizing: border-box;
}
/* Устанавливаем наследование «от корня» */
*, *::before, *::after {
margin : 0;
padding : 0;
/* Элемент всегда берёт значение
box-sizing у своего родителя */
box-sizing : inherit;
}
/* • Все элементы наследуют box-sizing от корня html
(в нашем случае: border-box).
•• Если элементу ниже по тексту явно задать content-box,
это значение будет наследоваться всеми его потомками
до нового явного изменения (переназначения).
••• Так работает вторая строка нашего кода:
*, *::before, *::after { box-sizing: inherit; } */
Прим. Указание [margin:0;padding:0;] — не имеет никакого отношения к нашей теме и указано, исключительно, чтобы «не портить глаза»
Паттерн: Прямое назначение
Паттерн: «Прямое назначение» — не менее популярен и часто (если не всегда) используется в небольших проектах. Смысл его предельно ясен: никакого наследования и прямая установка box-sizing каждому элементу.
/* Паттерн: Прямое назначение [direct assignment] */
*, *::before, *::after {
margin : 0;
padding : 0;
/* Задаем сразу всем и конкретно каждому элементу,
явно, напрямую и без всякого наследования */
box-sizing : border-box;
}
/* • Все элементы получают box-sizing явно и напрямую
(в нашем случае — border-box).
•• Если НИЖЕ, в коде CSS, элементу ЯВНО задать content-box, значение
НЕ! будет наследоваться потомками,
потому как, для всех элементов применяется глобальное правило:
*, *::before, *::after { box-sizing: border-box; }
••• За сим, значения, отличные от заданного нами базового
прямого назначения (box-sizing:border-box;),
при необходимости — задаем постоянно, явно и снова, каждому элементу. */
6. «Авторитетное сравнение»
- Варианты 1 и 2 — полностью рабочие блоки кода глобальной установки свойства box-sizing, широко применяемые в современной верстке.
- Оба варианта — нормальные и рабочие. Делают одно и то же, но по-разному.
7. Сравнение вариантов
Вариант 1 (inheritance-based)
- Более гибкий.
- Удобен, если нужно локально менять box-sizing с наследованием: менять поведение в отдельных местах-цепочках, пачкой, для всех вложенных элементов.
Принцип работы: изменил значение у элемента-родителя → это значение пошло от родителя вниз ко всем вложенным дочерним элементам, пока не задали новое значение box-sizing (не переопределили).
Вариант 2 (direct assignment)
- Проще и жёстче.
- Подходит для большинства проектов без особых требований.
- Если изменили значение у элемента-родителя, это значение не наследуется дальше вниз. То есть действует исключительно для этого элемента.
- Если нужно то же самое у других элементов, включая дочерние, задаёшь каждому отдельно.
На практике чаще используют Вариант 1.
8. Заключение
Главное отличие вариантов 1 и 2: наследование свойства box-sizing по дереву DOM:
- Вариант 1: наследуется, передаёт значение потомкам (значение идёт вниз по элементам).
- Вариант 2: не наследуется, не передаёт значение потомкам — действует для текущего элемента (значение остаётся там, где задано).
9. Как это работает
Вариант 1 [inheritance-based] (наследование)
- Значение задано в корне html.
- Наследование есть.
- Значение передаётся ко всем элементам.
- Получается цепочка: родитель → потомки.
- Значение box-sizing задано в html и через
inheritпередаётся всем потомкам. - Создаются цепочки: от родителя к дочернему элементу.
Вариант 2 [direct assignment] (напрямую)
- Значение задаётся сразу каждому элементу.
- Оно никуда не передаётся.
- Наследования нет.
- Каждый элемент живёт «сам по себе».
- Значение задаётся напрямую глобальным селектором
*. - Значение не передаётся вниз по DOM.
- Не создаются цепочки: от родителя к дочернему элементу.
10. Итог
- Вариант 1: значение задано и «течёт вниз» к дочерним элементам.
- Вариант 2: значение задаётся каждому отдельно и остаётся на месте. Вложенные элементы никак на него не реагируют.
11. Суперитог
Если сжать до предела:
- Вариант 1 — это про распространение: запускаешь значение в дерево, и оно живёт дальше.
- Вариант 2 — это про фиксацию: ставишь значение в точке, и оно там же заканчивается.
Главное различие между вариантами — это не способ задания свойства, а тип управления поведением внутри дерева.
Вариант 1 (inherit)
Ты управляешь не элементами, а потоками значений.
Любое изменение — это не просто точечная правка, а вмешательство в распространение значения.
Ты задаёшь не состояние элемента, а направление, по которому это состояние будет жить дальше.
Это означает:
- Элемент — не конечная точка.
- Элемент — участок-проводник значения.
- Любое изменение влияет, и на него, и на всё, что ниже.
В результате ты работаешь с системой как с связанной средой, где всё влияет друг на друга, в создаваемых цепочках.
Архивные тексты и практическое объяснение
Вариант 1 [inheritance-based]:
- Наследование свойства есть.
- Наследование задано глобально, в строке:
*, *::before, *::after { box-sizing: border-box; } - Создаются цепочки наследования от родителя к потомку (дочернему элементу).
- Значение box-sizing задаётся в корне html и наследуется: дочерний элемент берёт текущее значение у своего родителя через inherit, заданный глобально.
- Значение передаётся вниз по дереву.
Вариант 2 [direct assignment]:
- Наследования свойства нет.
- Цепочек наследования не существует.
- Значение box-sizing задаётся сразу всем элементам индивидуально, напрямую через глобальный селектор
- и псевдоэлементы
*::before, *::after.
Практика (как это работает)
Разница между вариантами проявляется не просто в наличии/отсутствии механизма наследования, а в том, что происходит, если изменить box-sizing внутри дерева:
Вариант 1 [inheritance-based]
- Есть цепочка наследования.
- Если где-то в дереве задать:
box-sizing: content-box;, то это значение становится новым для этого элемента и автоматически передаётся всем его потомкам. - Актуальное значение у родителя может меняться сколько угодно раз, и каждый раз становится новым источником вниз по дереву.
- Значение можно снова переопределять на любом уровне, и каждый раз оно будет дальше идти вниз по дереву.
- Получается слоистый пирог: каждый раз заданное свойство наследуется до тех пор, пока не будет задано иное.
Девиз: "изменил здесь → пошло дальше вниз, пока снова не переопределили"
Вариант 2 [direct assignment]
- Нет цепочки наследования.
- Если где-то в дереве задать:
box-sizing: content-box;, то это значение влияет только на этот элемент, и потомки не получают это значение. - Потому что для них снова применяется глобальное правило:
*, *::before, *::after { box-sizing: border-box; }
Девиз: "изменил здесь — здесь и закончилось. Надо пять раз под ряд — задавай пять раз под ряд. Наследования нет, свойство не передается вниз"