Блочная модель

Каждый элемент в CSS заключён в блок, и понимание поведения этих блоков — это ключ к умению задавать раскладку с помощью CSS, то есть выстраивать одни элементы относительно других элементов.
Блочные и строчные элементы
В CSS есть два типа элементов — блочные (block) и строчные (inline).

Вы уже познакомились со многими HTML-элементами и могли заметить, что их поведение не всегда одинаковое — некоторые элементы, как заголовки или абзацы всегда начинаются с новой строки. Такие элементы называются блочными.
Эти элементы - основа вёрстки HTML, так как напрямую воздействуют на то, как будут расположены элементы рядом с ними на странице.

Если элемент определён как блочный (block), то он будет вести себя следующим образом:
  • Начнётся с новой строки.
  • Будет расширяться вдоль строки таким образом, чтобы заполнить всё пространство, доступное в её контейнере. В большинстве случаев это означает, что блок станет такой же ширины, как и его контейнер, заполняя 100% доступного пространства.
  • Будут применяться свойства width и height.
  • Внешние и внутренние отступы, рамка будут отодвигать от него другие элементы.


Помимо блочных элементов существуют строчные элементы.
К ним относятся ссылки ( <a>), теги начертания текста ( <b>, <strong>, <i>, <em>), картинки, <span>. Они не влияют на расположение соседних элементов и предназначены для придания смысловой нагрузки. В отличие от блочных элементов, строчные не занимают всю ширину экрана, а лишь то пространство, которое им необходимо.

Если элемент имеет тип отображения строчный (inline), то:
  • Он не будет начинаться с новой строки.
  • Свойства width и height не будут применяться.
  • Вертикальные внешние и внутренние отступы, рамки будут применяться, но не будут отодвигать другие строчные элементы.
  • Горизонтальные внешние и внутренние отступы, рамки будут применяться и будут отодвигать другие строчные элементы


Тип отображения, применяемый к элементу, определяется значениями свойства display, такими как block и inline, и относится к внешнему значению.
Внутренний и внешний тип отображения
Здесь следует объяснить, что такое внутренние и внешние типы отображения.

Каждый блок в CSS имеет внешний тип отображения, который определяет, блочный он или строчный.

Элементы также имеют внутренний тип отображения, который определяет расположение элементов внутри них.
Когда вы перейдёте к более подробному изучению CSS вёрстки, вы встретите flex и другие внутренние значения, которые могут быть у ваших элементов, например grid. Но пока мы сосредоточимся на изучении внешнего типа.
Примеры отображения разных элементов
Пример 1.
У нас есть 2 разных элемента HTML с внешним типом отображения block.

Первый элемент — это абзац, у которого есть рамка, указанная в CSS. Браузер, по умолчанию, отображает его как блочный элемент, поэтому абзац начинается с новой строки и расширяется на всю доступную ему ширину.

Второй элемент - это абзац блочного типа, внутри которого есть два строчных элемента <span>. Элементы <span> по умолчанию имеют тип inline, однако у одного из них задан класс block, для которого установлен display: block.
index.html
<!DOCTYPE HTML>
<html>
   <head>
      <meta charset="utf-8">
      <title>Блочные и сточные внешние элементы</title>
      <link href="style.css" rel="stylesheet">
   </head>
   <body>
      <p>Я просто параграф. По умолчанию я имею блочный тип.</p>
      <p>Я другой параграф. У меня некоторые <span class="block">слова</span> заключены в <span>строчный элемент span.</span></p> 
   </body>
</html>
style.css
p 
{
  border: 2px solid purple;
  padding: 10px;
}

.block 
{
  display: block;
  border: 2px solid blue;
  padding: 10px;
}      
    
Сейчас вы видите, что <span> для которого был задан display:block стал блочным из-за чего произошел перенос "слова" на новую строку. Для второго <span> не был задан класс и видно, что "строчный элемент span" остался на своем месте и никуда не сдвинулся.
Пример 2.
Теперь рассмотрим как поведут себя строчные элементы (inline).

