Блочная и строчная модель. Часть 1: области блока и отступы

Чтение — около 8 минут· без учёта практики

После предыдущего урока текст сайта стал удобнее читать. Теперь отделим его от краёв блоков. Размещение строчных элементов и меню рассмотрим в следующей части.

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

На веб-странице большинство видимых HTML-элементов создают прямоугольные области — блоки. У элемента с display: none блока нет, а строчный элемент может разбиться на несколько фрагментов при переносе текста. При отрисовке страницы браузер определяет размеры и положение этих блоков и применяет к ним свойства CSS.

Из чего состоит блок и от каких свойств зависят его размеры, описывает блочная модель (англ. box model). В ней каждый блок состоит из четырёх областей:

  • content — содержимое;
  • padding — внутренние отступы;
  • border — рамка (граница) элемента;
  • margin — внешние отступы.

Свойство box-sizing определяет, какие из этих областей входят в заданные width (ширину) и height (высоту):

  • content-box — размеры задаются для содержимого; внутренние отступы и рамка прибавляются к ним. Это начальное значение свойства, показанное на схеме ниже.
  • border-box — размеры включают содержимое, внутренние отступы и рамку. Чем больше отступы и рамка, тем меньше места остаётся для содержимого.

Внешние отступы margin в заданные размеры не входят при обоих значениях. Например, при width: 200px и padding: 20px без рамки ширина элемента с внутренними отступами составит 240px для content-box и 200px для border-box.

Блочная модель CSS: содержимое окружено внутренними отступами, рамкой и внешними отступами.

Разберём подробнее каждую из четырёх областей блока.

Область содержимого (content area) содержит текст, изображения и вложенные элементы. Её размер задают свойства width (ширина), min-width (минимальная ширина), max-width (максимальная ширина), height (высота), min-height (минимальная высота) и max-height (максимальная высота). При box-sizing: content-box они задают размер именно содержимого, без отступов и рамки. Подробнее расчёт размеров при обоих значениях box-sizing рассмотрим в уроке «Размеры блочных элементов».

Внутренние отступы, или поля элемента (padding area), — пустая область вокруг содержимого. Её размер можно задать для всех сторон сразу или для каждой стороны отдельно. Фон элемента виден и под содержимым, и под внутренними отступами.

Рамка (border area) окружает внутренние отступы. Её толщину, цвет и стиль тоже задают для всех сторон или по отдельности — подробно в следующем уроке.

Внешние отступы (margin area) добавляют пустое пространство вокруг рамки и задают расстояние до соседних элементов. Они всегда прозрачны: фон элемента под ними не виден.

Внешние и внутренние отступы

Отступами управляют два свойства: margin — внешние отступы и padding — внутренние. Зададим одной фотографии Тони внешние отступы, а другой — внутренние. Пока у фотографий нет рамки и фона, разница не видна: обе просто отодвигаются от соседей. Поэтому сразу добавим рамку и фон:

Внешние и внутренние отступы: попробуйте сами

У первой картинки отступ снаружи рамки — в нём виден фон страницы. У второй отступ внутри рамки и закрашен фоном khaki. Через прозрачные участки самих картинок фон khaki виден в обоих случаях. Удалите border и background-color у img — картинки будут выглядеть одинаково.

index.html
HTML
<!doctype html>
<html lang="ru">
  <head>
    <meta charset="utf-8">
    <title>Внешние и внутренние отступы</title>
    <style>
      img {
        width: 150px; /* ширина изображения */
        height: auto; /* высота — по пропорциям */
        border: 3px solid orange; /* рамка показывает границу элемента */
        background-color: khaki; /* фон виден под содержимым и внутренними отступами */
      }
      .margin {
        margin: 30px; /* внешние отступы со всех сторон */
      }
      .padding {
        padding: 30px; /* внутренние отступы со всех сторон */
      }
    </style>
  </head>
  <body>
    <img src="assets/tony-toy.png" alt="Тони с канатом" width="300" height="400" class="margin">
    <img src="assets/tony-toy.png" alt="Тони с канатом" width="300" height="400" class="padding">
  </body>
</html>

Внутренний отступ добавляет промежуток между содержимым и рамкой элемента, а внешний — пустое пространство снаружи рамки, до соседних элементов. Поэтому только у второй картинки вокруг изображения есть дополнительная полоса фона khaki шириной 30px внутри рамки. Сам фон задан обеим картинкам и виден через прозрачные участки изображения Тони.

