Единицы измерения. Часть 1: размер шрифта

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

В предыдущем уроке мы оформили состояния ссылок и видимый фокус. Пора заняться самим текстом: на сайте Тони заголовки и абзацы до сих пор того размера, который выбрал браузер. Размер — первое, что делает текст удобным для чтения: важное можно выделить крупнее, второстепенное — мельче.

Свойство font-size

Размер шрифта задаёт свойство font-size. Его значение — длина: число и единица измерения, записанные слитно, без пробела.

CSS
p {
  font-size: 20px; /* размер шрифта всех абзацев — 20 пикселей */
}

Размер шрифта не может быть отрицательным: такое объявление браузер считает ошибкой и пропускает. Запись с пробелом (20 px) тоже ошибочна. Единица обязательна у любого ненулевого значения: font-size: 20 не сработает, без единицы допустим только 0.

Единицы измерения длины в CSS делятся на абсолютные, размер которых не зависит от окружения, и относительные, которые считаются от размера шрифта, родителя или окна браузера. Рассмотрим их по порядку. Единицы одинаково работают и в других свойствах с длиной — ширине, отступах, рамках. Размер шрифта удобен для знакомства: результат сразу виден.

Абсолютные единицы

Физические единицы

  • Дюймы (in): 1in = 2.54cm = 96px.
  • Сантиметры (cm): 1cm = 96px / 2.54, около 37.8px.
  • Миллиметры (mm): 1mm = 1/10 от 1cm.
  • Четверть миллиметра (Q): 1Q = 1/40 от 1cm.
  • Пики (pc): 1pc = 12pt = 1/6 дюйма.
  • Пункты (pt): 1pt = 1/72 дюйма.

Названия напоминают о линейке, но на экране сантиметр CSS не равен настоящему сантиметру: все физические единицы жёстко связаны с пикселем CSS (1in = 96px), а сколько это на самом деле, зависит от размера и плотности экрана. Поэтому на веб-страницах физические единицы почти не используют.

Их место — печать. Если страница предназначена не только для просмотра, но и для печати, в стилях для печати размер шрифта можно задать в пунктах, а поля страницы — в сантиметрах: принтер выводит их близко к настоящему размеру. В остальных случаях физические единицы использовать не стоит. Стили для печати задают отдельно от экранных; в уроках об адаптивности мы познакомимся с выбором типа устройства в @media.

Пиксели

Пиксель (px): 1px = 1/96 дюйма.

CSS
body {
  font-size: 16px; /* размер шрифта 16 пикселей для всего видимого содержимого */
}

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

Главный недостаток пикселей — они не учитывают настройку размера шрифта в браузере. Пользователь, которому трудно читать мелкий текст, может увеличить шрифт в настройках: в Google Chrome это «Настройки» → «Внешний вид» → «Размер шрифта» (Settings → Appearance → Font size). Текст, заданный в пикселях, на эту настройку не реагирует. Масштаб страницы (Ctrl + +, в macOS Cmd + +) увеличивает и пиксели, но меняет всю страницу и только на текущем сайте. Как сохранить настройку пользователя, разберём в разделе о единице rem.

Относительные единицы

Процентные значения

Если для элемента нет собственного объявления font-size, он наследует размер шрифта родителя. Некоторым элементам, например заголовкам, размер задают стили браузера. Базовый размер основного текста при стандартных настройках обычно составляет 16 пикселей. Пользователь может изменить его в настройках браузера, поэтому в CSS не стоит считать его постоянным.

Процентное значение font-size считается от размера шрифта родительского элемента: размер шрифта родителя — это 100%. Чтобы сделать текст одного абзаца вдвое крупнее, а другого — вдвое мельче, зададим каждому абзацу свой класс:

Процентные значения: попробуйте сами

В этом примере родитель абзацев — body с размером шрифта браузера (обычно 16px), поэтому 50% дают 8px, а 200% — 32px. Задайте body { font-size: 20px; } — оба абзаца пересчитаются от нового размера.

index.html
HTML
<!doctype html>
<html lang="ru">
  <head>
    <meta charset="utf-8">
    <title>Процентные значения font-size</title>
    <style>
      .small {
        font-size: 50%; /* половина размера шрифта родителя */
      }
      .big {
        font-size: 200%; /* вдвое больше размера шрифта родителя */
      }
    </style>
  </head>
  <body>
    <p>Обычный абзац: размер шрифта браузера по умолчанию.</p>
    <p class="small">Абзац с размером шрифта 50% от родителя.</p>
    <p class="big">Абзац с размером шрифта 200% от родителя.</p>
  </body>