Для наглядности в первом абзаце оставим элементы <span> как есть, но выделим их рамкой.
index.html
<!DOCTYPE HTML>
<html>
   <head>
      <meta charset="utf-8">
      <title>Блочные и сточные внешние элементы</title>
      <link href="style.css" rel="stylesheet">
   </head>
   <body>
      <p>Я параграф. У меня некоторые <span>слова</span> заключены в <span>строчный элемент span.</span></p> 
   <p class="inline">Я параграф или, по другому, абзац.</p>
   <p class="inline">Я еще один коротенький абзац.</p>
   </body>
</html>
style.css
p
{
  border: 2px solid purple;
  padding: 10px;
}

span
{
  border: 2px solid blue;
}
Сейчас вы видите, что второй и третий абзац по умолчанию ведут себя как блочные элементы - есть перенос строки. Зададим этим абзацам свойство display:inline и сделаем их строчными.
index.html
<!DOCTYPE HTML>
<html>
   <head>
      <meta charset="utf-8">
      <title>Блочные и сточные внешние элементы</title>
      <link href="style.css" rel="stylesheet">
   </head>
   <body>
      <p>Я параграф. У меня некоторые <span>слова</span> заключены в <span>строчный элемент span.</span></p> 
      <p class="inline">Я параграф или, по другому, абзац.</p>
      <p class="inline">Я еще один коротенький абзац.</p>
   </body>
</html>
style.css
p
{
  border: 2px solid purple;
  padding: 10px;
}

span
{
  border: 2px solid blue;
}

.inline 
{
  display: inline;
}
2 и 3-й абзацы теперь располагаются вместе на одной строке, а не начинаются каждый с новой строки, как они отображались будучи блочными элементами.
Что такое блочная модель?
Теперь полностью перейдем к понятию блочной модели.
Полностью блочная модель в CSS применяется к блочным элементам, строчные элементы используют не все свойства, определённые блочной моделью.

Модель определяет, как разные части элемента — поля, рамки, отступы и содержимое — работают вместе, чтобы создать объект, который вы можете увидеть на странице. Дополнительная сложность заключается в том, что существуют стандартная и альтернативная блочные модели.
Из чего состоит блочная модель в CSS

  • Содержимое: область, где отображается ваш контент, размер которой можно изменить с помощью таких свойств, как width и height.
  • Внутренний отступ: отступы располагаются вокруг содержимого в виде пустого пространства; их размер контролируется с помощью padding и связанных свойств.
  • Рамка: рамка оборачивает содержимое и внутренние отступы. Её размер и стиль можно контролировать с помощью border и связанных свойств.
  • Внешний отступ: внешний слой, заключающий в себе содержимое, внутренний отступ и рамки, представляет собой пространство между текущим и другими элементами. Его размер контролируется с помощью margin и связанных свойств.

Про все свойства мы поговорим чуть позже, в этом же уроке.
Блочная модель CSS
Стандартная блочная модель CSS
В стандартной блочной модели, если указать элементу атрибуты width и height, это определит ширину и высоту содержимого. Любые отступы и рамки затем добавляются к этой ширине и высоте для получения общего размера элемента. Это показано на изображении ниже.

Предположим, что в элементе есть следующий CSS определяющий width, height, margin, border, и padding:
.elem 
{
    width: 350px;
    height: 150px;
    margin: 10px;
    padding: 25px;
    border: 5px solid black;
}
Пространство, занимаемое этим объектом с использованием стандартной блочной модели, на самом деле будет равно 410px в ширину и 210px в высоту, поскольку внутренние отступы и рамки добавляются к размерам поля содержимого.

Ширина:
350px ширина блока + 25px внутреннего отступа сверху (padding) + 25px внутреннего отступа снизу + 5px рамка сверху (border) + 5px рамка снизу => 350 + 25 + 25 + 5 + 5 = 410