Для отступов подходят любые единицы длины CSS, которые мы разобрали в уроке «Единицы измерения». Удобно задавать их в rem — тогда отступы растут вместе с настройкой шрифта — или в em, если отступ должен зависеть от размера шрифта самого элемента.

Отступы с отдельных сторон

Свойства margin и padding задают отступы со всех сторон. Для каждой стороны есть отдельное свойство: к названию через дефис добавляется сторона.

Внутренние отступы:

Внешние отступы:

В CSS есть и логические свойства, которые задают отступы относительно направления письма: margin-inline и padding-inline — в начале и в конце строки, margin-block и padding-block — до и после блока по направлению расположения строк. При горизонтальном письме inline соответствует левой и правой сторонам, а block — верхней и нижней. При вертикальном письме эти оси меняются местами.

Логические свойства удобны для разных направлений письма. Например, margin-inline-start задаёт отступ в начале строки: слева для русского текста и справа для арабского. При этом переход к письму справа налево не меняет верх и низ: margin-block и padding-block по-прежнему задают отступы сверху и снизу, пока строки горизонтальные. В учебнике мы используем привычные стороны.

Отступы в процентах

Отступы можно задавать в процентах. Зададим двум фотографиям ширину и отступ слева в процентах:

Отступы в процентах: попробуйте сами

Ширина фотографий и отступы слева считаются от ширины body. Измените ширину окна — изменятся и фотографии, и отступы между ними.

index.html
HTML
<!doctype html>
<html lang="ru">
  <head>
    <meta charset="utf-8">
    <title>Отступы в процентах</title>
    <style>
      img {
        width: 25%; /* 25% ширины родителя */
        height: auto;
        margin-left: 15%; /* 15% ширины родителя, а не высоты */
      }
    </style>
  </head>
  <body>
    <img src="assets/tony-toy.png" alt="Тони с канатом" width="300" height="400">
    <img src="assets/tony-toy.png" alt="Тони с канатом" width="300" height="400">
  </body>
</html>

Проценты отступов браузер считает от ширины родительского блока, в котором находятся изображения, — здесь это <body>. Если его ширина 700 пикселей, отступ слева у каждого изображения составит:

Ширина изображения считается так же:

При изменении ширины окна меняются и изображения, и отступы. Высоту браузер вычисляет сам: у неё значение по умолчанию auto, и фотографии сохраняют пропорции. Важная особенность: вертикальные отступы в процентах тоже считаются от ширины родителя, а не от его высоты.

Сокращённая запись

Свойства margin и padding — сокращённые: в одном объявлении можно задать разные отступы для всех четырёх сторон. Важно соблюдать порядок значений. Рассмотрим его на внутренних отступах:

CSS
padding: 5px 10px 15px 20px;

Четыре значения расставляются по часовой стрелке, начиная сверху: сверху (5px) — справа (10px) — снизу (15px) — слева (20px). Чтобы запомнить порядок, используют английское слово TRouBLe: T — top, R — right, B — bottom, L — left.

CSS
padding: 5px 10px 15px;

Три значения: сверху (5px) — слева и справа (10px) — снизу (15px).

CSS
padding: 5px 10px;

Два значения: первое (5px) — сверху и снизу, второе (10px) — слева и справа.

CSS
padding: 5px;

Одно значение: одинаковый отступ со всех сторон — 5px.

Одно значение padding задаёт все стороны; два — вертикальные и горизонтальные; три — верх, боковые стороны, низ; четыре — верх, право, низ, лево. У margin тот же порядок.
Памятка: как значения сокращённого свойства распределяются по сторонам.

Для нулевого отступа единицу измерения можно не указывать. Например, слева и справа — 1em, сверху и снизу отступа нет:

CSS
padding: 0 1em;

Для внешних отступов (margin) порядок значений тот же. Рассмотрим пример:

Сокращённая запись margin: попробуйте сами

У заголовка отступы сверху 15px, слева и справа по 20% ширины, снизу 2em. Синий квадрат с отрицательным отступом сверху наезжает на зелёный. Замените -40px на 0 — квадрат опустится.