</html>

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

Проценты во вложенных элементах: попробуйте сами

У блока .double 200% от 12px — 24px, у вложенного блока 200% от 24px — 48px. Удалите правило div { font-size: 12px; } — проценты станут считаться от 16px, и размеры вырастут до 32px и 64px.

index.html
HTML
<!doctype html>
<html lang="ru">
  <head>
    <meta charset="utf-8">
    <title>Проценты во вложенных элементах</title>
    <style>
      div {
        font-size: 12px; /* базовый размер для всех блоков */
      }
      .double {
        font-size: 200%; /* вдвое больше родителя: 12px × 2 = 24px */
      }
      .double > div {
        font-size: 200%; /* вдвое больше своего родителя .double: 24px × 2 = 48px */
      }
    </style>
  </head>
  <body>
    <div>Родительский блок — 12px
      <div class="double">Блок .double — 200% от 12px
        <div>Вложенный блок — 200% от 24px</div>
      </div>
    </div>
  </body>
</html>

Для блока с классом double родитель — внешний блок <div> с размером 12px:

Если бы размер внешнего блока не был задан, расчёт шёл бы от базового размера: 16px × 200% = 32px.

Селектор дочерних элементов .double > div выбирает блок <div>, вложенный прямо в блок с классом double. Для него 100% — это уже 24px, а 200% — 48px:

В других свойствах проценты считаются от другой величины: например, ширина в процентах — от ширины родителя. От чего считается процент, указано в справочнике у каждого свойства.

Единица em

Em пришла из типографики: так называли кегль шрифта — высоту литеры, на которой отлита буква. Название связывают с буквой «M», которая в латинских шрифтах занимала почти весь квадрат литеры. В CSS 1em равен размеру шрифта. В свойстве font-size это размер шрифта родителя, поэтому em здесь работает так же, как проценты:

Значения em и проценты: попробуйте сами

Абзацы попарно одинаковы: 0.8em = 80%, 1.5em = 150%. Добавьте body { font-size: 20px; } — все четыре абзаца пересчитаются от нового размера родителя.

index.html
HTML
<!doctype html>
<html lang="ru">
  <head>
    <meta charset="utf-8">
    <title>Значения em и проценты</title>
    <style>
      .em-08 { font-size: 0.8em; }
      .pct-80 { font-size: 80%; }
      .em-15 { font-size: 1.5em; }
      .pct-150 { font-size: 150%; }
    </style>
  </head>
  <body>
    <p class="em-08">font-size: 0.8em</p>
    <p class="pct-80">font-size: 80%</p>
    <p class="em-15">font-size: 1.5em</p>
    <p class="pct-150">font-size: 150%</p>
  </body>
</html>

В других свойствах em считается от размера шрифта самого элемента. Например, отступ padding: 0.5em у кнопки с крупным шрифтом будет больше, чем у кнопки с мелким: отступ растёт вместе с текстом. Это удобно для компонентов, которые должны масштабироваться целиком. Отступы мы рассмотрим в уроке «Блочная и строчная модель».

Единица rem

Rem — сокращение от root em (англ. root — корень): размер считается от размера шрифта корневого элемента <html>, а не родителя.

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

Сравним em и rem на вложенных списках: в первом пунктам задано 1.25em, во втором — 1.25rem.

em и rem во вложенных списках: попробуйте сами

В первом списке каждый уровень в 1.25 раза крупнее предыдущего: em считается от родителя, который уже увеличен. Во втором списке все пункты одинаковы: rem считается только от корня. Добавьте четвёртый уровень в первый список и посмотрите, как он вырастет.

index.html
HTML
<!doctype html>
<html lang="ru">
  <head>
    <meta charset="utf-8">
    <title>em и rem во вложенных списках</title>
    <style>
      .em li {
        font-size: 1.25em; /* от размера шрифта родителя — растёт с каждым уровнем */
      }
      .rem li {
        font-size: 1.25rem; /* от размера шрифта корня — одинаковый на всех уровнях */
      }
    </style>
  </head>
  <body>
    <h2>1.25em</h2>
    <ul class="em">
      <li>Игрушки
        <ul>
          <li>Канат
            <ul>
              <li>Канат с мячиком</li>
            </ul>
          </li>
        </ul>
      </li>
    </ul>
    <h2>1.25rem</h2>
    <ul class="rem">
      <li>Игрушки
        <ul>
          <li>Канат
            <ul>
              <li>Канат с мячиком</li>
            </ul>
          </li>
        </ul>
      </li>
    </ul>
  </body>