Высота:
150 высота блока + 25px внутреннего отступа справа + 25px внутреннего отступа слева + 5px рамка справа + 5px рамка слева => 150 + 25 + 25 + 5 + 5 = 210
Внешний отступ (margin) не считается в фактическом размере объекта.
Конечно, он влияет на общее пространство, занимаемое объектом на странице, но только на внешнюю часть. Область элемента заканчивается на рамке — она не распространяется за нее.
Альтернативная блочная модель CSS
Вы можете подумать, что довольно неудобно добавлять рамки и отступы, чтобы получить реальный размер элемента, и окажетесь правы! По этой причине, спустя некоторое время после стандартной блочной модели, в CSS была введена альтернативная блочная модель.

При использовании альтернативной модели любая ширина — это ширина видимой части элемента на странице, поэтому ширина области содержимого будет равна общей ширине минус ширина рамки и внутреннего отступа.

Грубо говоря, в альтернативной модели опускаются

Тот же пример CSS, который использовался выше, даст следующий результат:
Ширина => 410px фактическое занимаемое пространство - 50px внутренние отступы сверху и снизу - 10px рамка сверху и снизу = 410-50-10 = 350px - теперь это фактический размер.
Тоже самое с высотой, она будет равна 150px.
По умолчанию браузеры используют стандартную блочную модель.

Чтобы использовать альтернативную блочную модель для элемента, укажите для него свойство box-sizing: border-box.
С помощью него вы говорите браузеру о том, что рамка элемента определяется любыми размерами, которые вы устанавливаете.
Если вы хотите, чтобы все ваши элементы использовали альтернативную блочную модель, установите свойство box-sizing для элемента <html>, затем задайте всем элементам наследование этого значения (inherit), как показано в примере ниже.
html 
{
    box-sizing: border-box;
}

*, *::before, *::after
{
    box-sizing: inherit;
}
Рассмотрим разницу на примере. Хорошо изучите css-файл и подумайте почему параметры заданы именно так.
index.html
<!DOCTYPE HTML>
<html>
   <head>
      <meta charset="utf-8">
      <title>Блочные и сточные внешние элементы</title>
      <link href="style.css" rel="stylesheet">
   </head>
   <body>
      <div class="box">Я использую стандартную модель.</div>
      <div class="box alternate">Я использую альтернативную модель.</div>
   </body>
</html>
style.css
.box 
{
    color: #093986;
    border: 5px solid #093986;
    background-color: #79A3E7;
    padding: 40px;
    margin: 40px;
    width: 300px;
    height: 150px;
}

.alternate
{
    box-sizing: border-box;
    width: 390px;
    height: 240px;
}
 
Внешние отступы, внутренние отступы и рамки
Вы уже видели как работают свойства margin, padding и border в приведённом выше примере. Используемые в этом примере свойства — сокращённые и позволяют нам устанавливать все четыре стороны блока одновременно. У них также есть эквивалентные полные свойства, которые позволяют индивидуально управлять разными сторонами блока.

Рассмотрим каждое свойство более подробно.
CSS: Рамки (borders)
Любой блочный элемент в HTML можно выделать с помощью рамок. Такой стилистический приём позволяет удобно отделить однотонные компоненты друг от друга, или выделить ключевой элемент на странице.

Если вы используете стандартную блочную модель, размер рамки прибавляется к значениям width и height элемента.
Если вы используете альтернативную блочную модель, то размер рамки уменьшает поле контента своего блока, так как значения рамки входят в заданные ему width и height.

Для создания границы у элемента используется свойство border.

Для создания индивидуальных свойств каждой из четырёх сторон, используются:
  • border-top - верхняя граница
  • border-right - правая граница
  • border-bottom - нижняя граница
  • border-left - левая граница

Для установки ширины, стиля или цвета всех рамок:
  • border-width — ширина границы
  • border-style — стиль границы
  • border-color — цвет границы
Также можно установить ширину, стиль или цвет для каждой рамки индивидуально, указав нужную границу и необходимое к ней свойство, например:
  • border-top-width
  • border-top-style
  • border-top-color и т.д.

Можно указывать несколько свойств, а можно всё объединить в рамках свойства border. Такой вариант встречается чаще всего и выглядит он так:
.element 
{
    border: 1px solid #FF7373;
}

