Xiper

Вертикальный текст

Автор: Евгений Рыжков Дата публикации:

Задача

пример вертикальной надписиСделать вертикальную надпись (заголовок, пункт меню, сообщение и т.п.), при чем надпись должна быть текстом, чтобы можно было ее менять.

Решение

Не казалась бы подобная задача такой фантастической, если бы разработчики браузеров поспевали за рекомендациями W3C. Те уже давно предлагают свойство writing-mode для указания направления текста. С помощью него и можно задать вертикальное направление.

Как ни странно, ни один из "продвинутых" браузеров в настоящее время данное свойство не признают. И что еще более странно, его понимает Interner Explorer! И чтоб вообще добить — начиная с версии 5.5! Это первый случай в моей практике. когда решение нужно искать не для IE, а для остальных браузеров.

каждый браузер выбрал свою дорогуРазработчики остальных браузеров, проигнорировав рекомендации стандартов, пошли другим путем. При чем, каждый из них своим. Mozilla внедрила -moz-transform, Opera — -o-transform, webkit как уже можно было догадаться — -webkit-transform. Зачем было столько свойств плодить, мне не понятно. Ну не будем такими придирчивыми, и на этом им спасибо. Следует отметить, что эти три свойства позволяют повернуть текст на произвольный угол (значением свойств является угол — и это плюс), в отличие от writing-mode, который ныне способен отобразить текст только в двух положениях: горизонтально (значение lr-tb) и вертикально (tb-rl).

Теперь, чтобы развернуть надпись вертикально нужно:

  • перечислить все варианты поворота текста
  • указать фиксированные размеры контейнера с текстом (ширину и высоту). Без них блок с текстом может вести себя непредсказуемо

Чтобы посмотреть как поворот повлияет на положение поворачиваемого элемента в потоке, добавим до и после него по блоку.

<div class="firstBlock"></div>
<div id="rotateText">Текст, который будем поворачивать</div>
<div class="lastBlock"></div>
#verticalText {
    -moz-transform: rotate(90deg);
    -webkit-transform: rotate(90deg);
    -o-transform: rotate(90deg);
    writing-mode: tb-rl;
    width: 300px;
    height: 200px;
}

Демо пример. Смотрим результат и лично меня он не удовлетворяет:

вертикальный текст в IE Вертикальный текст в IE

В IE отработало как нужно — текст повернулся, блок остался на своем месте. Вывод: доработок никаких не требуется.

вертикальный текст в продвинутых браузерах Вертикальный текст в Firefox, Opera 10.51, Safari 3.5, Chrome

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

вертикальный текст в Opera версии ниже 10.51 вертикальный текст в Opera версии ниже 10.51 и Firefox версии ниже 3.5

Эти браузеры придется отлавливать с помощью Javascript (об этом скрипте подробней скоро напишем) и поворачивать текст с помощью SVG (об этом методе подробней в следующем материале). Т.к. в SVG нет автоматического переноса строк, поэтому повернутый текст будет в одну строку. Это придется учесть и динамически изменить размер блока так, чтобы текст не обрезался.

И так, имеем тот же HTML код:

<div class="firstBlock"></div>
<div id="rotateText">Текст, который будем поворачивать</div>
<div class="lastBlock"></div>

Стили для продвинутых браузеров и для IE отличаются. Чтобы разграничить воспользуемся условными комментариями:

<style type="text/css">
#rotateText {
	-moz-transform: rotate(90deg);
	-webkit-transform: rotate(90deg);
	-o-transform: rotate(90deg);
	height: 200px; /* размеры задаем сразу с учетом, что будет повернут на 90 градусов */
	width: 100px; 
	border: 2px solid red;
	margin: -50px 0 -50px 50px; /* подтягиваем отступы, образовавшиеся во время вращения */
}
</style>
<!--[if IE]>
<style type="text/css">
#rotateText {
	writing-mode:tb-rl;
	height: 100px; /* для IE размеры остаются как обычно */
	width: 200px;
	margin: 0; /* и отступы корректировать не нужно */
}
</style>
<![endif]-->
<script type="text/javascript" src="path-to/jquery-1.3.2.min.js"></script> <!--jquery для простых манипуляций с объектами-->
<script type="text/javascript" src="path-to/bdetect.js"></script> <!--скрипт для определения браузера и его версии-->
<script type="text/javascript">
function vertText()
{
	var browser = browserDetect(1),
		browserName = browser[0],
		browserVer = browser[1],
		browserVerPoints = browser[2];
		browserVer = parseFloat(browserVer+"."+browserVerPoints);
	/* внедрять SVG будем только для Opera версии ниже 10.51 и FF ниже 3.5 */
	if((browserName=="Opera" && browserVer<10.5) || (browserName=="Firefox" && browserVer<3.5))
	{
		var el = jQuery("#rotateText"),
			text = el.text(),								/* запоминаем текст */
			textLen = text.length,
			textFontStyle = el.css("font-style"),			/* узнаем текущие парамеры текста */
			textFontSize = el.css("font-size"),
			textColor = el.css("color"),
			elWidth = el.css("height"), /* определяем первоначальную ширину блока (в стилях она равна высоте) */
			elHeight = 250, 			/* подбираем высоту чтобы текст одной строкой поместился */
			textPosY = -180, 			/* подбираем координаты, чтобы текст не прилипал к границам блока */
			textPosX = 0;
			/* имя шрифта задаю непосредственно в элементе SVG text - по другому не хотел восприниматься */
		/*
			обнуляем текущий текст и добавляем SVG объект с повернутым текстом c сохраненными параметрами текста
		 */
		el
			.css({margin: "0", width: elWidth, height: elHeight+"px"})
			.text('')
			.append("<object type="image/svg+xml" data="data:image/svg+xml; charset=utf-8,<svg xmlns=''><text x='"+textPosX+"' y='"+textPosY+"' font-family='Arial' font-size='"+textFontSize+"' fill='"+textColor+"' transform='rotate(90)' text-rendering='optimizeSpeed'>"+text+"</text></svg> "></object>");
	}
}
window.onload=vertText; /* при загрузке страницы вызываем функцию поворота текста */
</script>

Демо пример. Теперь получаем следующий результат:

IE6-8, Firefox 3.5+, Opera 10.5+, Safari 3.5+, Chrome 3+ вертикальный текст в современных браузерах
Firefox версии ниже 3.5, Opera версии ниже 10.5 вертикальный текст в старых браузерах

Проверено в:

Преимущества

  • текст является текстом
  • текст можно выделить и скопировать
  • доступна возможность многострочного текста с автоматическим переносом строк (кроме некоторых старых версий браузеров)

Недостатки

  • для более старых версий Opera и FF текст будет одной строкой, плюс им потребуется включенный Javascript
  • текст может начинаться только от одного угла родительского блока — правого верхнего
  • CSS код не походит валидацию — свойства -moz-transform, -webkit-transform, -o-transform отстуствуют в спецификациях

Выводы

Пользователей, которые используют более старые версии Firefox и Opera немного и каждый день таких становится меньше. Поэтому выше описанный прием я считаю можно использовать в проектах. И хоть метод не идеален и не гибок, как приятно все же осозновать что ты можешь реализовать вертикальный текст!

По теме

Более универсальный метод — «Текст под углом»

Материалы

  • W3C :: CSS3 Text Module
  • MDC :: -moz-transform
  • Dev.Opera :: CSS3 transitions and 2D transforms
  • MSDN :: writingMode Property