</html>

В первом списке каждый вложенный пункт берёт за основу размер своего родителя, уже увеличенный в 1.25 раза: 16px → 20px → 25px → 31.25px. Во втором списке размер каждого пункта считается от корня: 16px × 1.25 = 20px на любом уровне.

При корневом размере 16px font-size 1.25em даёт во вложенных пунктах 20px, 25px и 31.25px — каждый раз от шрифта родителя. При 1.25rem все три уровня получают 20px от корня.
Стрелки показывают, откуда берётся основа расчёта font-size.

Главное достоинство rem — он сохраняет настройку пользователя. Размер шрифта корня по умолчанию берётся из настройки браузера. Если пользователь увеличил шрифт со стандартных 16px до 20px, то 1rem станет 20px, и весь текст, заданный в rem, вырастет пропорционально. Значения в пикселях останутся прежними.

Настройка шрифта браузера: попробуйте сами

Правило html изображает настройку шрифта в браузере. Замените 100% на 150%: абзац в rem станет крупнее, абзац в px не изменится.

index.html
HTML
<!doctype html>
<html lang="ru">
  <head>
    <meta charset="utf-8">
    <title>Настройка шрифта браузера, rem и px</title>
    <style>
      html {
        font-size: 100%; /* так ведёт себя настройка шрифта в браузере: попробуйте 150% */
      }
      .rem {
        font-size: 1rem;
      }
      .px {
        font-size: 16px;
      }
    </style>
  </head>
  <body>
    <p class="rem">Абзац в rem: растёт вместе с размером шрифта корня.</p>
    <p class="px">Абзац в px: остаётся 16 пикселей.</p>
  </body>
</html>

Обе единицы широко используются, и у каждой своя задача. Rem подходит для размеров текста и отступов страницы: они зависят только от настройки пользователя и предсказуемы в любом месте документа. Em подходит, когда размер должен зависеть от шрифта самого элемента или родителя: отступы внутри кнопки, значок рядом с текстом. Перевести значения из пикселей в rem и em поможет виджет в конце урока. Для самостоятельных расчётов откройте конвертер единиц CSS: задайте размер шрифта и переведите нужное значение.

Единица ex

Единица ex зависит от шрифта: 1ex равен высоте строчной буквы «x» в шрифте элемента. Используется редко — в основном для тонкой типографской настройки, например чтобы выровнять значок по высоте строчных букв.

Высота строчной «x» часто близка к 0.5em, но зависит от шрифта. Если браузер не может определить эту метрику, используется значение 0.5em.

Высота строчной буквы x — единица ex — в сравнении с размером шрифта em.

Единица ch

Единица ch тоже зависит от шрифта: 1ch равен ширине символа «0» (ноль, символ Юникода U+0030). В моноширинном шрифте, где все символы одной ширины, блок шириной 50ch вмещает ровно 50 символов. В обычном шрифте символы разной ширины, поэтому ch задаёт ширину, а не число символов в строке. Это удобный ориентир, чтобы ограничить длину строки текста, — так мы поступим в уроке «Форматирование текста».

Единица ch: попробуйте сами

Оба абзаца ограничены шириной 30ch. В моноширинной строке помещается ровно 30 цифр, а количество букв в обычном тексте зависит от их ширины. Измените значение на 20ch.

index.html
HTML
<!doctype html>
<html lang="ru">
  <head>
    <meta charset="utf-8">
    <title>Ширина в символах ch</title>
    <style>
      p {
        max-width: 30ch; /* около 30 символов в строке */
        background-color: linen;
      }
      .mono {
        font-family: monospace; /* у моноширинного шрифта все символы шириной 1ch */
      }
    </style>
  </head>
  <body>
    <p>Я карликовый пинчер. Мне три года, я вешу 8 кг и люблю гулять в любую погоду.</p>
    <p class="mono">0123456789012345678901234567890123456789</p>
  </body>
</html>

Если браузер не может определить ширину «0», используется значение 0.5em.

Ключевые слова размера шрифта

Кроме длины, свойство font-size принимает ключевые слова:

CSS
small {
  font-size: small; /* маленький размер шрифта для всех элементов <small> */
}

Абсолютные ключевые слова — ступени шкалы размеров браузера от medium. Размеры в таблице приведены для Google Chrome при стандартной настройке шрифта (16px); другие браузеры могут немного отличаться, а при изменении настройки меняется вся шкала.

