Тег hr размечает тематический разрыв - место, где на странице меняется тема. Тег одиночный, закрывающего нет, собственных атрибутов тоже: те, что управляли видом линии в HTML4, из стандарта убраны, и всё оформление ушло в CSS. Любопытная деталь, которая объясняет половину трудностей со стилями: по умолчанию hr - это вообще не линия, а блок нулевой высоты с рамкой по всем четырём сторонам.
<p>Разобрались с выбором рамы.</p>
<hr>
<p>Теперь о навесном оборудовании.</p>
Что именно считается сменой темы, почему hr - не украшение и чем заменять устаревшие атрибуты size, width, color и noshade, разобрано в уроке курса - тег hr: черта, которая обозначает смену темы . Здесь речь о другом: как этой чертой управлять и почему привычные свойства ведут себя не так, как ожидается.
Как задать стиль линии hr
Начать придётся с того, из чего линия сделана, - без этого дальнейшее выглядит набором необъяснимых причуд.
Браузер задаёт тегу hr нулевую высоту содержимого и рамку 1px inset со всех четырёх сторон. Видимая черта - это верхняя и нижняя рамки, сложенные вплотную: мы измерили в Chromium, её высота ровно 2 пикселя, по одному на рамку. Фона у элемента нет, а сверху и снизу браузер добавляет по 8 пикселей отступа.
Из этого следует главное: линия состоит из рамки. Значит, добраться до неё можно только свойствами рамки - и привычные способы покрасить элемент проходят мимо.
Пример: что выходит из привычных свойств
Из четырёх попыток подействовала одна - рамка. Фон и цвет текста линию не трогают, а высота растянула её в пустую коробку с рамками по краям.
Свойство background не даёт ничего: красить нечего, содержимое нулевой высоты, а рамки прилегают вплотную друг к другу. Свойство color не даёт ничего тоже - браузер прописывает рамке собственный серый цвет, и текущий цвет текста на неё не влияет. Это две первые вещи, которые пробуют, и обе мимо.
Подействовало только border-color - и это подтверждает, из чего линия сделана. Правда, вместе с цветом остаётся и стиль inset: верхний пиксель черты браузер рисует темнее нижнего. На тонкой линии это незаметно, а на толстой превращается в нежеланный объём.
Отдельно стоит разобрать height. Высота прибавляется к содержимому, рамки при этом никуда не деваются - шесть пикселей высоты дают коробку в восемь: серая черта сверху, серая снизу, пусто между ними. Если к такой высоте добавить фон, полоса наконец закрасится, но сверху и снизу её по-прежнему будет окаймлять серая рамка.
Рабочих способов два, и оба начинаются с того, что стандартную рамку нужно убрать.
Пример: два способа задать линию
Все три линии нарисованы без единого устаревшего атрибута. Первая держится на рамке, вторая на фоне, третья показывает пунктир и ограниченную ширину.
/* линия рамкой - подходит для пунктира и двойной черты */
hr { border: none; border-top: 3px solid crimson; }
/* линия фоном - удобна, когда нужен градиент или большая толщина */
hr { border: none; height: 6px; background: crimson; }
Какой выбрать - зависит от задачи. Через рамку доступны её собственные виды: dashed, dotted, double. Через фон удобнее делать толстые полосы и градиенты, потому что фон умеет то, чего рамка не умеет. Ширину в обоих случаях задаёт width, а отцентрировать укороченную линию помогает margin: 0 auto.
Почему текст нельзя вписать внутрь hr
Разделитель с подписью посередине - «Раздел второй», «Продолжение», просто звёздочка - выглядит так, будто внутри линии стоит текст. Написать это напрямую не получится: hr одиночный, содержимого у него не бывает вовсе.
Браузер в такой разметке не ругается, а просто выводит всё по-своему: рисует линию, а текст оставляет снаружи, следующей строкой.
Пример: текст в hr и правильная сборка
В первом случае текст оказался под линией, а не в ней. Во втором черта и подпись - части одного элемента, и текст встал посередине.
Собирают такой разделитель на обычном контейнере: подпись - его содержимое, а две половинки черты - декоративные псевдоэлементы, которые растягиваются по свободному месту.
<div class="split">Раздел второй</div>
.split { display: flex; align-items: center; gap: 10px; }
.split::before,
.split::after { content: ""; flex: 1; height: 1px; background: #c9c2b6; }
У такой замены есть последствие, о котором стоит знать заранее. Мы посмотрели структуру доступности в Chromium: тег hr попадает в него с ролью разделителя, а контейнер с чертой из псевдоэлементов не попадает никак - для программы чтения с экрана его там просто нет.
Разница решает, что выбрать. Если черта только украшает - контейнер подходит, и терять в нём нечего. А если в этом месте действительно кончается одна тема и начинается другая, разрыв должен остаться в разметке: тогда рядом с надписью прописывают hr, либо надпись оформляют заголовком - заголовок сам объявляет новый раздел, и черта становится его оформлением. Как выбрать уровень такого заголовка, разобрано на странице тега h3.
Частые ошибки
Ошибки с этим тегом делятся на две группы: попытки управлять видом линии не теми средствами и попытки применить разрыв там, где меняется не тема, а оформление.
| Ошибка | Что происходит | Как исправить |
|---|---|---|
Цвет линии задан свойством background или color | Ничего не меняется: линия состоит из рамки, и оба свойства до неё не достают | Убрать рамку и задать border-top либо добавить к фону height |
Толщина задана одним height | Выходит пустой прямоугольник в тонкой рамке, а не черта | Сначала border: none, потом высота и фон |
Декоративная черта нарисована тегом hr | Программа чтения с экрана объявляет разделитель там, где тема не менялась | Применить рамку у обычного блока |
Текст написан между <hr> и следующим тегом как подпись к линии | Текст выводится под чертой отдельной строкой | Собрать разделитель на контейнере или оформить подпись заголовком |