index.html
HTML
<!doctype html>
<html lang="ru">
  <head>
    <meta charset="utf-8">
    <title>Сокращённая запись margin</title>
    <style>
      h1 {
        margin: 15px 20% 2em; /* сверху 15px, слева и справа 20%, снизу 2em */
        background-color: linen; /* фон показывает ширину заголовка */
      }
      .one,
      .two,
      .three {
        width: 50px;
        height: 50px;
      }
      .one {
        background-color: yellow;
        margin: 2em; /* одинаковый отступ со всех сторон */
      }
      .two {
        background-color: lime;
        margin: 25px 75px; /* сверху и снизу 25px, слева и справа 75px */
      }
      .three {
        background-color: blue;
        margin: -40px 25px 25px 100px; /* сверху -40px: блок наезжает на предыдущий */
      }
    </style>
  </head>
  <body>
    <h1>Привет! Меня зовут Тони</h1>
    <div class="one"></div>
    <div class="two"></div>
    <div class="three"></div>
  </body>
</html>

  • Групповым селектором всем трём блокам заданы ширина и высота 50px.
  • У заголовка отступы сверху (15px), слева и справа (20%) и снизу (2em). Фон показывает, что заголовок стал уже.
  • Блоку .one заданы одинаковые отступы 2em со всех сторон.
  • Блоку .two — 25px сверху и снизу, 75px слева и справа.
  • Блоку .three — сверху -40px, справа и снизу 25px, слева 100px. Отрицательный отступ сверху сдвинул блок вверх, и он наложился на предыдущий.

Схлопывание внешних отступов

В обычном потоке браузер располагает блочные элементы друг под другом в порядке HTML-кода — например, два соседних абзаца <p>. Здесь мы рассматриваем именно такое расположение, без специальных способов размещения элементов, которые будем изучать дальше. Вертикальные внешние отступы соседних блоков в таком потоке могут схлопываться (англ. margin collapsing): если оба отступа неотрицательные, между блоками остаётся больший из двух.

Схлопывание отступов: попробуйте сами

У первого абзаца отступ снизу 10px, у второго сверху 20px, но расстояние между ними 20px, а не 30px. Увеличьте margin-bottom до 40px — расстояние станет 40px.

index.html
HTML
<!doctype html>
<html lang="ru">
  <head>
    <meta charset="utf-8">
    <title>Схлопывание вертикальных отступов</title>
    <style>
      p {
        background-color: linen; /* фон показывает границы абзацев */
      }
      .first {
        margin-bottom: 10px; /* отступ снизу 10px */
      }
      .second {
        margin-top: 20px; /* отступ сверху 20px */
      }
    </style>
  </head>
  <body>
    <p class="first">Я маленький, но смелый, гуляю целый день.</p>
    <p class="second">А вечером на кресле сплю — и мне не лень.</p>
  </body>
</html>

Соседние абзацы в обычном блочном потоке: margin-bottom 10px первого и margin-top 20px второго схлопываются в общий промежуток 20px.
При схлопывании двух положительных отступов остаётся больший.

Казалось бы, расстояние между абзацами должно быть 30px (10px снизу у первого плюс 20px сверху у второго), а на деле оно 20px — браузер выбрал больший отступ. Обязательно учитывайте это при вёрстке. Отступ 16px снизу у второго абзаца задан стилями браузера: по умолчанию у абзацев внешние отступы сверху и снизу равны 1em.

Если один отступ отрицательный, он вычитается из положительного: 30px и -20px дают 10px. Если оба отрицательные, остаётся отступ с большим модулем: -10px и -20px дают -20px. Попробуйте эти значения в примере выше.

Отступ может схлопываться и у вложенных элементов: если у обычного блочного родителя нет внутреннего отступа, рамки и строчного содержимого сверху, отступ первого вложенного элемента «выходит» за пределы родителя.

Отступ заголовка выходит за родителя: попробуйте сами

Отступ заголовка оказался над фоном вводного блока, а не внутри него. Добавьте блоку .intro правило padding: 1rem; — отступ заголовка окажется внутри блока, и фон начнётся у края окна.

index.html
HTML
<!doctype html>
<html lang="ru">
  <head>
    <meta charset="utf-8">
    <title>Отступ заголовка выходит за родителя</title>
    <style>
      body {
        margin: 0;
      }
      .intro {
        background-color: hsl(30, 80%, 95%); /* фон вводного блока */
      }
      h1 {
        margin-top: 40px; /* отступ заголовка сверху */
      }
    </style>
  </head>
  <body>
    <div class="intro">
      <h1>Привет! Меня зовут Тони</h1>
      <p>Я карликовый пинчер.</p>
    </div>
  </body>
</html>

В обычном горизонтальном письме схлопываются вертикальные внешние отступы блоков; горизонтальные отступы и отступы строчных элементов не схлопываются. Чтобы отделить отступ первого ребёнка от верхнего края родителя, задайте родителю ненулевой padding-top или верхнюю рамку. Это не отменяет схлопывание отступов между соседними блоками внутри родителя.

