Всё, что нужно знать об автоматических переносах в CSS

Автор оригинала: Richard Rutter
  • Перевод


Недавно меня пригласили выступить с вечерней лекцией в Типографском обществе Австрии. Для меня стало большой честью последовать по стопам таких светил, как Мэтью Картер, Вим Краувел, Маргарет Калверт, Эрик Шпикерман и покойная Фреда Сэк.

Я рассказал о некоторых золотых правилах типографики в интернете, а потом во время секции QA меня спросили о текущей ситуации с автоматическими переносами в вебе. Это хороший вопрос, особенно с учётом того, что немецкий язык знаменит часто используемыми длинными существительными (например, Verbesserungsvorschlag означает «предложение для улучшения»), поэтому переносы широко используются в большинстве письменных носителей.

В вебе автоматические переносы появились в 2011 году и теперь широко поддерживаются. Safari, Firefox и Internet Explorer 9 поддерживают их на всех платформах, а Chrome — на Android и MacOS (пока нет на Windows или Linux).

Как включить автоматические переносы


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

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

1. Установка языка


Язык веб-страницы устанавливается с помощью атрибута HTML lang:

<html lang="en">

Это лучший способ установки языка для всех веб-страниц, включены там переносы или нет. Установка языка поможет инструментам для автоматического перевода, скринридерам и другим вспомогательным программам.

Атрибут lang="en" применяет языковой тег ISO, сообщая браузеру, что текст на английском языке. В этом случае браузер выберет дефолтный английский словарь переносов, что обычно соответствует переносам и в американском английском. Хотя американский и британский английский заметно отличаются в орфографии и произношении (и, следовательно, переносах), но разница не такая существенная, как между вариантами португальского. Проблема решается добавлением «региона», чтобы браузер знал, какой вариант английского наиболее подходит в качестве словаря переносов. Например, чтобы указать бразильский португальский или британский английский:

<html lang="pt-BR">
<html lang="en-GB">

2. Включение переносов


После установки языка можно включить автоматические переносы в CSS. Это исключительно просто:

hyphens: auto;

В настоящее время Safari и IE/Edge требуют префиксов, поэтому прямо сейчас следует написать так:

-ms-hyphens: auto;
-webkit-hyphens: auto;
hyphens: auto;

Управление переносами


Но недостаточно просто включить функцию в CSS. В спецификациях CSS Text Module Level 4 появилась возможность управлять переносами, как в программах для вёрстки (например, InDesign) и некоторых текстовых редакторах (включая Word). Эти элементы управления позволяют разными способами установить количество переносов в тексте.

Ограничение длины слова и количества символов до и после переноса


Если переносить короткие слова, их труднее читать. Точно так же вы не хотите отрывать от слова маленький кусочек. Общепринятое эмпирическое правило состоит в том, чтобы переносить только слова длиной не менее шести букв, оставляя не менее трёх символов до переноса и не менее двух на следующей строке.

В Оксфордском руководстве по стилю рекомендуется минимум три буквы после переноса, хотя допустимы редкие исключения.

Эти ограничения задаются с помощью свойства hyphenate-limit-chars. Оно принимает три значения, разделённые пробелами. Это минимальное ограничение символов для всего слова, минимальное количество символов до и после переноса. Чтобы соответствовать вышеупомянуторму эмпирическому правилу, указываем 6, 3 и 2, соответственно:

hyphenate-limit-chars: 6 3 2;


hyphenate-limit-chars в действии

По умолчанию для всех трёх параметров установлено значение auto. Это означает, что браузер выберет лучшие настройки на основе текущего языка и макета. CSS Text Module Level 4 предполагает использование в качестве отправной точки 5 2 2 (на мой взгляд, это приводит к излишним переносам), но браузеры могут изменять параметры на своё усмотрение.

В настоящее время это свойство поддерживает только IE/Edge (с префиксом), а Safari ограничивает количество символов через устаревшее свойство из предыдущего черновика CSS3 Text Module. Это означает, что вы можете добиться одинакового эффекта в Edge и Safari (с перспективным планированием для Firefox) с помощью такого кода:

/* legacy properties */
-webkit-hyphenate-limit-before: 3;
-webkit-hyphenate-limit-after: 2;