/*
где:
1px — ширина границы
solid — стиль границы
#FF7373 — цвет границы
*/
В CSS существует 9 стилей границ:
  • none - удаляет границу
  • dotted - линия в виде точек
  • dashed - линия в виде тире
  • solid - сплошная линия
  • double - двойная линия
  • groove - выпуклая линия
  • ridge - выпуклая линия, противоположность groove
  • inset - рамка с тенью с одной стороны
  • outset - противоположность inset, тень с другой стороны
Посмотреть как они выглядят можно ниже.
Дополнительно для рамок
У рамок можно скруглять уголки у границ и фона. Для этого следует применять свойство border-radius.
В качестве значения ему можно задавать как пиксели, так и проценты.
Если задавать значения в %, то можно получить овал.
Приведём пример:
.box1 
{
    border: 5px solid #FF7373;
    border-radius: 50px;
    padding: 20px;
    margin-bottom: 30px;
}

.box2
{
    border: 5px solid #FF7373;
    border-radius: 50%;
    padding: 20px;
}
CSS: Внутренние отступы (padding)
Рассматривая различные блоки, которые были созданы на протяжении всех уроков можно заметить, что текст «прилипает» к краям блоков. Например:
Поэтому внутренний отступ обычно используется, чтобы отодвинуть контент от рамок.

Для создания внутренних индивидуальных отступов используется 4 правила:

  • padding-top — внутренний отступ сверху
  • padding-right — внутренний отступ справа
  • padding-bottom — внутренний отступ снизу
  • padding-left — внутренний отступ слева
Каждое свойство принимает числовое значение и единицу измерения, например пиксели.

Используя свойство padding без задания отельной границы, вы применяете свойство ко всем границам элемента сразу.
Такое свойство называется сокращённое свойство, т.к. является сокращением от уже известных свойств и позволяет установить:
  • отступ сверху
  • отступ справа
  • отступ снизу
  • отступ слева
Порядок указания важен и соответствует тому, как он указан выше.

Посмотрите на то, как заданы отступы в примере ниже.
Свойства padding-top, padding-bottom, padding-right и padding-left по 20px делают тоже самое, что и один padding:20px.
box3 при этом делает тоже самое, что и первые два, только в сокращенном варианте.
.box1 
{
    color: white;
    background-color: #006900;
    padding: 20px;
    margin-bottom: 20px;
}

.box2
{
    color: white;
    background-color: #006900;
    padding-top: 20px;
    padding-right: 20px;
    padding-bottom: 20px;
    padding-left: 20px;
    margin-bottom: 20px;
}

.box3
{
    color: white;
    background-color: #006900;
    padding: 20px 20px 20px 20px;
}
Помимо такой записи для удобства существуют сокращённые записи этих правил:
  • Если указать только одно значение, то оно будет использовано одновременно для всех сторон.
  • Если указать два значения, то первое будет использоваться для отступов по вертикали (сверху и снизу), а второе по горизонтали (справа и слева).
  • Если указать три значения, то они будут использоваться для отступа сверху, по горизонтали и снизу.
В padding нельзя использовать отрицательные значения: они должны быть положительными или равными 0.
CSS: Внешние отступы (margin)
Внутренние отступы позволяли добавить «воздуха» в блок и дать пространство между границей блока и его контентом. А внешние отступы не дают двум соседним блокам прижиматься друг к другу.
Посмотрите как выглядят два блока без внешнего отступа(margin).
Для создания внешних индивидуальных отступов используется 4 правила:

  • margin-top — внешний отступ сверху
  • margin-right — внешний отступ справа
  • margin-bottom — внешний отступ снизу
  • margin-left — внешний отступ слева
Для объединения значений используют свойство margin, в котором сохраняется порядок указания:
  • отступ сверху
  • отступ справа
  • отступ снизу
  • отступ слева
Сокращенные правила записи такие же как и у внутренних отступов.
Схлопывание внешних отступов
Ключевой момент, который нужно понимать в отношении внешних отступов (margin), это концепция схлопывания. Если у вас есть два элемента, внешние отступы которых соприкасаются, и оба значения margin положительные, то эти значения будут объединены в одно, равное большему из двух значений. А если одно или оба значения отрицательны, то сумма отрицательных значений будет вычтена из общей суммы.