Блочная модель в инструментах разработчика

Размеры каждой области блока показывает вкладка Computed в инструментах разработчика Google Chrome, знакомая по уроку «Инструменты разработчика». Вверху вкладки — схема блочной модели выбранного элемента: в центре размер содержимого, вокруг — значения padding, border и margin с каждой стороны. При наведении на элемент на вкладке Elements браузер подсвечивает на странице содержимое, внутренние и внешние отступы разными цветами. Так проще всего найти, откуда взялся лишний промежуток.

Потренируйтесь

Меняйте внутренний и внешний отступы и толщину рамки блока и следите, как меняются его размеры: размер содержимого, размер с рамкой и место, которое блок занимает вместе с внешними отступами. Переключите box-sizing с content-box на border-box: внутренние отступы и рамка войдут в заданные размеры, а область содержимого уменьшится. Проследите, как меняются размер содержимого и размер блока с рамкой.

Блок в натуральном размере

Содержимое
  • Содержимое
  • Padding
  • Border
  • Margin
Содержимое
240 × 120 px
С рамкой
288 × 168 px
С внешними отступами
320 × 200 px
Параметры блока

Справочник свойств
HTML и CSS текущего блока
CSS
.box {
  box-sizing: content-box;
  width: 240px;
  height: 120px;
  padding: 20px;
  border: 4px solid #487a9a;
  margin: 16px;
}
HTML
<div class="box">Содержимое</div>

Задания на блочную модель и box-sizing — в тренажёре размеров

Проверьте себя

Выберите ответ — объяснение появится сразу. Ответ можно менять.

1. У двух соседних обычных блоков схлопываются отступы: снизу у первого 30px, сверху у второго −20px. Каков итоговый отступ?
Показать ответ

10px — Отрицательный отступ вычитается из положительного: 30 − 20 = 10px.

2. В каком порядке от содержимого наружу расположены области блока?
Показать ответ

content → padding → border → margin — Содержимое окружают внутренние отступы, их — рамка, а снаружи рамки — внешние отступы.

3. Элементу заданы фон и margin: 20px. Виден ли фон в области внешнего отступа?
Показать ответ

Нет, внешний отступ всегда прозрачен — Фон элемента виден под содержимым и внутренними отступами. Внешний отступ — пустое место снаружи рамки.

4. Как расставятся отступы при padding: 5px 10px 15px?
Показать ответ

Сверху 5px, слева и справа 10px, снизу 15px — Три значения: первое — сверху, второе — слева и справа, третье — снизу.

5. Какое объявление ошибочно?
Показать ответ

padding: -10px; — Внутренний отступ не может быть отрицательным, браузер пропустит такое объявление.

6. Ширина родителя 600px, высота 300px. Элементу задано margin-top: 10%. Каков отступ сверху?
Показать ответ

60px — Проценты отступов считаются от ширины родителя — даже для отступов сверху и снизу.

7. У первого абзаца margin-bottom: 30px, у следующего под ним — margin-top: 20px. Каково расстояние между ними?
Показать ответ

30px — Вертикальные внешние отступы соседних блоков схлопываются: остаётся больший из них.

8. Отступ сверху у заголовка внутри блока с фоном оказался над фоном, а не внутри. Как это исправить?
Показать ответ

Задать блоку внутренний отступ padding — Отступ вложенного элемента выходит за родителя, только если между ними нет внутреннего отступа или рамки.

Задание

В css/style.css задайте body { margin: 0; }, main { padding: 1.5rem 1rem; }, добавьте padding: 1.5rem к .intro и padding: 1rem к footer. Существующие объявления сохраните.

Ожидаемый результат: шапка и подвал занимают всю ширину окна, текст отступает от краёв, а фон вводного блока окружает заголовок вместе с его отступами. Меню пока остаётся вертикальным.

Выполните задание

css/style.css
CSS
/* Общие стили сайта Тони */

/* Шрифт заголовков Nunito (лицензия SIL Open Font License): кириллица и латиница в разных файлах */
@font-face {
  font-family: "Nunito";
  src: url("../assets/nunito-cyrillic-800-normal.woff2") format("woff2");
  font-weight: 800;
  font-display: swap; /* пока шрифт загружается, текст виден запасным шрифтом */
  unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}

