мастер на все руки
0,1
рейтинг
16 января 2012 в 16:30

Разработка → Переносы в вебе и выключка по формату

Как известно, растягивать по ширине тексты на сайтах с помощью конструкции «text-align: justify;» крайне не рекомендуется. Основная проблема — слишком большие пробелы между словами из-за отсутствия переносов в словах.

Долгое время браузеры не могли самостоятельно переносить слова. Однако недавно ситуация с поддержкой автоматических переносов стала улучшаться. Firefox 6 стал поддерживать переносы в английских текстах, а с выходом Firefox 8 очередь дошла и до русских текстов. Переносы также есть в последних версиях Safari. Поэтому настала пора подумать, как можно использовать выключку по формату с откатом к выключке влево, если браузер не поддерживает автоматические переносы.

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

Вот фрагмент кода, иллюстрирующий идею:
<style>
.hyphens {
	-moz-hyphens: auto;
	-ms-hyphens: auto;
	-webkit-hyphens: auto;
	hyphens: auto;
	}
</style>
<script type="text/javascript">
function is_hyphens ()
{
	function get_height (eItem)
	{
		var rect = eItem.getBoundingClientRect();
		return rect ? (rect.bottom - rect.top) : eItem.offsetHeight;
	}

	var eHyphens = document.createElement('DIV'),
	    eNoHyphens = document.createElement('DIV');

	document.body.appendChild(eHyphens);
	document.body.appendChild(eNoHyphens);

	eHyphens.innerHTML = eNoHyphens.innerHTML = 'синхрофазотрон';
	// 1em не работало в Safari, а 2em на iPad
	eHyphens.style.width = eNoHyphens.style.width = '3em';
	eHyphens.className = 'hyphens';

	var result = get_height(eHyphens) > get_height(eNoHyphens);

	document.body.removeChild(eHyphens);
	document.body.removeChild(eNoHyphens);

	return result;
}
</script>

На демонстрационной странице в первом фрагменте применяется выключка по формату и переносы, если браузер их поддерживает:
image

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

Я протестировал этот код в основных браузерах под Windows (кроме IE10) и в некоторых под Ubuntu. Переносы поддерживают только Firefox (скриншот выше) и Safari в Windows, и в обоих браузерах код работает правильно. Также выяснилось, что в моей установке Ubuntu Firefox не переносит русские слова, видимо, из-за отсутствия словарей.

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

