Блочная модель элемента - это набор css-свойств элемента, позволяющих управлять его внешним видом. С помощью набора свойств box-модели вы можете оформить различные элементы в соответствии с дизайнерским макетом, изменяя их ширину и высоту, а также добавив различные отступы и рамки.
Свойства box-модели включают в себя:
- Ширину содержимого элемента
- Высоту содержимого элемента
- Переполнение элемента. Свойство overflow
- Внутренние отступы
- Внешние отступы
- Рамки, или границы
При создании разметки страницы очень важно понимать, как соотносятся между собой все эти свойства для формирования внешнего вида блока.
Когда мы говорим о box-модели, подразумеваем, что речь идет, прежде всего, о блочных элементах, т.е. тех элементах, которые имеют css-свойство display
со значением block
и по умолчанию занимают все доступное пространство внутри родительского элемента. Для строчных элементов свойства блочной модели работают не всегда предсказуемо. Применять свойства box-модели можно также к элементам с display: inline-block
, а также к элементам таблицы с display: table
или table-cell
.
На рисунке видно, каким образом распределяется пространство внутри блочной модели элемента. Часть свойств может быть назначена только для одной или нескольких сторон элемента. В этих случаях важны суффиксы, связанные с англоязычными названиями сторон - top (верхняя), right (правая), bottom (нижняя) и left (левая).
Ширина содержимого элемента
Ширина содержимого элемента определяется свойством width
, для которого доступны следующие варианты значений:
1 | width: auto|значение в px, pt, %, in, em, rem, mm и др. единицах |initial|inherit; |
Значение auto
используется по умолчанию. Оно значит, что любой блочный элемент занимает автоматически все доступное пространство внутри элемента-родителя или в браузере. Значение initial
устанавливает исходное значение, т.е. по сути, равнозначно auto, inherit
- наследует значение от родителя. Чаще всего ширину задают в каких-либо единицах, из которых самыми популярными являются пиксели (px), проценты (%), а также единицы, связанные с размером шрифта родительского элемента - em или корневого элемента (тег <html>) - rem.
В случае, если ширина задается в %, расчет ее ведется относительно ширины родительского элемента или окна браузера.
Вы можете посмотреть пример в отдельном окне по ссылке.
Минимальная и максимальная ширина элемента
Кроме свойства width вы также можете использовать такие полезные свойства, как max-width
и min-width
. Как следует из их названий, max-width
ограничивает максимальную ширину блока, а min-width
не дает элементу стать меньше указанного в ней размера.
Для этих свойств допустимы такие значения:
1 2 | max-width: none (по умолчанию)| размер в px, em, in, % и др. единицах | inherit | initial min-width: 0 (по умолчанию)|размер в px, em, in, % и др. единицах | inherit |initial |
Обычно эти свойства применяют, когда не нужно строго ограничивать размер элемента, но при этом он должен быть не более max-width
, но и не менее min-width
.
В примере ниже 2 блока с изображениями помещаются в контейнер с классом wrapper. Размеры этого контейнера определяются размерами блоков с фотографиями. Стили всех нужных элементов таковы:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | .wrapper { width: 80%; max-width: 938px; margin: 20px auto; border: 2px dotted #444; padding: 10px 0; overflow: hidden; } .cat-block { width: 48%; margin: 1%; float: left; min-width: 230px; } .cat-block img {max-width: 100%;} |
Для того чтобы оба блока с фото поместились (а размер изображения в каждом из них составляет 450x280px), необходимо, как минимум 900px (450px*2). Также нужно учесть отступы, а они указаны в свойстве margin: 1%
и при расчете будут составлять примерно 9px с каждой стороны (900px*1%/100% = 9px
).
Важно: проценты в случае отступов рассчитываются относительно ширины родительского элемента.
Получается, что при расчете максимальной ширины контейнера с классом wrapper
мы должны отталкиваться от ширины блоков с фото + учитывать отступы между ними. Получаем такую величину: (450+2*9)*2 = 468*2 = 936px
. Т.е. можем написать, что у класса wrapper min-width: 936px
.
Но почему тогда в стилях выше указано значение в 938px
? Подвох тут в процентном значении у свойства margin: от 936px 1% будет составлять уже 9.36px. Для 2-х блоков с горизонтальными отступами с 2-х сторон это значение нужно умножить на 4. И тогда получится 900 + 9.36*4 = 937.44px
. Можем округлить это значение до 938px и остановиться на нем. Для того чтобы избежать всей этой головной боли с вычислениями, лучше использовать свойство box-sizing: border-box
.
Для того чтобы при уменьшении экрана у нас изменялась ширина контейнера, мы назначим классу wrapper свойство width: 80%
, но вместе с этим у нас будут уменьшаться и блоки с фотографиями, т.к. их ширина указана, как width: 48%
. Чтобы вместе с уменьшением блока изменялся размер фотографий, для селектора .cat-block img
указано свойство max-width: 100%
. Если мы хотим предотвратить уменьшение блоков с фото, мы можем установить минимальную их ширину в 230px (min-width: 230px
), поэтому на маленьких экранах второй блок переедет вниз, под первый. Ширина их по-прежнему останется равной 48% от размера родителя, но меньше 230px она не будет.
Вы можете посмотреть пример в отдельном окне по ссылке и увидеть, как изменяются размеры элементов в зависимости от ширины экрана.
Высота содержимого элемента
Высота содержимого элемента определяется свойством height
, для которого доступны следующие варианты значений:
1 | height: auto|значение в px, pt, %, in, em, rem, mm и др. единицах |initial|inherit; |
Можно заметить, что значения для высоты элемента задаются так же, как и для его ширины, но указывать высоту элемента явно (в px, %, pt, em, rem, in, cm, mm или других единицах измерения) стоит далеко не всегда.
Из примера можно увидеть, что при явном назначении высоты какого-либо блока (родительского или дочернего), текст может не помещаться и выходить за пределы этого блока, что не слишком-то красиво выглядит. Поэтому чаще всего высоту оставляют с ее значением по умолчанию - auto
, а это значит, что высота блока будет формироваться в зависимости от количества текста в нем. Также стоит понимать, что ширина и высота блока взаимосвязаны - чем меньше ширина элемента, тем больше будет его высота при одинаковом наполнении текстом или другим содержимым.
Минимальная и максимальная высота элемента
Если все же необходимо задать высоту, можно также использовать такие css-свойства, как min-height
или max-height
. Они могут иметь следующие значения:
1 2 | max-height: none (по умолчанию)| размер в px, pt, em, in, % и др. единицах | initial | inherit min-height: 0 (по умолчанию)| размер в px, pt, em, in, % и др. единицах | initial | inherit |
Когда вы используете оба значения, вы говорите браузеру, что высота какого-либо элемента не может быть меньше значения, заданного для min-height
, но и не больше значения для max-height
.
В примере ниже вы можете управлять этими свойствами и наблюдать за изменениями высоты элементов. Заметьте, что изначально 3 блока имеют разную высоту и "рваные" нижние края. За счет увеличения min-height
вы можете "продлить" меньший из блоков, выравняв высоту всех элементов. Изменение max-height
приведет к появлению полосы прокрутки в каждом блоке, т.к. указанного значения недостаточно для того, чтобы поместился весь контент, плюс для блоков назначено свойство overflow: auto
.
Если же значение максимальной высоты будет меньше, чем значение минимальной, оно будет проигнорировано. Это говорит о том, что нет смысла указывать оба значения в такой ситуации.
Вы можете посмотреть пример в отдельной вкладке и изменять высоту элементов при разном размере окна браузера.
Переполнение элемента. Свойство overflow
При верстке страницы вы можете столкнуться с необходимостью задать ширину или высоту элементу, но при этом содержимое элемента помещаться в заданные размеры не будет. В этом случае вы получаете переполнение элемента его содержимым и задаетесь вопросом, что с этим делать.
Для решения этой проблемы служит свойство overflow с такими вариантами значений:
1 | overflow: visible (по умолчанию)| hidden | scroll | auto | initial | inherit; |
В примере ниже для области стихотворения заданы такие стили:
1 2 3 4 5 6 7 8 | #elem { width: 400px; height: 400px; background: url(images/tetrad.jpg) 0 -5px; background-attachment: local; line-height: .8; padding: 10px; } |
По умолчанию вы видите текст, выходящий за пределы блока с фоном в виде тетрадного листа (overflow: visible
). Вы можете обрезать весь текст вне листа (overflow: hidden
), добавить одну вертикальную полосу прокрутки, если переносы текста выполняются автоматически, или 2 полосы прокрутки, если переносы запрещены свойством white-space: nowrap
, - так работает свойство overflow: auto
. Свойство overflow: scroll
добавляет 2 полосы прокрутки вне зависимости от необходимости в них. Значение initial
возвращает нас к значению по умолчанию, т.е. к overflow: visible
.
Протестировать пример в новой вкладке.
Внутренние отступы (padding)
Внутренние отступы включаются в заливку фоном или фоновым изображением и очень важны для визуального восприятия блока с текстом. По умолчанию у большинства элементов они равны 0. Исключение составляют только списки. Тем не менее, добавлять внутренние отступы приходится очень часто, т.к. без них текст "прилипает" к границе элемента, и выглядит это некрасиво и неаккуратно.
Внутренние отступы можно задавать в любых единицах, доступных в CSS, но всегда это должно быть положительное число или ноль. Отрицательными они быть не могут, в отличие от отступов внешних. Определять отступы можно сразу для всех 4-х сторон элемента (1 цифра), одновременно для верхней и нижней и левой и правой сторон (2 цифры), для верха, боковых сторон и низа (3 цифры) и по часовой стрелке, начиная с верхней стороны (4 цифры):
Когда вы назначаете 4 разных значения, то обход выполняется по схеме: сверху-справа-вниз-налево или на английском top-right-bottom-left.
В случае, если padding
назначается в % (внимание!), его величина рассчитывается относительно ширины родительского элемента. Это важно понимать, т.к. далеко не всегда вы будете готовы к тому, что отобразит вам браузер.
Если существует необходимость назначить только один отступ, используют свойство padding
с указанием стороны, для которой его назначают:
padding-top
- только для верхней;padding-right
- для правой;padding-bottom
- только для нижней;padding-left
- для левой.
Для того чтобы назначить отступы с 3-х сторон элемента, можно сначала указать padding
для всех сторон, а затем обнулить отступ там, где он не нужен:
1 2 3 4 | padding: 20px; padding-left: 0; /* или */ padding: 20px 20px 20px 0; |
Внешние отступы (margin)
Внешние отступы всегда являются прозрачными и отодвигают соседние элементы друг от друга. Довольно много элементов в HTML по умолчанию имеют внешние отступы, чаще всего по горизонтальным сторонам (сверху и снизу) - это заголовки всех уровней, абзацы, блочная цитата (blockquote) и списки.
Внешние отступы записываются аналогично внутренним, т.е. с помощью одной, двух, трех или четырех цифр, но могут быть заданы как положительным, так и отрицательным числом. Положительные числа отодвигают соседние элементы друг от друга, а отрицательные, наоборот, сближают.
Помимо значений в цифрах+единицы измерения, свойство margin
имеет еще значение auto
, - оно означает, что в зависимости от ширины элемента, его отступ будет рассчитан автоматически браузером. Например, для какого-то элемента-контейнера можно написать такие css-правила:
1 2 3 4 | .container { width: 80%; margin: auto; } |
Браузер сам рассчитает, сколько в пикселях будет 80% от ширины открытого окна, а все остальное пространство поделит на 2 и распределит поровну с 2-х сторон контента. Т.е. это простой способ центрирования блочных элементов в CSS. О других способах центрирования элементов можно прочитать в соответствующей статье.
Вы можете самостоятельно посмотреть на выравнивание блока с текстом при использовании разных свойств.
У внешних отступов есть еще одна особенность - они схлопываются для элементов, которые идут друг за другом по вертикали. Это значит, что при назначении у блоков свойства margin: 20px 0; между соседними блоками будет не 40px (20px верхнего блока + 20px нижнего блока), а всего 20px, т.к. отступы накладываются.
Схлопывание срабатывает только для вертикальных отступов, но не применяется для горизонтальных. Кроме того, схлопывание не срабатывает:
- для тега
<html>
- для строчных элементов;
- для элементов, имеющих свойство
float: left
илиright
- у абсолютно позиционированных элементов
- для элементов, у которых на стороне схлопывания задано свойство
padding
- для элементов, у которых на стороне схлопывания задано свойство
border
.
Рамки, или границы (свойство border)
По умолчанию блочные элементы рамок не имеют. Даже таблицы, и те отображаются без рамки до назначения им свойства border
.
Вариантов использования этого свойства очень много, т.к. состоит оно из 3-х составляющих - цвета рамки (border-color), ее толщины (border-width) и стиля (border-style). Комбинировать эти свойства можно в разной последовательности, важно помнить, что в составных или универсальных свойствах значения записываются через пробел:
1 | .block { border: 3px solid red;} |
Если вы забудете написать цвет рамки, то по умолчанию к ней применится цвет текста. Еще важно помнить, что рамки (границы) в % не задаются. В любых других единицах, но не в %. И к ним можно применять ключевые слова thin
(тонкая), medium
(средняя) и thick
(толстая), если вам так будет удобней, чем в других единицах. Лучше, конечно, задавать толщину применительно к размеру шрифта (em, rem) или в px, но выбор у вас в этом вопросе широк.
Протестировать некоторые свойства и просто посмотреть на другие можно в файле о рамках.
В статье "Простые задачи по JavaScript" можно посмотреть, как использованы рамки для создания светофора исключительно на HTML и CSS.
Использование свойства border для создания стрелок
На сайте довольно часто необходимо использовать различные виды стрелок либо для кнопки плавной прокрутки содержимого страницы вверх, либо для выпадающих пунктов меню. Вы можете сделать это либо с помощью иконочных шрифтов, либо с помощью SVG или PNG-изображений, однако CSS тоже может вам помочь в этом.
See the Pen Sass arrow mixin by Elen (@ambassador) on CodePen.
Свойство border с использованием линейного градиента
Если для вашей страницы необходимы рамки (границы) с линейным градиентом, то вы можете использовать один из приведенных ниже вариантов.
See the Pen CSS dashed border using linear-gradient by Naoya (@nxworld) on CodePen.