@font-face {
  font-family: "Nunito";
  src: url("../assets/nunito-latin-800-normal.woff2") format("woff2");
  font-weight: 800;
  font-display: swap;
  unicode-range: U+0000-00FF, U+2000-206F, U+20AC, U+2122;
}

body {
  background-color: linen;
  color: #2b211b; /* цвет для потомков без собственного значения */
  font-size: 1.0625rem; /* 17px при настройке браузера по умолчанию */
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif; /* системный шрифт устройства */
  line-height: 1.6; /* множитель: у каждого элемента интервал от его собственного размера шрифта */
}

/* Общий цвет заголовков — групповой селектор */
h1,
h2 {
  color: saddlebrown;
  font-family: "Nunito", "Trebuchet MS", system-ui, sans-serif;
  font-weight: 800;
  line-height: 1.2; /* крупному тексту хватает меньшего интервала */
}

/* Размеры заголовков в rem — от размера шрифта корня, а не родителя */
h1 {
  text-align: center;
  font-size: 2.5rem;
}

h2 {
  font-size: 1.75rem;
}

/* Вводный блок главной страницы */
.intro {
  background-color: hsl(30, 80%, 95%);
}

/* Ширина вводных абзацев ограничена 60ch; количество букв в строке зависит от шрифта и текста */
.intro p {
  max-width: 60ch;
}

/* Важное предупреждение во вводном блоке — темнее основного акцента */
.intro strong {
  color: #6e3510;
}

/* Оглавление главной страницы */
.toc {
  background-color: white;
  border: 1px solid tan;
}

/* Подчёркивание ссылок чуть ниже букв: не задевает выносные элементы */
a {
  text-underline-offset: 3px;
}

/* Ссылки меню в шапке — селектор потомков */
nav a {
  color: saddlebrown;
  text-decoration: none;
}

/* Ссылки оглавления главной страницы */
.toc a {
  color: #6b5d52; /* тёплый серый: контраст 6.34:1 на белом фоне оглавления */
}

figcaption {
  color: #6b5d52; /* тёплый серый: контраст 5.64:1 на фоне linen */
  font-size: 0.95rem;
}

footer {
  background-color: hsl(30, 50%, 90%);
  text-align: center;
}

/* Ссылка в подвале берёт цвет текста подвала */
footer a {
  color: inherit;
}

/* Поля формы получают шрифт страницы вместо шрифта браузера */
input,
select,
textarea,
button {
  font: inherit;
}

/* Ссылки темнеют при наведении указателя */
a:hover {
  color: #5c2d0c;
}

/* Ссылки меню подчёркиваются при наведении и фокусе с клавиатуры */
nav a:hover,
nav a:focus-visible {
  text-decoration: underline;
}

/* Заметная рамка фокуса у ссылок, полей и кнопок при работе с клавиатуры */
:focus-visible {
  outline: 3px solid #1f6feb;
  outline-offset: 3px;
}

/* Цитата из книги — шрифтом с засечками и курсивом */
blockquote {
  font-family: Georgia, "Times New Roman", serif;
  font-style: italic;
}