/* current proposal */
-moz-hyphenate-limit-chars: 6 3 2; /* not yet supported */
-webkit-hyphenate-limit-chars: 6 3 2; /* not yet supported */
-ms-hyphenate-limit-chars: 6 3 2;
hyphenate-limit-chars: 6 3 2;

Ограничение числа последовательных переносов


По эстетическим соображениям можно ограничить количество строк подряд с переносами. Последовательные чёрточки дефисов (три или более), уничижительно называются лесенкой. Общее эмпирическое правило для английского языка заключается в том, что две строки подряд —идеальный максимум (хотя в немецком лесенки более длинные). По умолчанию CSS не ограничивает количество последовательных дефисов, но можно установить максимальное их количество в свойстве hyphenate-limit-lines. В настоящее время это поддерживается только IE/Edge и Safari (с префиксами).

-ms-hyphenate-limit-lines: 2;
-webkit-hyphenate-limit-lines: 2;
hyphenate-limit-lines: 2;


Свойство hyphenate-limit-lines предотвращает лесенку

Можете снять ограничение с помощью no-limit.

Запрет переносов в последней строке абзаца


По умолчанию браузер спокойно переносит самое последнее слово абзаца, так что окончание слова сидит в последней строке, как одинокая сирота. Зачастую предпочтительнее большой пробел в конце предпоследней строки, чем полслова в последней строке. Это устанавливается свойством hyphenate-limit-last со значением always.

hyphenate-limit-last: always;

В настоящее время свойство поддерживается только в IE/Edge (с префиксом).

Уменьшение количества дефисов путём установки зоны переноса


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

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

Для этого нужно указать максимальное допустимое количество пробелов между последним словом строки и краем текстового поля. Если в данном пространстве начинается новое слово, оно не переносится. Это пространство известно как зона переноса. Чем больше зона переноса, тем сильнее неровность и тем меньше переносов. Регулируя зону, вы ищете оптимальное соотношение между количеством дефисов и заполнением строки.


Слева: стрелки указывают строки, где перенос разрешён. Справа: перенос с заданной зоной переноса

Для этого используется свойство hyphenation-limit-zone, где указывается размер в пикселях или процентах (относительно ширины текстового поля). В контексте адаптивного дизайна имеет смысл установить зону переноса в процентах. Это означает, что зона переноса станет меньше на экранах меньшего размера, что вызовет больше переносов и меньше незаполненных строк. И наоборот, на более широких экранах зона переноса расширится, следовательно, будет меньше переносов и больше оборванных строк, которые на широких экранах не так критичны. Основываясь на типичных значениях в программах для вёрстки, можно начать с 8%.

hyphenate-limit-zone: 8%

В настоящее время поддерживается только в IE/Edge (с префиксом).

Всё вместе


С помощью свойств CSS Text Module Level 4 установим для абзаца те же параметры управления переносами, как в обычных программах для вёрстки:

p {
    hyphens: auto;
    hyphenate-limit-chars: 6 3 3;
    hyphenate-limit-lines: 2;   
    hyphenate-limit-last: always;
    hyphenate-limit-zone: 8%;
}

C соответствующими префиксами и откатами код выглядит так:

p {
    -webkit-hyphens: auto;
    -webkit-hyphenate-limit-before: 3;
    -webkit-hyphenate-limit-after: 3;
    -webkit-hyphenate-limit-chars: 6 3 3;
    -webkit-hyphenate-limit-lines: 2;
    -webkit-hyphenate-limit-last: always;   
    -webkit-hyphenate-limit-zone: 8%;

    -moz-hyphens: auto;
    -moz-hyphenate-limit-chars: 6 3 3;
    -moz-hyphenate-limit-lines: 2;  
    -moz-hyphenate-limit-last: always;
    -moz-hyphenate-limit-zone: 8%;

    -ms-hyphens: auto;
    -ms-hyphenate-limit-chars: 6 3 3;
    -ms-hyphenate-limit-lines: 2;
    -ms-hyphenate-limit-last: always;   
    -ms-hyphenate-limit-zone: 8%;

    hyphens: auto;
    hyphenate-limit-chars: 6 3 3;
    hyphenate-limit-lines: 2;
    hyphenate-limit-last: always;   
    hyphenate-limit-zone: 8%;
}

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

Похожие публикации

