Простое вертикальное центрирование текста с помощью SVG

Лиа Веру 26 марта 2013

Существует множество способов вертикального выравнивания текста в контейнере произвольных размеров:

  • использование display:table;
  • Flexbox;
  • хаки с использованием display:inline-block;
  • оборачивание текста в дополнительный элемент и его абсолютное позиционирование;

…и, вероятно, множество других, о которых я уже забыла.

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

Всё это началось, когда я обнаружила в SVG-спецификации свойство text-anchor. Оно определяет, куда ссылаются атрибуты x и y элемента <text> (см. подробнее про x и про y в спецификации SVG. — прим. редактора). Волшебство начинается, когда мы задаем в качестве значения middle и атрибуты x и y указывают на центр текста. Так что если задать значения 50%, они будут указывать в центр SVG-контейнера. А если высота и ширина установлены в 100%, текст окажется в центре контейнера, которым может быть любой HTML-элемент!

Следует учитывать, что центрируется в том числе и базовая линия текста, так что я постаралась найти способ адекватно её сместить. Установка dominant-baseline:middle для элемента <text> вроде бы решила проблему везде, кроме IE. В результате я просто задала элементу <text> dy=".3em", что сработало везде, но может требовать настройки сообразно реальной высоте строки (см. подробнее про элемент <text> и про атрибут dy в спецификации SVG. — прим. редактора).

Кроме того, я вижу у метода следующие недостатки:

  • избыточная разметка (а именно, 2 элемента: <svg> и <text>);
  • если текст занимает больше одной строки, вам придётся разбивать его на строки вручную;
  • не получится применить некоторые новомодные CSS-свойства: например, text-shadow в Chrome будет работать, а в Firefox — нет, поскольку формально оно всё ещё не входит в спецификацию SVG;
  • вам придётся дублировать цвет текста в свойстве fill, так как SVG не понимает СSS-свойство color (значение цвета из CSS можно получить с помощью fill:currentColor — прим. редактора).

Но есть и некоторые достоинства:

  • не нужно трогать родительский контейнер;
  • мягкая деградация в браузерах, не поддерживающих SVG;
  • абсолютно доступный, не помешает SEO;
  • отлично работает в IE9, в отличие от Flexbox;
  • можно использовать любые стили для текста, доступные в SVG. Например, stroke!

Результат показан ниже, посмотреть на код и поиграть с ним можно в Даблете.

Проверено в последних Chrome, Firefox, IE9+. Несмотря на то, что этот способ не подойдёт для всех случаев, надеюсь, он вам пригодится.

Перевод оригинальной записи «Easily center text vertically, with SVG!» Лии Веру (Lea Verou). Переведено и опубликовано с разрешения автора.

Перевод выполнил Антон Немцев (SilentImp).

Теги: ,

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

  1. tibalt 26 марта 2013 в 20:51

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

  2. SilentImp 26 марта 2013 в 20:54

    Поддерживает, просто надо переводы строки вручную делать.

  3. Лев Солнцев 29 марта 2013 в 0:47

    Если я я правильно понял, многострочный текст будет гораздо сложнее: позиционировать каждую строчку вручную. Имхо, такой метод пригодится только если хочется применить эффекты SVG, такие как градиенты на тексте, обводка, которая в SVG тоже может быть богаче оформлена, не везде, но будут работать и фильтры. В противном случае проще и кросс-браузернее обычный трюк с большим line-height.

  4. SilentImp 29 марта 2013 в 12:04

    Все так. Если честно, пока не встретил случая в своей работе когда такой подход был бы оправдан. Но Леа права. Лучше иметь больше инструментов в своей работе, чем меньше.

Перейти к началу