Вертикальный текст и текст под углом

Задача: сделать вертикальный текст или текст под углом на странице. Рассмотрим способы решения.

Содержание статьи

  1. Использование изображения
  2. transform: rotate(<угол>)
  3. Решение для IE — writing-mode
  4. Фильтры IE — Matrix и BasicImage
  5. Применение SVG
  6. Canvas — текст на холсте

Использование изображения

Первое, что приходит в голову — не заниматься ерундой и сделать текст обычной картинкой, используя тег <img> или свойство background. Вставка <img> конечно предпочтительней — т.к. дополнительно можно прописать title и alt для поисковиков. Хотя зависит от ситуации.

Плюсы использования картинки

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

Минусы

  • нельзя выделить/скопировать, иногда может быть абсолютно недопустимо, например контакты на сайте
  • такой «текст» не индексируется поисковиками
  • при изменении текста придется менять и перезаливать картинку
  • не масштабируется
  • лишний запрос к серверу, опять же

transform: rotate(<угол>)

Вариант для современных браузеров — CSS3-свойство transform и функция трансформации rotate(<угол>). В качестве единиц измерения угла используются следующие величины:

  • градусы deg
  • грады grad
  • повороты turn
  • радианы rad

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

Сделаем текст вертикальным, применив трансформацию:

elem {
  -webkit-transform: rotate(90deg); /* не забываем префиксные свойства */
  -moz-transform: rotate(90deg);
  -ms-transform: rotate(90deg);
  -o-transform: rotate(90deg);
  transform: rotate(90deg);
}
Пример transform: rotate()
Пример transform: rotate()

Плюсы трансформации

  • работает во всех современных браузерах, включая IE9+
  • есть возможность выделить/скопировать текст
  • гибкое решение, поменяли значение — получили другой угол

Минусы

  • отсутствие кроссбраузерности — не работает в IE<9

Решение для IE — writing-mode

Невероятно, но способ сделать вертикальный текст в Internet Explorer существует еще с допотопных времен, а именно со времен появления 6-ой версии. И способ даже проще, чем в современных браузерах. Отвечает за это свойство CSS writing-mode со значением tb-rl.

Добавим writing-mode в вышеприведенный код и получим кроссбраузерный вариант вертикального текста:

elem {
  -webkit-transform: rotate(90deg);
  -moz-transform: rotate(90deg);
  -ms-transform: rotate(90deg);
  -o-transform: rotate(90deg);
  transform: rotate(90deg);
  writing-mode: tb-rl; /* для IE ниже 9 */
}

Конечно, элементы с применением trasform: rotate() и writing-mode в потоке ведут себя по разному — придется немного потрудится над стилизацией, а также разграничить стили для IE. Более наглядно это продемонстрировано в демо-примере.

Плюсы writing-mode

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

Минусы

  • круг применения значительно ограничен: только для IE и только для вертикального текста

Фильтры IE — Matrix и BasicImage

А что, если нам нужно видеть в Internet Explorer не вертикальный текст, а другой вариант, под другим углом? Ведь старые браузеры не поддерживают трансформации. К счастью, не все так плохо — ведь еще есть фильтры Matrix, аналог трансформаций CSS3 и BasicImage, который успешно применяется в некоторых случаях. Синтаксис фильтров таков:

elem {
  -ms-filter:"progid:DXImageTransform.Microsoft.Matrix(<параметры>)"; /* правило для IE8, должно идти первым */
   filter:progid:DXImageTransform.Microsoft.Matrix(<параметры>); /* IE6,7 */
}

elem {
  -ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(<параметры>)"; /* аналогично */
  filter:progid:DXImageTransform.Microsoft.BasicImage(<параметры>);
}

Параметры Matrix:

  • enabled — включение или выключение фильтра, принимает значения true (включен) и false (выключен). По умолчанию true
  • Dx — смещение элемента по горизонтали, положительное значение — смещение вправо, отрицательное — смещение влево. Единицы измерения — пиксели
  • Dy — смещение элемента по вертикальное, положительное значение — смещение вниз, отрицательное — смещение вверх. Единицы измерения — пиксели
  • FilterType — задает тип пикселов нового содержимого, принимает значения bilinear (по умолчанию) и nearest neighbor
  • M11, M12, M21, M22 — значения fM11, fM12, fM21, fM22 матричных преобразований, принимают значения от 0 до 1.0
  • SizingMethod — указывает, должен ли элемент изменять свои размеры, чтобы включить результаты работы фильтра. Принимает значения clip to original (по умолчанию — не изменяет размеры) и auto expand (наоборот).

Честно говоря, фильтры не заслуживают такого дотошного внимания, есть у них существенные недостатки. Я нашел отличный сервис для трансформаций IE — IE’s CSS3 Transforms Translator. Выставляете параметры и на выходе получаете готовый результат — нет нужды заниматься переводами самостоятельно.

Так выглядит поворот текста на 45° с применением Matrix:

elem {
   -ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.7071067811865474, M12=-0.7071067811865477, M21=0.7071067811865477, M22=0.7071067811865474, SizingMethod='auto expand')"; /* IE8+ */
   filter: progid:DXImageTransform.Microsoft.Matrix(
            M11=0.7071067811865474,
            M12=-0.7071067811865477,
            M21=0.7071067811865477,
            M22=0.7071067811865474,
            SizingMethod='auto expand'); /* IE6,7 */
}

