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

Перевод «Easily center text vertically, with SVG!»

Перевод Антон Немцев

Редактура Вадим Макеев

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

  • использование 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+. Несмотря на то, что этот способ не подойдёт для всех случаев, надеюсь, он вам пригодится.