/* Подпись под цитатой — у правого края */
blockquote + figcaption {
  text-align: right;
}
index.html
HTML
<!doctype html>
<html lang="ru">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="Сайт карликового пинчера Тони: игрушки, режим дня и запись на прогулку.">
    <title>Сайт Тони</title>
    <link rel="stylesheet" href="css/style.css">
  </head>
  <body>
    <header>
      <!-- Меню сайта -->
      <nav>
        <ul>
          <li><a href="index.html">Главная</a></li>
          <li><a href="pages/toys.html">Мои игрушки</a></li>
          <li><a href="pages/signup.html">Запись на прогулку</a></li>
        </ul>
      </nav>
    </header>
    <main>
      <div class="intro">
        <h1 id="top">Привет! Меня зовут Тони</h1>
        <p>Я карликовый пинчер. Мне три года, я вешу 8&nbsp;кг и люблю гулять в любую погоду. Хозяин говорит: <q>Тони — лучший сторож в доме</q>.</p>
        <p>Мой день рождения — <time datetime="2023-09-22">22 сентября</time>. <strong>Пожалуйста, не кормите меня со стола!</strong></p>
        <p>Моя родословная записана в Российской кинологической федерации (<abbr title="Российская кинологическая федерация">РКФ</abbr>).</p>
      </div>
      <ul class="toc">
        <li><a href="#toy">Моя любимая игрушка</a></li>
        <li><a href="#commands">Команды, которые я знаю</a></li>
        <li><a href="#schedule">Мой режим дня</a></li>
        <li><a href="#walks">Где я гуляю</a></li>
        <li><a href="#song">Песня для прогулок</a></li>
      </ul>
      <section>
        <h2 id="toy">Моя любимая игрушка</h2>
        <p data-toy-id="17">Это канат с мячиком. Хозяин бросает его, а я приношу обратно — <em>почти</em> всегда. <a href="pages/toys.html">Посмотреть все игрушки Тони</a>.</p>
        <figure>
          <img src="assets/tony-toy.png" alt="Тони сидит и держит в зубах канат с красным мячиком" width="300" height="400" title="Мой канат &quot;Удав&quot;">
          <figcaption>Я и мой канат «Удав»</figcaption>
        </figure>
        <p><a href="assets/tony-toy.png" download>Скачать фотографию</a></p>
        <p>Подробнее о моей породе — в статье <a href="https://ru.wikipedia.org/wiki/Карликовый_пинчер" target="_blank">«Карликовый пинчер» в Википедии</a>.</p>
        <hr>
        <p>Вечером игра закончилась. Канат остался на полу, а я свернулся калачиком в кресле.</p>
      </section>
      <section>
        <h2>Мой стишок</h2>
        <p>
          Я маленький, но смелый,<br>
          Гуляю целый день,<br>
          А вечером на кресле<br>
          Сплю — и мне не лень.
        </p>
      </section>
      <section>
        <h2 id="commands">Команды, которые я знаю</h2>
        <p>Хозяин научил меня командам на немецком:</p>
        <dl>
          <dt lang="de">Sitz!</dt>
          <dd>сидеть</dd>
          <dt lang="de">Platz!</dt>
          <dd>лежать</dd>
          <dt lang="de">Fuß!</dt>
          <dd>рядом</dd>
        </dl>
        <details>
          <summary>Почему команды на немецком?</summary>
          <p>Карликовый пинчер — немецкая порода, и хозяину понравилась эта традиция.</p>
        </details>
      </section>
      <section>
        <h2 id="schedule">Мой режим дня</h2>
        <table>
          <caption>Режим дня Тони</caption>
          <thead>
            <tr>
              <th scope="col">Время</th>
              <th scope="col">Будни</th>
              <th scope="col">Выходные</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <th scope="row">07:00</th>
              <td>Прогулка, 20 минут</td>
              <td>Сплю</td>
            </tr>
            <tr>
              <th scope="row">08:00</th>
              <td colspan="2">Завтрак</td>
            </tr>
            <tr>
              <th scope="row">13:00</th>
              <td>Жду хозяина и сплю</td>
              <td>Прогулка в парке, 1 час</td>
            </tr>
            <tr>
              <th scope="row">19:00</th>
              <td colspan="2">Ужин</td>
            </tr>
            <tr>
              <th scope="row">21:00</th>
              <td colspan="2">Вечерняя прогулка</td>
            </tr>
          </tbody>
        </table>
      </section>
      <section>
        <h2 id="progress">Мои успехи</h2>
        <p>Учу команду «Апорт»: пройдено 3 занятия из 5. <progress value="3" max="5">3 из 5</progress></p>
        <p>Прогулка сегодня: 40 минут. <meter value="40" min="0" max="90" low="30" high="60" optimum="75">40 из 90 минут</meter></p>
      </section>
      <section>
        <h2 id="walks">Где я гуляю</h2>
        <p>Я люблю гулять в сквере у дома.</p>
        <p>
          <a href="pages/walks.html" target="walk">Маршрут</a> |
          <a href="assets/tony.png" target="walk">Фото с прогулки</a>
        </p>
        <iframe src="pages/walks.html" name="walk" title="Маршрут и фото прогулки Тони" width="320" height="420"></iframe>
        <h3>Видео с прогулки</h3>
        <p>Субтитры помогут, если вы смотрите видео без звука.</p>
        <video width="180" height="320" poster="assets/walk.jpg" controls>
          <source src="assets/walk.mp4" type="video/mp4">
          <track src="assets/ru.vtt" kind="subtitles" srclang="ru" label="Русский" default>
          <p><a href="assets/walk.mp4">Скачать видео</a></p>
        </video>
        <h3>Как я лаю</h3>
        <p>Так я разговариваю с хозяином — у нас целый диалог!</p>
        <audio controls>
          <source src="assets/bark.mp3" type="audio/mpeg">
          <p><a href="assets/bark.mp3">Скачать запись</a></p>
        </audio>
      </section>
      <section>
        <h2 id="song">Песня для прогулок</h2>
        <p>Хозяин включает эту песню, когда мы выходим гулять.</p>
        <iframe width="480" height="270" src="https://www.youtube.com/embed/ojULkWEUsPs?start=17" title="Baha Men — Who Let the Dogs Out" loading="lazy" allow="fullscreen"></iframe>
        <p><a href="https://www.youtube.com/watch?v=ojULkWEUsPs">Baha Men — Who Let the Dogs Out на YouTube</a></p>
      </section>
      <section>
        <h2>Моя любимая книга</h2>
        <p>Хозяин читал мне вслух рассказ <cite>«Каштанка»</cite> Антона Чехова. Он начинается так:</p>
        <figure>
          <blockquote>
            <p>Молодая рыжая собака — помесь таксы с дворняжкой — очень похожая мордой на лисицу, бегала взад и вперёд по тротуару и беспокойно оглядывалась по сторонам.</p>
          </blockquote>
          <figcaption>— Антон Чехов, <cite>«Каштанка»</cite></figcaption>
        </figure>
      </section>
      <p><a href="#top">Наверх</a></p>
    </main>
    <footer>
      <p><small>&copy; 2026 Тони и его хозяин</small></p>
      <address>Написать хозяину Тони: <a href="mailto:tony@example.com">tony@example.com</a></address>
    </footer>
  </body>