Значение Описание
xx-small Самый маленький размер шрифта. Около 9px.
x-small Очень маленький размер шрифта. Около 10px.
small Маленький размер шрифта. Около 13px.
medium Средний размер шрифта, равен настройке браузера (16px). Это начальное значение свойства.
large Большой размер шрифта. Около 18px.
x-large Очень большой размер шрифта. 24px.
xx-large Ещё больший размер шрифта. 32px.
xxx-large Самый большой размер шрифта. 48px.
smaller Размер шрифта меньше, чем у родителя: следующая ступень шкалы вниз, примерно в 1.2 раза меньше.
larger Размер шрифта больше, чем у родителя: следующая ступень шкалы вверх, примерно в 1.2 раза больше.

Ключевые слова размера шрифта: попробуйте сами

Абзацы показывают шкалу от xx-small до xxx-large. В последнем абзаце smaller и larger считаются от размера родителя small. Замените класс последнего абзаца на x-large — относительные размеры вырастут вместе с ним.

index.html
HTML
<!doctype html>
<html lang="ru">
  <head>
    <meta charset="utf-8">
    <title>Ключевые слова размера шрифта</title>
    <style>
      .xx-small { font-size: xx-small; }
      .x-small { font-size: x-small; }
      .small { font-size: small; }
      .medium { font-size: medium; }
      .large { font-size: large; }
      .x-large { font-size: x-large; }
      .xx-large { font-size: xx-large; }
      .xxx-large { font-size: xxx-large; }
      .smaller { font-size: smaller; }
      .larger { font-size: larger; }
    </style>
  </head>
  <body>
    <p class="xx-small">xx-small</p>
    <p class="x-small">x-small</p>
    <p class="small">small</p>
    <p class="medium">medium</p>
    <p class="large">large</p>
    <p class="x-large">x-large</p>
    <p class="xx-large">xx-large</p>
    <p class="xxx-large">xxx-large</p>
    <p class="small">small, а внутри <span class="smaller">smaller</span> и <span class="larger">larger</span></p>
  </body>
</html>

Относительные ключевые слова smaller и larger берут размер шрифта родителя и сдвигают его на ступень по шкале браузера. Точный коэффициент стандарт оставляет браузеру; обычно он около 1.2. Ключевые слова подходят для быстрых правок, но для собственной шкалы размеров на сайте удобнее rem: значения точнее и не зависят от шкалы браузера.

Размер шрифта в инструментах разработчика

Значение в относительных единицах браузер переводит в пиксели. Итог показывает вкладка Computed, знакомая по уроку «Инструменты разработчика»: выберите элемент и найдите свойство font-size. Там всегда пиксели, даже если в CSS записано 1.25rem или 150%. Если раскрыть свойство, браузер покажет, из какого правила взято значение.

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

Введите размер, например 24px или 1.5rem, и посмотрите, сколько это в других единицах. Измените размер шрифта корня — значения в rem пересчитаются, а пиксели останутся прежними. Измените размер шрифта родителя для em и сравните результат.

Можно ввести с единицей: 1.5rem, 12pt, 50vw

Контекст, px
для rem; в браузере по умолчанию 16px
элемента, а в свойстве font-size — родителя
для ch; зависит от шрифта, обычно около 0.5em
Абсолютные
Абсолютные
px24pxCSS-пиксель
pt18ptтипографский пункт: 1pt = 1/72 дюйма = 4/3px24px ÷ 4/3px = 18pt
От размера шрифта
От размера шрифта
rem1.5remот font-size корневого элемента24px ÷ 16px = 1.5rem
em1.5emот font-size элемента (в самом font-size — родителя)24px ÷ 16px = 1.5em
ch3chот ширины символа «0» в шрифте элемента24px ÷ 8px = 3ch

Все единицы и перевод px в rem во всём CSS — в конвертере единиц

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

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

1. Какое объявление размера шрифта браузер применит?
Показать ответ

font-size: 1.5rem; — Число и единица записаны слитно, значение положительное — объявление корректно.

2. Что такое пиксель CSS (px)?
Показать ответ

Условная единица: браузер сам пересчитывает её в точки экрана, на плотном экране 1px занимает несколько точек — Пиксель CSS равен 1/96 дюйма CSS. На экранах с высокой плотностью точек он занимает две, три и больше точек экрана.

3. Блоку div задан font-size: 12px, вложенному в него блоку — 200%, а блоку внутри вложенного — тоже 200%. Каков размер шрифта самого внутреннего блока?
Показать ответ