Комментарии 11

    +5
    Есть мнение, что сами переносы — атавизм, который стоит оставить позади.

    Аргументы вкратце следующие:
    1. В вебе нет ограничения на число строк, поэтому нет острой потребности заполнять площадь по максимуму.
    2. Раздробленные слова затрудняют чтение сильнее, чем «рваный край».

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

    Рваный край становится проблемой только в том  случае, если неудачно подобрана ширина колонки. Для сплошного текста оптимальна длина строки в ~6—9 слов (и слегка варьируется для разных языков). В такой колонке колебания рваного края составляют от силы процентов пять-десять ширины, это смотрится вполне нормально и живо. Если же колонка выглядит рваной, это как раз сигнал о том, что есть проблема с пропорциями шрифта и строки — тогда лучше по возможности подрихтовать дизайн, а не лечить симптомы.

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

    У меня есть примерно 10
    причин не делать пере-
    носы при сплошном набо-
    ре текста в вебе.
    У меня есть
    примерно 10 причин
    не делать переносы
    при сплошном наборе
    текста в вебе.

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

    Что касается эстетики, тут тоже не всё однозначно. Избыточно ровные текстовые блоки сродни симметричной композиции и т.п. Обычно человеку изначально нравятся симметрия, яркие цвета и простые геометрические формы. Но по мере развития вкуса, предпочтение отдается асимметрии, полутонам и сложным пятным. (Не в смысле ханжества; просто естественная закономерность из культурологии, основывается на изучении народных искусств на разных стадиях развития).

    Так что, на мой взгляд, переносы в вебе не нужны. Как не нужен, например, text-indent для отбивки абзацев или    п р о б е л ь н а я     р а з р я д к а   для выделения текста. Это пережитки бумажных изданий, вынужденные костыли, обусловленные несовершенством технологий верстки. По мере развития технологии их желательно изживать из массового оборота.

    P.S. Кстати, есть вероятность, что сами принципы чтения постепенно изменятся. Вот интересный эксперимент (англ.), например. Вместо вывода целого текста выводится одно поле, которое показывает текст пословно — скорость чтения получается выше обычной. Это не полноценная замена тексту, конечно, их сложно всерьез сравнивать, но сама попытка переосмыслить процесс чтения о многом говорит.

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

      и что делать на телефоне с текстом на немецком (пример слова есть в статье)?
        0
        Возможно, есть смысл использовать сжатые гарнитуры (condensed) и кегль чуть скромнее. Что немцы частенько и делают, собственно.



        К сожалению, я не знаю немецкого (переносы тоже от балды расставлены), поэтому адекватно протестить не могу. Чисто визуально, несмотря на сжатие, глазу проще выхватить из контекста слово, когда оно не дробится:



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

        Ну и держим в голове, что ваш пример довольно специфичен: википодобный немецкий текст в ширине 304px, без редактуры. Мы всё-таки по большей части работаем с русскоязычными или на крайняк англоязычными текстами. В быту всё проще. Рядовой текст без переносов выглядит вполне нормально даже без изменения кегля и гарнитуры. Читается легче, чем с переносами.

        Вообще, если слова длиной под 30 знаков — исключения, то в идеале хотелось бы лечить их индивидуально. Мягкими переносами (&shy;) или принудительно дробить. Тривиальная задача для типографа, в общем-то. Если такой возможности нет, лучше уж просто оставлять свободно висеть в отдельной строчке, нет в этом ничего особо страшного. Одна визуально некрасивая строчка вряд ли стоит сотни переносов по всей простыне.

          0
          Сжатые гарнитуры и уменьшенный кегль — это жестоко по отношению к слабовидящим. Знаю по личному опыту; едва ли не на всех сайтах увеличиваю масштаб (прямо сейчас на Хабре у меня 133%).
        0
        С точки зрения… скорочтения… рваный край лучше, чем дробные слова.

        По каким исследованиям? Мне кажется, что с дробными словами есть профит когда предугадывается окончание и фактически чтение начинается со второго слова на новой строке.
          +2
          Вряд ли существует фундаментальное исследование, не тот масштаб проблемы. Есть много мнений на этот счёт, есть рекомендация избегать переносов в самых разных Style Guides.

          Гайд «Википедии»:
          Use of soft hyphens should be limited to special cases, usually involving very long words or narrow spaces (such as captions in infoboxes or other tight page layouts, or column labels in narrow tables). Widespread use of soft hyphens is strongly discouraged, because it makes the wikitext very difficult to read and to edit.

          Чикагский гайд (платный, но есть trial), на который ссылается гайд MS:
          The hyphenation function on your word processor should be turned off. The only hyphens that should appear in the manuscript are hyphens that would appear regardless of where they appeared on the page (e.g., in compound forms). Do not worry if such a hyphen happens to fall at the end of a line or if the right-hand margin is extremely ragged. By the same token, do not attempt to manually break excessively long words (e.g., long URLs) with a hyphen. See also 2.96.

          Это не исследования, конечно. Но рекомендации. Каждый руководствуется субъективным опытом. Я описываю свои наблюдения, которые основаны на довольно плотной работе с текстом в течение нескольких лет (копирайтинг, редактура и т.п.). Их не обязательно принимать на веру, но можно принять как пищу для размышлений.

          Так вот, личное мнение:

          1. Техника чтения такова, что мы идентифицируем слова отнюдь не последовательно. Наиболее значимы для распознавания первые и последние символы. (Здесь чуть глубже, с отсылками и примерами). Когда слово дробится, мы сразу теряем часть опорных символов, число вариантов вырастает, распознание затрудняется.

          2. Чтение со второго слова равносильно центральной или правосторонней выключке, потому что глаз вынужден нащупывать начало каждой новой строки. (Опять же, не могу сослаться на классическое исследование, но это входит в любой сборник «плохих практик» по типографике и полностью подтверждается моим личным опытом).

          3. При послоговом переносе возникает многовариантность из-за общих приставок и корней. «Мама, я принёс тебе теле-...» — телефон? телевизор? телескоп? телеграмму? Это постоянный микроподбор вариантов на основе контекста.

          Предугадывание (нечеткий поиск) кажется мне по определению более ресурсоёмкой операцией, чем прямое и однозначное считывание. Косвенно это подтверждается тем, насколько сложнее на глаз найти все вхождения определенного слова в длинном тексте, если оно местами дробится переносами.

          Учитывать моё мнение или нет — тут уж целиком на ваше усмотрение :)

          P.S. Прошу прощения, дальше углубляться не готов, итак слишком увлёкся)
            +1
            Ого, основательно =) Эх, сейчас бы айтрекер и пару сотен людей.
          +1
          Рваный край мне в любом случае кажется некрасивым; поэтому я всегда прописываю  text-align: justify;  (в этом я перфекционист: ставлю  &nbsp;  перед тире и использую кавычки-ёлочки). Да, на значительной части строк можно обойтись без переносов. Но существуют длинные слова (гиппопотомонстросесквипедалиофобия — боязнь длинных слов :-) ).

          А что касается подбора ширины колонки — страницу читают на разных устройствах с разными экранами.
          0
          -moz-hyphenate-limit-chars: 6 3 2; /* not yet supported */

          пихать эту строку в стили бессмысленно. браузеры уже давно отказались (к счастью) от префиксов. если Firefox добавит поддержку переносов, то уже без префиксов.
            0
            Пока Chrome не станет нормально поддерживать переносы, то пока смысла мало в них, к сожалению.
              0
              Прочитал с интересом, благодарю (поставил плюс).

              Хочу заметить, что язык лучше всего указывать в трёх местах.

              Во-первых, в HTTP-заголовках:
              Nginx:
              add_header Content-Language ru;
              Apache:
              DefaultLanguage ru

              Во-вторых и в третьих, в HTML:
              <html dir="ltr" lang="ru">
              <meta http-equiv="content-language" content="ru">

              Предвижу вопрос: зачем дублирование.
              Отвечаю: для поисковых систем на основе опыта работы с ними.
              Решил я прописать description на двух языках:
              <meta name="description" lang="ru" content="Здесь было описание">
              <meta name="description" lang="en" content="The description was here">
              И что я увидел? Что Яндекс, что Гугл проигнорировали атрибут lang и увидели каждый только одно описание: один только первое, другой только второе (какой какое, за давностью прошедших лет не помню). Так что пришлось мне оставить только русское описание (сайт был на русском языке), а английское спрятать в HTML-комментарий.

              Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

              Самое читаемое