Box-Sizing: секрет простых лейаутов
Box-sizing – это свойство CSS, которое делает верстку макетов сайта более понятным. Если вы работали с CSS, то вы знаете, что использование свойств width, padding и border ведет к путанице. Иногда, когда используется свойство width, оно не может быть всегда применено к тому, что вы ожидаете – например ширина width задается в процентах, а граница border указывается в пикселях. Тем не менее, используя свойство box-sizing, ширина блока в 200px будет действительно отображать блок шириной 200px.
Это никак не связано с JavaScript и это также работает в Internet Explorer, начиная с 8й версии.
Блочная модель
Ширина и высота любого элемента на веб-странице описана в блочной модели CSS. Тонкости блочной модели могут быть сложными, но самая важная часть к понимаю это то, как вычисляются ширина и высота блока на странице. Сумма нескольких свойств CSS образует фактически отображаемую ширину и высоту блока.
Без box-sizing, ширина width представляет собой область содержимого (158px).
Актуальная ширина включает ширину области – content, отступы – padding, и границу – border.
Это означает, что если будет установлена ширина 200px, то элемент займет точно указанный размер, если не будет padding и border. Т.е., свойство width означает ширину контентной области, а не ширину всего блока (включая padding и border).
Если вы хотите сделать ширину блока равной 200px, а потом захотите сделать отступы по 20px с каждой стороны, необходимо позаимствовать 40px (20px для левой и 20px для правой сторон) от этой ширины. То же самое надо сделать, при установке величины border. Все это делает код менее читабельным. Чтобы блок имел общую ширину 200px, необходимо код писать так:
Все это не очень удобно. К счастью, есть более лучший и наглядный способ, который может привести к аналогичному результату.
Вместо вычисления ширины, включающей отступы и границы, свойство box-sizing в сочетании с border-box использует собственную ширину в качестве общей ширины блока. И предыдущий код можно изменить так:
Теперь любые отступы или границы не будут добавлены к общей ширине. Вместо этого, они будут автоматически вычитаться из предоставленного пространства. Это приводит к тому, что код становится более понятным для чтения и понимания.
Ниже показано изображение, каким образом свойство box-sizing:border-box расчитывает ширину
Когда box-sizing включен – ширина width является шириной всего блока.
Ширина контента автоматически подстраивается в зависимости от правого и левого отступа, и значений бордеров.
На самом деле, многие веб-дизайнеры и разработчики выступают за использование на веб-страницах для всех элементов более естественного и интуитивного подхода к компоновке блоков.
Paul Irish предлагает использовать следующий код для этого:
Свойство box-sizing не новое, и только из-за того, что оно не поддерживалось в браузерах Internet Explorer ниже 8й версии, его не применяли. Теперь, когда вышли новые версии браузеров эта техника работы с box-sizing становится популярной и рекомендуется использовать ее при создании своих сайтов. Для более полной информации о поддерживаемых браузеров, смотрите в таблице.
Также свойство box-sizing, по-умолчанию, встроено в стили популярных фреймворков Bootstrap и Foundation. Оба эти фреймворка применяют значение border-box к абсолютно всем элементам, что делает их системы более понятными.
Свойство box-sizing
Свойство box-sizing может принимать одно из двух значений – border-box или content-box . В зависимости от выбранного значения браузер по-разному трактует значение свойств width/height .
Значения box-sizing
Для большей наглядности посмотрим на картинку этого div в зависимости от box-sizing :
В верхнем случае браузер нарисовал весь элемент размером в width x height , в нижнем – интерпретировал width/height как размеры внутренней области.
Исторически сложилось так, что по умолчанию принят content-box , а border-box некоторые браузеры используют если не указан DOCTYPE , в режиме совместимости.
Но есть как минимум один случай, когда явное указание border-box может быть полезно: растягивание элемента до ширины родителя.
Пример: подстроить ширину к родителю
Задача: подогнать элемент по ширине внешнего элемента, чтобы он заполнял всё его пространство. Без привязки к конкретному размеру элемента в пикселях.
Например, мы хотим, чтобы элементы формы ниже были одинакового размера:
Как сделать, чтобы элементы растянулись чётко по ширине FORM ? Попробуйте добиться этого самостоятельно, перед тем как читать дальше.
Попытка width:100%
Первое, что приходит в голову – поставить всем элементам INPUT ширину width: 100% .
Как видно, не получается. Элементы вылезают за пределы родителя.
Причина – ширина элемента 100% по умолчанию относится к внутренней области, не включающей padding и border . То есть, внутренняя область растягивается до 100% родителя, и к ней снаружи прибавляются padding/border , которые и вылезают.
Есть два решения этой проблемы.
Решение: дополнительный элемент
Можно убрать padding/border у элементов INPUT/SELECT и завернуть каждый из них в дополнительный DIV , который будет обеспечивать дизайн:
В принципе, это работает. Но нужны дополнительные элементы. А если мы делаем дерево или большую редактируемую таблицу, да и вообще – любой интерфейс, где элементов и так много, то лишние нам точно не нужны.
Кроме того, такое решение заставляет пожертвовать встроенным в браузер дизайном элементов INPUT/SELECT .
Решение: box-sizing
Существует другой способ, гораздо более естественный, чем предыдущий.
При помощи box-sizing: border-box мы можем сказать браузеру, что ширина, которую мы ставим, относится к элементу полностью, включая border и padding :
Мы сохранили «родную» рамку вокруг INPUT/SELECT и не добавили лишних элементов. Всё замечательно.
box — sizing
Это свойство определяет как будут вести себя размеры блока.
Время чтения: меньше 5 мин
- Кратко
- Пример
- Как понять
- Как пишется
- Подсказки
- На практике
- Алёна Батицкая советует
- Светлана Коробцева ,
- Антон Капустинский
Обновлено 2 ноября 2022
Кратко
Скопировать ссылку «Кратко» Скопировано
При помощи свойства box — sizing можно изменить то, как браузер будет рассчитывать размеры элемента.
По умолчанию размером элемента считается размер контентной области. Если кроме width и height указать ещё и padding с border , то браузер посчитает размер элемента как width + padding * 2 + border * 2 и height + padding * 2 + border * 2 .
Если задать значение border — box для свойства box — sizing , то браузер изменит принцип расчёта и padding с border уже будут включены в width и height .
Подробнее об особенностях расчёта размеров элемента можно прочитать в статье «Блочная модель».
Пример
Скопировать ссылку «Пример» Скопировано
Создадим два элемента и зададим обоим элементам идентичные стили:
Отличаться они будут только фоном и значением свойства box — sizing .
В итоге элементы получились разного размера! Как так? Мы ведь указали одинаковые ширину, высоту и внутренние отступы, а так же рамку
Как понять
Скопировать ссылку «Как понять» Скопировано
Причина в том, что при значении свойства box — sizing , равном content — box (значение по умолчанию) ширина элемента рассчитывается следующим образом:
Ширина контентной области (100) + внутренний отступ слева и справа (25 + 25) + ширина правой и левой рамок (10 + 10). Итого: 170 пикселей.
Аналогично с высотой.
Выходит что первый элемент получил размеры 170 х 170.
Размер второго элемента считается иначе. Из-за значения свойства box — sizing браузер воспринимает width и height как конечные размеры элемента. Получается что в 100 пикселей указанной ширины уже включены и внутренние боковые отступы и боковые рамки. Размеры второго элемента будут 100 х 100.
Как пишется
Скопировать ссылку «Как пишется» Скопировано
В качестве значения для свойства box — sizing невозможно использовать что-то кроме ключевых слов. Значение может быть только одно.
- content — box — значение по умолчанию. Финальная ширина = ширина + правый внутренний отступ + левый внутренний отступ + правая рамка + левая рамка
- border — box — значение width и height являются финальными размерами элемента. Финальная ширина = ширина
Подсказки
Скопировать ссылку «Подсказки» Скопировано
Свойство нельзя анимировать при помощи transition
Свойство не наследуется.
При любом значении свойства внешние отступы ( margin ) в расчёт не берутся.
Значение по умолчанию: content — box .
На практике
Скопировать ссылку «На практике» Скопировано
Алёна Батицкая советует
Скопировать ссылку «Алёна Батицкая советует» Скопировано
Из-за стандартного механизма расчёта размера элемента многие начинающие разработчики получают не те размеры элемента, которые ожидали. При этом есть два решения:
- Подгонять размер элемента под желаемый, высчитывая самостоятельно, какими должны быть внутренние отступы и рамка, чтобы в итоге получился нужный размер.
- В самом начале работы «сбросить» стандартное значение, заменив его на предсказуемое box — sizing .
Для «сброса» можно использовать универсальный селектор. Напиши в самом начале файла со стилями:
Теперь все размеры элементов будут равны тем значениям, что заданы в свойствах width и height . Так победим
Note to Self — Guide on CSS Box-Sizing
This is my own summarized understanding of CSS box-sizing property. After going through several courses and articles about web development. You will realize the most of the courses recommend the following simplest best practice for box-sizing:
For quite a while, I am just reusing this boilerplate code and forget the reason and what’s the purpose of having this code. So I wrote this article to enhance my understanding and hardwired this into my brain and serves as a place where I could redirect if my fellow teammates asked me why you choose to use border-box.
Why border-box?
The first question you always have is why border-box is the most popular and recommended the box-sizing method. The reason is fairly simple. It’s because straightforward and intuitive.
Straightforward
It is straightforward in terms of specifying the width of the element. When you’re trying to specifying the width of the element with the following code.
As human beings, we tend to interpret this element to have a total width of 300px, which is wrong in this scenario. Instead, the total width of the element is: 350px.
However, if we declare box-sizing: border-box. The width of the container will factor in the padding and border width as well which equivalent to: 300px.
This means no matter how much border and padding you have set, the width of the element is still similar to what you specify in the width property, which 300px in this example.
Codepen Example:
Conclusion
Due to this situation, it’s counterintuitive and counterproductive if we every time we have to calculate the element width by ourselves. It’s even more impossible to calculate the width via
Using border-box approach, it makes the development experience much better.
However, there is a slightly better practice for box-sizing which I will explore and write about later. It’s about inheriting the box-sizing.