</html>
pages/signup.html
HTML
<!doctype html>
<html lang="ru">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="Запишитесь на совместную прогулку с карликовым пинчером Тони.">
    <title>Запись на прогулку с Тони</title>
    <link rel="stylesheet" href="../css/style.css">
  </head>
  <body>
    <header>
      <nav>
        <ul>
          <li><a href="../index.html">Главная</a></li>
          <li><a href="toys.html">Мои игрушки</a></li>
          <li><a href="signup.html">Запись на прогулку</a></li>
        </ul>
      </nav>
    </header>
    <main>
      <h1>Запись на прогулку</h1>
      <p>Гуляйте вместе с Тони! Оставьте заявку, и хозяин Тони напишет вам, чтобы договориться о встрече.</p>
      <p><a href="../index.html#walks">Где мы гуляем</a></p>
      <form>
        <fieldset>
          <legend>О вас</legend>
          <p>
            <label for="owner">Ваше имя</label>
            <input type="text" id="owner" name="owner" autocomplete="name" required>
          </p>
          <p>
            <label for="email">Электронная почта</label>
            <input type="email" id="email" name="email" autocomplete="email" placeholder="anna@example.com" required>
          </p>
        </fieldset>
        <fieldset>
          <legend>Ваша собака</legend>
          <p>
            <label for="breed">Порода</label>
            <input type="text" id="breed" name="breed" list="breeds">
            <datalist id="breeds">
              <option value="Карликовый пинчер"></option>
              <option value="Такса"></option>
              <option value="Йоркширский терьер"></option>
              <option value="Беспородная"></option>
            </datalist>
          </p>
          <p>
            <label for="dogs">Сколько собак придёт</label>
            <input type="number" id="dogs" name="dogs" min="1" max="3" value="1">
          </p>
        </fieldset>
        <fieldset>
          <legend>Когда гулять</legend>
          <p>
            <label for="date">Дата</label>
            <input type="date" id="date" name="date" required>
          </p>
          <label><input type="radio" name="time" value="morning" checked> Утром</label>
          <label><input type="radio" name="time" value="evening"> Вечером</label>
        </fieldset>
        <fieldset>
          <legend>Прогулка</legend>
          <p>
            <label for="leader">Ведёт прогулку</label>
            <input type="text" id="leader" name="leader" value="Тони" readonly>
          </p>
          <p>
            <label for="route">Маршрут</label>
            <select id="route" name="route">
              <optgroup label="В городе">
                <option value="square">Сквер у дома</option>
                <option value="pond" selected>Пруд с утками</option>
              </optgroup>
              <optgroup label="За городом">
                <option value="forest">Лес</option>
                <option value="river" disabled>Берег реки — закрыт до весны</option>
              </optgroup>
            </select>
          </p>
          <p>
            <label for="wishes">Пожелания</label><br>
            <textarea id="wishes" name="wishes" rows="4" cols="40" maxlength="300" placeholder="Например: моя собака боится велосипедов"></textarea>
          </p>
        </fieldset>
        <fieldset>
          <legend>Что взять с собой</legend>
          <label><input type="checkbox" name="take" value="ball"> Мячик</label>
          <label><input type="checkbox" name="take" value="rope"> Канат</label>
        </fieldset>
        <p>
          <button type="submit">Записаться на прогулку</button>
          <button type="reset">Очистить форму</button>
        </p>
      </form>
    </main>
    <footer>
      <p><small>&copy; 2026 Тони и его хозяин</small></p>
      <address>Написать хозяину Тони: <a href="mailto:tony@example.com">tony@example.com</a></address>
    </footer>
  </body>