А как бы вы решили эту задачу?
Роман Парпалак @parpalak
карма
81,0
рейтинг 0,1
мастер на все руки
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (60)

  • +1
    Может лучше в «Типографику»? :)

    Всё равно зияющие пробелы в заголовке с переносами. Возможно, имеет смысл включать стиль для абзацев текста и отключать для заголовков. Текст субъективно читается лучше, чем при рваном крае с такой шириной колонки.
    • +6
      Могу перенести в «Типографику», если надо. Я рассматривал техническую сторону вопроса и подумал, что «Веб-разработка» уместнее.

      Да, крупные заголовки и узкие колонки всё равно выглядят плохо, несмотря на переносы.
  • 0
    FF 9.0.1, MacOS X 10.7.2, полет нормальный!
    Отличная идея! В узких колонках — да, не айс. Видимо, придется пока разумно использовать там, где это точно будет надо. Спасибо :-)
    • 0
      Вдогонку: Safari 5.1.2, MacOS X 10.7.2, полет нормальный!
  • +1
    Хм. Firefox 9.0.1, Windows — первый фрагмент в демо выглядит также как и второй. Может потому что у меня Firefox английский?
    • +2
      Да, скорее всего. У меня в Ubuntu Firefox тоже английский.

      Для автоматических переносов браузерам нужны словари. Как показывает практика, переносы в русских текстах есть в русских версиях браузеров.
      • –1
        Mac OS 10.7.2, последний Хром. Смена языка системы на русский не помогла — переносы не работают :(
        • +1
          Хром и не поддерживает автоматические переносы: caniuse.com/css-hyphens
      • +1
        Точно, заменил тестовое слово на английское (dissatisfaction), 1-й фрагмент стал идентичен третьему.
  • 0
    В FF 8.0 (Windows) выглядит очень даже :)
  • –2
    «синхрофазотрон»
    Длинны слова всегда достаточно? Могу ещё предложить «высококвалифицированный» =)
  • +3
    Если абстрагироваться от неполной поддержки, имевшей место до Firefox 8, можно проверять проще:

    function isHyphensSupported() {
    	var s = document.documentElement.style;
    
    	return       'hyphens' in s
    	    ||    'MozHyphens' in s
    	    || 'WebkitHyphens' in s
    	    ||  'KhtmlHyphens' in s;
    }
    

    Кстати, свойство без префикса (hyphens в данном случае) применять в общем случае небезопасно до тех пор, пока спецификация не выйдет из состояния черновика.
    • +1
      Дело в том, что формальной поддержки свойства hyphens, а именно значения 'auto', недостаточно. В браузере может не быть словарей. Английские Safari и Firefox русские слова не переносят.
      • +1
        Англоязычный Firefox переносит без проблем (проверено на nightly-сборке 20120115031052). Главное у корневого элемента документа (или элемента, содержащего текст, подлежащий авторасстановке переносов) указать правильный атрибут lang, чтобы браузер знал, какой словарь использовать:

        <html lang="ru">
        • 0
          Спасибо, добавил на демонстрационной странице.
          • +1
            Подтверждаю, на английском FF 9.0.1 заработало.
          • НЛО прилетело и опубликовало эту надпись здесь
          • 0
            А в моем английском FF 9.0.1 на Ubuntu так и не заработало.
  • +2
    Да никак эту задачу не надо решать, никогда браузеры не научатся переносить слова так, чтобы это не требовало ручного вмешательства. Ну вот что это за безобразие?

    Читать совершенно неприятно.
    А если и научатся, то всё-равно применять это на практике в вебе — архоизм. Даже на новостных и информационных сайтах. Пусть это решают сами пользователи, используя возможности браузера, Reader в том же Сафари — как раз в эту сторону шаг, только вот до остальных разработчиков это всё никак не дойдёт. Тут же от множества факторов зависит, а не от одной только прихоти «хочу чтобы правый край был ровным». Лучше о содержании текста пусть думают, чтобы читался легко и приятно в любых режимах. Выключку по ширине, как правило, применяют к куче нудного монотонного текста, читать который нет ни малейшего желания, зато выглядит «красиво», чо, и навевает ещё больше скуки.
    • +1
      Пардоньте, врожде предпросмотр делал, там картинка грузилась:
      • +2
        Перенос «до-ступны» некорректен. Правила русского языка предписывают переносить «дос-туп-ны».
        Это означает, что фактически переносы не поддерживаются.
        Перенос «определя-ет» формально корректен, но некрасив. Либо опреде-ляет, либо без переноса вообще.
        Перенос «про-странства» некорректен. Правильно «прос-тран-ства».
        • 0
          В итоге: идея «расстановка переносов» — это хорошо и правильно.
          Текущая реализация — всё равно, что её нет, только хуже, потому что многие могут подумать что она есть и начать использовать. Если я увижу на каком-нибудь сайте такие переносы, то впечатление то же самое будет, как будто фон розовый и шрифт Comic Sans.
          • +4
            Эти переносы не подойдут даже для сайтов Почты России и Сбербанка!
        • 0
          Это вопрос к авторам словарей переносов в браузерах.

          Кстати, какие именно правила русского языка вы имеете в виду? Я заглянул в правила переносов и не нашел там запретов на приведенные вами примеры.
        • –1
          Вы неправы. И «до-ступны», и «дос-тупны» допустимы, причём первый считается предпочтительным. Аналогично с «пространством».
        • НЛО прилетело и опубликовало эту надпись здесь
        • +2
          Насколько я помню, правила переноса упростили.
    • +1
      Уместно заметить, что авторасстановка переносов имеет смысл не только при выравнивании по ширине, но и в узких колонках текста с выравниванием по левому краю.
      • 0
        Авторасстановка — бессмысленна и беспощадна, и никто меня в не переубедит в обратном. Я уж лучше от узкой колонки избавлюсь или вручную перенос воткну, чем безконтрольному и бездушному механизму доверять. Хотя, это зависит от того, как к тексту относишься и какое он значение имеет на сайте.
        • 0
          Возможность повлиять на дизайн есть далеко не всегда. Вручную расставить переносы — тоже (например, на сайте какого-нибудь СМИ, наполняемом заказчиком самостоятельно). Авторасстановка переносов в таких случаях может хотя бы предотвратить вылезание длинных слов за пределы колонки.
  • 0
    Скриншотик бы, интересно.
    • +2
      • +2
        Отличная книга
        • 0
          О, хоть кто-то узнал :)
          • 0
            Я думаю, что многие узнали :)
    • +1
      Добавил в текст топика.
  • +9
    Переносы слов в заголовках не допускаются, даже если для этого есть техническая возможность.
  • –1
    А зачем вообще нужны переносы? В компьютерах по-моему они должны уже вымереть.
    • 0
      Согласен.
      Имхо, переносы нужны были для бумаги, чтобы экономить место.
      К счастью, в случае экрана место виртуально бесконечно, так что смысла в переносах я тоже не вижу.
      Да и качество работы этих автопереносов оставляет желать лучшего — даже я, с моей тройкой по русскому в школе, знаю, что нельзя переносить «ра-диоприемниках», «со-бой».
      • –1
        Вы неправы. Так переносить можно.
        • +1
          Как я уже выше написал, по русскому всю дорогу имел тройку, потому допускаю, что могу ошибаться.

          Насколько я помню правила, действительно, переносить можно свободно по слогам, но некорректным и некрасивым считалось разрывать корень слова (как в случае с «ра-диоприемниках» (или радио — это приставка?:))
          А случай вроде «со-бой», насколько я помню, точно всегда подчеркивали красным, лучше было перенести все слово на новую строку, чем там переносить.

          Лично мне такие переносы режут глаз и замедляют лично мою скорость чтения.

          P.S. Был бы благодарен за ссылку на правило, согласно которым так переносить правильно (вы же, я так понял, взяли на себя роль grammar nazi в этом топике, вот и отдувайтесь:)
          • 0
            Некрасивым считается отрывать одну букву от корня, например, хотя это и допустимо. А ссылка на правила в этом топике чуть ниже (вроде) есть.
      • 0
        Место бесконечно в теории, а на практике ширина строки ограничена удобством чтения и появлением горизонтальной прокрутки.
        • 0
          Это да, согласен. Никому не было бы удобно горизонтально скроллить или бегать глазами по всему экрану туда-сюда при чтении.
          Но вертикально-то, как правило, место ничем не ограничено.
          • 0
            Но это обессмысливает скорее многоколоночную вёрстку (в сущности — переносы по вертикали), нежели переносы.
  • 0
    Ubuntu, FF 9.0.1 — ничего не увидел на страничке )-:
  • +2
    Использую hyphenator
    • 0
      Да, штука полезная, хотя приводит к нехорошим эффектам зачастую. Лучше, чем ничего, однако.
  • 0
    Первый айпад, mobile safari.
    Первый абзац на тестовой странице с переносами, но выключка по левому краю.
    • 0
      image
      • +1
        Попробуйте еще раз. Я увеличил ширину временного элемента на демонстрационной странице.
        • 0
          Работает!
  • 0
    FF 9.0.1, MacOS X 10.6.8 — отлично отображается. В остальных (Chrome, Opera, Safari) без изменений, наверно из-за отсутствия словарей.
  • 0
    а я добавляю мягкий перенос (­), весьма удобно если кто-то ввел длинное слово без пробелов
    • 0
      в скобках было shy, хабр съел )
  • 0
    в Опере не работает
    • 0
      Опера не поддерживает автоматические переносы: caniuse.com/css-hyphens
  • 0
    Да, жаль, что css hypens:auto не работает. Упростило бы жизнь.
    Я использую плагин для jQuery, который сам расставляет переносы: http://htmler.ru/2013/12/07/jquery-perenosy-russkogo-teksta/

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