В примере ниже есть два абзаца.
Первому абзацу задан margin-bottom 50 пикселей.
У второго абзаца margin-top 30 пикселей.
Отступы схлопываются так, что в результате margin между двумя блоками составляет 50 пикселей, а не сумму отдельных значений margin.
html
<div class="container">
  <p class="box1">Я параграф.</p>
  <p class="box2">Я тоже параграф.</p>
</div>
    
css
.container
{
    border: 5px solid #A60000;
    padding: 20px;
    margin: 20px;
}

.box1 
{
    border: 5px solid #FF7373;
    padding: 20px;
    margin-bottom: 30px;
}

.box2
{
    border: 5px solid #FF7373;
    padding: 20px;
    margin-top: 30px;
}
Вы сами можете проверить это.
Скопируйте выше код и установите второму абзацу margin-top: 0px;
Видимое расстояние между абзацами не изменилось - отступ остается равный 50px, заданный в margin-bottom первого абзаца.

Теперь установите значение margin-top: -20px.
Теперь видимое расстояние стало 30px - произошло вычитание из положительного значения 50px из первого абзаца.

Попробуйте еще поиграть со значениями и посмотреть, что будет происходить с отступами.
Внешний отступ может быть как положительным, так и отрицательным. Негативное значение может привести к перекрытию некоторых элементов страницы.

Независимо от того, используете ли вы стандартную или альтернативную блочную модель, внешний отступ всегда добавляется после расчёта размера видимого блока.
Дополнительно

Свойство margin применяется не только для задания отступов, но и для центрирования блочных элементов.
Для этого правый и левый отступ следует задать в значение auto.

В примере ниже внутренний блок станет по центру:
html
<div class="parent">
	<div class="child"></div>
</div>
css
.parent 
{
   border: 1px solid red;
}

.child 
{
   height: 100px;
   width: 200px;
   border: 1px solid green;
   margin: 10px auto;
}
Имейте ввиду, что таким образом можно центрировать только блочные элементы, только по горизонтали и только, если им задана ширина.

Если нам нужны разные верхний и нижний отступ margin, то можно написать вот так:
css
.child 
{
    margin: 30px auto 10px auto;
}

/*
Можно переписать и через три значения: первое задаст верхний отступ, третье - нижний, а второе задаст значение auto для правого и левого отступов:
*/

.child 
{
    margin: 30px auto 10px;
}
Значение auto для margin на самом деле может не только центрировать. Фактически это значение позволяет рассчитать отступ автоматически и сделать его максимально возможным. Когда мы ставим auto для левого и правого отступа - элемент центрируется.

Можно поставить только левый отступ.
В этом случае элемент получит максимально возможный отступ слева и займет крайнее правое положение:
html
<div class="parent">
	<div class="child"></div>
</div>
css
.parent 
{
   padding: 10px 0;
   border: 1px solid red;
}

.child
{
   margin-left: auto; /* задаем автоматический левый отступ */
   height: 100px;
   width: 200px;
   border: 1px solid green;
}
При необходимости можно задать и правый отступ и элемент не будет прижат вплотную к правой границе, а отступит от нее:
css
.parent
{
   padding: 10px 0;
   border: 1px solid red;
}

.child 
{
   margin-left: auto;
   margin-right: 20px; /* задаем правый отступ */
   height: 100px;
   width: 200px;
   border: 1px solid green;
}
Блочная модель и строчные элементы
Все сказанное ранее полностью применимо к блочным элементам.
Некоторые из свойств могут быть также применены и к строчным (inline) элементам, например к <span>.

На примере рассмотрим как поведут себя строчные элементы с теми же свойствами, что и блочные.
Допустим у нас есть элемент <span> внутри div. К нему мы применим свойства width, height, margin, border и padding.
html
<div class='box1'>При работе с <span>CSS</span> используют не только оформление текстов, но и оформление блоков. 
В этом модуле вы изучите, как добавлять внутренние и внешние отступы и границы. 
Узнаете о том, что такое блочная модель и как свойства влияют на конечные размеры элемента :)</div>
css
span 
{
    margin: 20px;
    padding: 20px;
    width: 80px;
    height: 50px;
    background-color: #FFB2B2;
    border: 2px solid #A60000;
}

