Тег br делает перенос строки внутри текста. Тег одиночный, закрывающего нет, содержимого у него не бывает, собственных атрибутов тоже нет - только глобальные. Применять его стоит там, где перенос сам по себе часть содержания: в адресе, в стихотворной строке, в подписи. Для разделения абзацев он не годится - это разобрано в уроке курса.
<p>Измаил<br>
Тверская 1<br>
офис 5</p>
Чем перенос отличается от границы абзаца, нужен ли слэш перед скобкой и почему два br подряд не заменяют новый абзац - всё это разобрано в уроке - тег br: перенос строки внутри одной мысли . Здесь речь о том, что происходит дальше: чем перенос из разметки отличается от переноса, который браузер сделал сам, где br не срабатывает вовсе и как управлять переносами без него.
В этой статье
Что попадает в текст, когда его копируют
Переносов на странице два вида, и на глаз они неразличимы. Один браузер делает сам, когда строка упирается в край блока. Второй стоит в разметке тегом br. Выглядят одинаково, а разными оказываются в тот момент, когда текст со страницы копируют.
Ползунок ниже меняет ширину обоих блоков. Под каждым показано, что попадёт в буфер обмена, если выделить и скопировать его целиком; \n в этой записи - и есть перенос строки.
Пример: один адрес, два способа перенести строку
Как бы вы ни двигали ползунок, в верхнем блоке переносы остаются в записи, а в нижнем их там нет никогда - сколько бы строк ни получилось на экране.
Вывод из этого простой и объясняет, зачем тег вообще нужен. Перенос по ширине принадлежит оформлению, перенос тегом br - содержимому. Первый исчезает при копировании, при выводе на печать, при другом размере шрифта. Второй остаётся, потому что он часть текста, а не часть вёрстки.
То же самое видно и с другой стороны. Мы посмотрели структуру доступности в Chromium: на месте br появляется отдельный узел переноса строки, а текст, перенесённый по ширине блока, остаётся одним куском без всяких отметок. Программа чтения с экрана сделает на этом переносе паузу - и не сделает её там, где строку разорвал край блока.
Отсюда и правило, к которому сводится вся тема: br применяют тогда, когда перенос должен пережить копирование. Адрес, где каждая строка - отдельная часть; стихотворение, где разбивка задана автором; подпись в несколько строк. Если же перенос нужен только для красоты на конкретной ширине экрана, ему место в стилях - об этом третий раздел.
Где тег br не срабатывает
В большинстве мест br ведёт себя предсказуемо: внутри абзаца, ячейки таблицы, пункта списка, кнопки и даже ссылки он делает ровно то, что обещает. Но есть места, где он не работает, и молча - ошибки браузер не покажет.
Причина у всех случаев одна: есть элементы, содержимое которых по спецификации не разметка, а просто текст. Тег внутри такого элемента перестаёт быть тегом.
Пример: три места, где перенос не получится
В выпадающем списке перенос пропал и слова слиплись, в поле ввода тег виден буквами, и только в обычном блоке он сработал.
Мы проверили это в Chromium и свели замеры в таблицу.
| Где прописан | Что получается |
|---|---|
p, div, td, li, button | Перенос строки, как и ожидается |
a | Перенос есть, ссылка остаётся одной ссылкой; в её доступном названии перенос читается как пробел |
option | Элемент в структуре документа есть, но надпись выводится слитно: «Измаил Тверская 1» превращается в «ИзмаилТверская 1» |
textarea | Остаётся обычным текстом - пользователь видит в поле сами угловые скобки |
title | Элемента не возникает вовсе, во вкладке браузера видны угловые скобки |
Случай с option заслуживает отдельного внимания: слова не просто остаются в одной строке, они склеиваются без пробела. Разметка выглядит правдоподобно, ошибки нет, а надптсь в списке испорчена. Если строки в пункте списка нужно разделить, помогает обычный пробел или тире, а многострочные надписи собирают уже не на select.
В textarea и title перенос задаётся не тегом, а настоящим переводом строки в самом тексте. В поле ввода он и вводится клавишей, а в заголовке вкладки переносов не бывает по определению - браузер покажет всё одной строкой.
Перенос, который нужен не на всех экранах
Остаётся случай, ради которого br берут чаще всего и почти всегда напрасно: разбить надвое длинный заголовок, чтобы он красиво лёг в две строки. На странице тега h1 сказано, почему так делать не стоит - на узком экране жёсткий перенос оказывается в случайном месте фразы. Теперь о том, чем его заменить.
Средств три, и выбор между ними зависит от того, насколько жёстко нужно управлять переносом.
Самое мягкое - неразрывный пробел между слова, которые нельзя разделять: «10 кг», «Иван Петров», предлог и следующее за ним слово. Браузер сам решает, где переносить, но эти пары не разорвёт. Чаще всего заголовку хватает ровно этого.
Самое жёсткое - br с классом, который скрывается стилями. Тег с display: none перенос не делает вовсе: мы измерили, высота блока падает с двух строк до одной. Значит, перенос можно включить медиазапросом только там, где он уместен, и выключить на узком экране. Одна тонкость: пробел перед тегом нужен обязательно. Пока перенос виден, лишний пробел всё равно схлопывается, а когда тег скрыт - без пробела слова склеятся.
Третье средство - свойство text-wrap: balance: браузер сам выравнивает длину строк в заголовке. Работает оно только на коротких заголовках, и место переноса вы не выбираете - результат стоит проверять глазами, а не принимать на веру.
Пример: три заголовка на узком экране
Первый и третий заголовки разбиты одинаково, но держит их разное: в первом - тег, в третьем - неразрывный пробел. Во втором тот же тег скрыт стилями, и браузер разбил строки по-своему.
<h2>Как выбрать велосипед<br class="wide-only">для города</h2>
/* перенос работает только на широком экране */
.wide-only { display: none; }
@media (min-width: 700px) {
.wide-only { display: inline; }
}
Отдельный случай - переносы, которые приходят вместе с данными: адрес из базы, текст письма, стихотворение из файла. Добавлять в такой текст теги не требуется: при свойстве white-space: pre-line браузер выводит переводы строк, которые уже есть в самом тексте. Мы проверили - при копировании такие переносы сохраняются точно так же, как от br.
Частые ошибки
Почти все ошибки с этим тегом сводятся к одному: br берут ради внешнего вида, хотя он про содержание.
| Ошибка | Что происходит | Как исправить |
|---|---|---|
Заголовок разбит на строки тегом br | На узком экране перенос оказывается в случайном месте фразы | Скрыть тег медиазапросом или склеить слова неразрывным пробелом |
Несколько br подряд ради отступа | Расстояние зависит от размера шрифта и на другом экране разъезжается | Задать расстояние свойством margin |
br прописан внутри option | Переноса нет, а слова склеиваются без пробела | Разделить части пробелом или тире |
| Переносы из данных заменяются тегами при выводе | Лишняя обработка текста, а при ошибке в ней разметка ломается | Применить white-space: pre-line |