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