.box1 
{
    border: 2px solid #FF7373;
    padding: 20px;
    margin-bottom: 30px;
}
Вы можете видеть, что ширина и высота игнорируются.
Вертикальные внешние и внутренние отступы и рамки применены, но они не изменяют положение других элементов относительно строчного элемента, и поэтому отступы и рамка перекрывают другие слова в абзаце.
Горизонтальные внешние и внутренние отступы и рамки применены и заставляют другие элементы отодвинуться от нашего.


Можно ли что-то с этим сделать?
Да, можно! С помощью элемента display: inline-block

Существует особое значение display, которое представляет собой золотую середину между inline и block.
Оно полезно в ситуациях, когда вы не хотите, чтобы элемент переносился на новую строку, но нужно, чтобы он применял width и height и избегал перекрытия, показанного выше.

Элемент с display: inline-block применяет ряд свойств блочного элемента, о которых мы уже знаем:

  • Применяются свойства width и height.
  • Использование padding, margin и border приведёт к тому, что другие элементы будут отодвинуты от нашего элемента.
Он не перенесётся на новую строку и станет больше, чем его содержимое, только если вы явно зададите свойства width и height.

Добавим свойство display: inline-block к нашему элементу <span> из примера выше.
html
<div class='box1'>При работе с <span>CSS</span> используют не только оформление текстов, но и оформление блоков. 
В этом модуле вы изучите, как добавлять внутренние и внешние отступы и границы. 
Узнаете о том, что такое блочная модель и как свойства влияют на конечные размеры элемента :)</div>
css
span 
{
    display: inline-block;
    margin: 20px;
    padding: 20px;
    width: 80px;
    height: 50px;
    background-color: #FFB2B2;
    border: 2px solid #A60000;
}

.box1 
{
    border: 2px solid #FF7373;
    padding: 20px;
    margin-bottom: 30px;
}
Попробуйте изменить значение свойства на display: block или полностью удалить строку, чтобы увидеть разницу. Попробуйте также поиграть с отступами и рамкой.
Если расположить несколько строчно-блочных элементов рядом, то они выстроятся в ряд, подобно строчным элементам:
html
<div class='box1'>При работе с <span>CSS</span> <span>используют</span> <span>не только</span> <span>оформление</span> <span>текстов</span>, но и оформление блоков. 
В этом модуле вы изучите, как добавлять внутренние и внешние отступы и границы. 
Узнаете о том, что такое блочная модель и как свойства влияют на конечные размеры элемента :)</div>
css
span 
{
   display: inline-block;
   width: 100px;
   height: 20px;
   margin-bottom: 20px;
   background-color: #FFB2B2;
   border: 2px solid #A60000;
}

.box1 
{
   border: 2px solid #FF7373;
   padding: 20px;
   margin-bottom: 30px;
}
Практика
1. Пирамида
Повтори страницу по образцу, сделав так, чтобы зеленые блоки располагались по центру своего родителя.
    2. Много рамок
    Повтори страницу по образцу.
      3. Меню
      Пробуем делать меню сайта.
      Вспоминаем семантику сайта, используй списки и особый тег для навигации по сайту.

      Подсказка: чтобы поставить меню по центру, обрати внимание, что внутри блока текст и работать нужно с ним.

      Особая подсказка:
      В CSS для списка к коду добавь:
        list-style: none; /*убираем маркеры списка*/
        margin: 0px; /*убираем верхнее и нижнее поле, равное 1em*/
        padding-left: 0px; /*убираем левый отступ, равный 40px*/
        Для ссылки к коду пропиши:
          text-decoration: none; /*убираем подчеркивание текста ссылок*/
          Если возникнут вопросы - обратись к наставнику.
            4. Меню и основной контент
            К меню, которое получилось в предыдущем задании добавьте основной контент.
            Вспоминаем семантику сайта, в качестве подсказки используй списки и особый тег для навигации по сайту.
              Следующее занятие