48px — Процент считается от итогового размера родителя: 12px × 200% = 24px, затем 24px × 200% = 48px.

4. Задано body, div { font-size: 150%; }. В <body> вложен блок <div>, а в него — ещё один <div>. Каков размер шрифта текста во внутреннем блоке при базовом размере 16px?
Показать ответ

54px — Каждый уровень увеличивает размер родителя в 1.5 раза: body — 16 × 1.5 = 24px, первый div — 36px, второй — 54px.

5. Те же элементы, но правило body, div { font-size: 1.5em; }. Каков размер шрифта текста в блоке <div>, вложенном прямо в <body>?
Показать ответ

36px — В свойстве font-size em считается от родителя, как проценты: body — 16 × 1.5 = 24px, div — 24 × 1.5 = 36px.

6. А если правило body, div { font-size: 1.5rem; }? Каков размер шрифта во внутреннем блоке <div>?
Показать ответ

24px — Rem считается от размера шрифта корня <html> (16px), а не от родителя: 16 × 1.5 = 24px на любом уровне.

7. Почему размеры текста на сайте удобнее задавать в rem, а не в px?
Показать ответ

Значения в rem растут вместе с настройкой размера шрифта в браузере, а пиксели — нет — Размер шрифта корня берётся из настройки браузера. Если пользователь увеличит шрифт, весь текст в rem вырастет пропорционально.

8. Чем плохо правило html { font-size: 10px; }?
Показать ответ

Корень всегда 10px, и настройка размера шрифта пользователя больше не влияет на значения в rem — Размер в пикселях заменяет значение из настройки браузера. Если корню нужен другой размер, задавайте его в процентах или em.

9. Отступ кнопки задан как padding: 0.5em, а её размер шрифта — 20px. Каков отступ?
Показать ответ

10px — Вне свойства font-size em считается от размера шрифта самого элемента: 20px × 0.5 = 10px.

Задание

Ожидаемый результат: основной текст на всех страницах немного крупнее прежнего, главный заголовок страницы — 40px, заголовки разделов — 28px, подписи к фотографиям чуть мельче основного текста. Проверьте на вкладке Computed: у абзаца font-size — 17px. Объясните, почему заголовки получили размер от корня, хотя они вложены в <body> с размером 17px.

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

css/style.css
CSS
/* Общие стили сайта Тони */
body {
  background-color: linen;
  color: #2b211b; /* цвет для потомков без собственного значения */
}

/* Общий цвет заголовков — групповой селектор */
h1,
h2 {
  color: saddlebrown;
}

h1 {
  text-align: center;
}

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

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

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

/* Ссылки оглавления главной страницы */
.toc a {
  color: dimgray;
}

figcaption {
  color: dimgray;
}

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;
}
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

Добавьте те же объявления в css/style.css своей папки my-site, сохраните файл и откройте сайт в браузере. Затем увеличьте размер шрифта в настройках Google Chrome («Настройки» → «Внешний вид» → «Размер шрифта», Settings → Appearance → Font size) до «Крупный» (Large). Проверка: весь текст сайта стал крупнее. Верните настройку обратно. Если результат отличается, нажмите в редакторе «Показать решение» и сравните его со своим кодом.

Дополнительная задача

Элементу <body> и элементам <div> задан размер шрифта 150%. Считайте размер шрифта корня равным 16px. Прежде чем проверять результат в браузере, посчитайте, сколько пикселей составляет размер шрифта:

  • текста внутри <body>;
  • текста внутри блока <div>, вложенного в <body>;
  • текста внутри блока <div>, вложенного в другой блок <div>.

Затем проверьте ответ на вкладке Computed. Замените 150% на 1.5em, а потом на 1.5rem, и снова посчитайте и проверьте.

Выполните дополнительную задачу

index.html
HTML
<!doctype html>
<html lang="ru">
  <head>
    <meta charset="utf-8">
    <title>Размер шрифта во вложенных блоках</title>
    <style>
      body,
      div {
        font-size: 150%;
      }
    </style>
  </head>
  <body>
    Текст внутри тела документа
    <div>Текст внутри блока
      <div>Текст внутри вложенного блока</div>
    </div>
  </body>
</html>

Проверить расчёты

При 150% и 1.5em размеры одинаковы — 24px, 36px и 54px: каждый уровень считается от родителя. При 1.5rem все три текста по 24px: размер считается от корня (16px × 1.5).

В следующей части рассмотрим единицы окна и функции для вычисления размеров.