</html>
pages/toys.html
HTML
<!doctype html>
<html lang="ru">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="Любимые игрушки Тони и правила игры в канат.">
    <title>Игрушки Тони</title>
    <link rel="stylesheet" href="../css/style.css">
  </head>
  <body>
    <header>
      <nav>
        <ul>
          <li><a href="../index.html">Главная</a></li>
          <li><a href="toys.html">Мои игрушки</a></li>
          <li><a href="signup.html">Запись на прогулку</a></li>
        </ul>
      </nav>
    </header>
    <main>
      <h1>Мои игрушки</h1>
      <ul>
        <li>Канат с мячиком «Удав» — моя любимая игрушка</li>
        <li>Резиновая косточка — для вечеров, когда гулять уже поздно</li>
        <li>Пищащий ёжик — его я прячу <del>под диваном</del> <ins>в своей лежанке</ins></li>
      </ul>
      <img src="../assets/tony.png" alt="Тони сидит и смотрит в камеру" width="300" height="400">
      <h2>Как играть со мной в канат</h2>
      <ol>
        <li>Покажите мне канат.</li>
        <li>Бросьте его подальше.</li>
        <li>Подождите, пока я принесу его обратно.</li>
        <li>Похвалите меня — и всё сначала!</li>
      </ol>
      <section>
        <h2 id="album">Мой фотоальбом</h2>
        <ul>
          <li>
            <figure>
              <img src="../assets/album-puppy.png" alt="Тони-щенок сидит и смотрит в камеру" width="300" height="400">
              <figcaption>Я в детстве</figcaption>
            </figure>
          </li>
          <li>
            <figure>
              <img src="../assets/album-squirrel.png" alt="Тони лежит в обнимку с плюшевой белкой" width="300" height="400">
              <figcaption>С плюшевой белкой</figcaption>
            </figure>
          </li>
          <li>
            <figure>
              <img src="../assets/album-hoodie.png" alt="Тони стоит в бежевой толстовке с капюшоном" width="300" height="400">
              <figcaption>В худи для холодной погоды</figcaption>
            </figure>
          </li>
          <li>
            <figure>
              <img src="../assets/album-harness.png" alt="Тони в оранжевой шлейке ждёт прогулку" width="300" height="400">
              <figcaption>Шлейка надета — идём гулять!</figcaption>
            </figure>
          </li>
          <li>
            <figure>
              <img src="../assets/album-laugh.png" alt="Тони лежит, запрокинув голову, и широко открыл пасть, будто смеётся" width="300" height="400">
              <figcaption>Смеюсь над шуткой хозяина</figcaption>
            </figure>
          </li>
          <li>
            <figure>
              <img src="../assets/album-sleep.png" alt="Тони спит, положив голову на лапы" width="300" height="319">
              <figcaption>После прогулки</figcaption>
            </figure>
          </li>
        </ul>
      </section>
      <p><a href="../index.html#commands">Какие команды я знаю</a></p>
      <p><a href="../index.html">Вернуться на главную</a></p>
    </main>
    <footer>
      <p><small>&copy; 2026 Тони и его хозяин</small></p>
      <address>Написать хозяину Тони: <a href="mailto:tony@example.com">tony@example.com</a></address>
    </footer>
  </body>
</html>
pages/walks.html
HTML
<!doctype html>
<html lang="ru">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="Маршрут прогулки Тони: сквер, пруд и поляна для игры с канатом.">
    <title>Где гуляет Тони</title>
    <link rel="stylesheet" href="../css/style.css">
  </head>
  <body>
    <h1>Мой маршрут</h1>
    <ol>
      <li>Сквер у дома.</li>
      <li>Пруд с утками.</li>
      <li>Поляна для игры с канатом.</li>
    </ol>
  </body>
</html>

Продолжите в VS Code

Перенесите правила в свою папку my-site, сохраните файл и проверьте все четыре страницы. В DevTools откройте вкладку Computed и найдите области блока .intro. Если результат отличается, сравните его с решением в редакторе. Во второй части продолжим с этого состояния.