BasicImage также имеет много параметров, однако для решения поставленной задачи понадобится только один — rotation. Параметр позволяет указать поворот элемента с шагом в 90°, принимает значения от 0 до 3. Примеры поворотов:

elem-90 {
  -ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)"; // 90°
  filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);
}

elem-180 {
  -ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)"; // 180°
  filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);
}

elem-270 {
  -ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)"; // 270°
  filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);
}

Плюсы фильтров

  • текст выделяется/копируется

Минусы

  • фильтры значительно тормозят браузер
  • использование фильтров отключает сглаживание шрифтов — некрасиво
  • работают только для IE

Применение SVG

Один из отличных способов сделать текст под углом — использование SVG-графики. С появлением HTML5 стало возможным внедрение SVG прямо в документ. Например так выглядит вставка текста в SVG под углом 45°:

<svg width="12" height="140" class="svg-text">
  <text x="0" y="0" transform="rotate(90)">Вертикальный текст</text>
</svg>

Как видите, для текста используется тег <text> с координатами x и y и атрибутом transform.

Если нужно сделать текст вертикальным, как альтернативу в элемент <text> следует добавить style="writing-mode: tb":

<svg width="12" height="140" class="svg-text">
  <text style="writing-mode: tb">Вертикальный текст</text> <!-- tb - top to bottom -->
</svg>

writing-mode: tb работает везде, кроме Firefox (на момент написания 19.0). Лучше использовать transform="rotate()".

Плюсы использования SVG

  • текст выделяется/копируется/масштабируется
  • возможно указать любой угол
  • доступна стилизация через CSS
  • работает во всех современных браузерах

Минусы

  • SVG не поддерживается IE<9, используем библиотеку Raphael для эмуляции SVG через VML, чтобы добиться кроссбраузерности

Canvas — текст на холсте

Одна из существенных новых фишек HTML5 — элемент <canvas>, или попросту холст, на котором рисуются разные штуки. Точно так же холст помогает реализовать текст под углом.

Добавим элемент на страницу:

<canvas id="canvas" width="18" height="150">
  <p>Извините, ваш браузер не поддерживает canvas.</p>
</canvas>

Начнем использовать холст при помощи JS. Напишем функцию draw() Получим его id и контекст.

function draw() {
  var cvs, ctx; // холст и контекст
  cvs = document.getElementById('canvas');

  // проверка поддержки метода getContext
  if(cvs & cvs.getContext) {
    ctx = cvs.getContext('2d');
  }
}

Теперь воспользуемся методом контекста rotate(<угол>). rotate(<угол>) позволяет повернуть холст на заданный угол. Метод принимает значения радиан, вот примеры смещения на 45° и 90°.

ctx.rotate(Math.PI / 2); // смещение на 45°
ctx.rotate(Math.PI / 4); // смещение на 90°

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

Займемся текстом. За рисование текста на холсте отвечает метод fillText(). Синтаксис метода:

fillText(text, x, y [, maxWidth]);
  • text — сам текст, который необходимо нарисовать
  • x, y — координаты относительно верхнего левого угла
  • maxWidth — необязательный параметр, позволяет указать максимальную ширину текста

Добавим метод в наш скрипт:

ctx.fillText('Вертикальный текст', 0, 0);

Повесим готовую функцию на событие onload документа. Вот полный сценарий:

onload = function() {
  draw();
}

function draw() {
  var cvs, ctx; // холст и контекст
  cvs = document.getElementById('canvas');

  // проверка поддержки метода getContext
  if(cvs & cvs.getContext) {
    ctx = cvs.getContext('2d');

    ctx.font = '16px Arial'; // небольшие настройки шрифта - размер и семейство
    ctx.rotate(Math.PI / 2); // повернули на 90 градусов
    ctx.fillText('Вертикальный текст', 0, 0); // нарисовали на холсте
  }
}

Код простой, но этого достаточно для вывода текста под любым углом.

Плюсы canvas

  • поддерживается всеми современными браузерами

Минусы

  • текст не выделяется — графика все-таки
  • не кроссбраузерно, в IE<9 не работает

Итоги

Способов сделать текст под углом превеликое множество, но Internet Explorer добавляет существенную ложку дегтя — нет ни одного кроссбраузерного метода реализации, приходится искать альтернативные библиотеки и свойства CSS. В принципе то что есть сейчас позволит вам решить задачу, но все же хочется быстрого отмирания старых IE.

Результат

Еще раз все примеры:

Ресурсы по теме

Рейтинг статьи

Похожие статьи

Комментарии читателей

  1. Вася:

    Толково написано. Больше бы таких статей встречать в интернете вместо всякого обрывистого шлака.

  2. Вася:

    Хорошая статья.

  3. Большое вам спасибо! А вы будете писать ещё на эту тему?

  4. Nadezda Krivohizina:

    Сенкс за инфу, почитал с интересом

  5. Отличная статья! Если бы не IE, то можно было бы подумать что жизнь удалась. :)
    Правда, сам я пока еще не использую нигде текст под углом. Нужно будет начать применять.

Добавить комментарий