- PVSM.RU - https://www.pvsm.ru -

display: flex;
justify-content: center; /* Горизонтальное центрирование */
align-items: center; /* Вертикальное центрирование */
Не спрашивайте, почему вам нужно запомнить четыре слова вместо просто горизонтальное/вертикальное; всё равно лучше, чем было до этого.
Ещё можно использовать сетку:
display: grid;
justify-items: center; /* Горизонтальное центрирование */
align-items: center; /* Вертикальное центрирование */
Также не спрашивайте, почему выражение justify-content стало justify-items.
Если вы не прочь немного вспомнить школу, то можем опереться на фундаментальные принципы:

Да даже ChatGPT умеет центрировать контент:

ChatGPT: Чтобы центрировать один прямоугольник внутри другого, нужно совместить их центры. Предположим, у нас есть два прямоугольника — одни внутри другого.
Выберем обозначения:
Чтобы центрировать внутренний прямоугольник во внешнем, нужно установить координаты его центра (x2, y2) равными координатам центра внешнего прямоугольника (x1, y1).
Значит, формулами для центрирования внутреннего прямоугольника во внешнем будут:
x2 = x1
y2 = y1
Это обеспечит совпадение центров внутреннего и внешнего прямоугольников по вертикали и горизонтали, а значит и центрирование внутреннего прямоугольника во внешнем.
Хорошо, пусть не сразу, но в конечном итоге он находит решение. Я лишь хочу сказать, что все знают, как делать центрирование. Это просто. И если вы запутаетесь, то информация всегда под рукой.
Тем не менее, когда мы смотрим на реальные приложения, то видим, что эти методы не используются. Вот пример:

Или вот:

Или даже такой:

То есть между «знанием как» и фактическим применением этого знания явно возникает какой-то пробел.

Теоретически между теорией и практикой разницы нет. К сожалению, мы живём в практическом мире. Так что же происходит? Будем разбираться.
В шрифтах происходит одно из самых серьёзных нарушений. Плохо выровненный текст встречается повсюду. Приведу примеры.
Его не может выровнять ни Apple:

Ни Microsoft:

Ни GitHub:

Ни Valve:

Ни Slack:

Ни Telegram:

Ни Google Maps:

Честно говоря, я могу с ходу привести бесконечный список примеров криво выровненных надписей кнопок:

Думаю, смысл вы поняли. Многочисленные компании — крупные и малые, в нативной или веб-среде — имеют проблемы с выравниванием текста.
Если вам недостаточно примеров со шрифтами, то очередной проблемой является высота строки.
Это довольно сложная тема, и для лучшего её понимания советую каноническую статью Винсента де Оливейры Deep dive CSS: font metrics, line-height and vertical-align [1].
Вот как это выглядит на практике. Slack:

Notion:

Airbnb:

YouTube:

Выровнять два элемента в разных контейнерах практически невозможно:

Многие пробовали:

Но немногие преуспели:

Помешать может CSS (разные элементы управления имеют разные значения, которые нужно отменить, прежде чем начать выравнивание):

И здесь нет лёгкого решения. Просто закатываем рукава и ныряем в спецификации.
Иконки подобны небольшим прямоугольникам, вставляемым в текст. Поэтому здесь актуальны все те же проблемы, которые связаны с текстом и высотой строки. Выравнивание иконок рядом с текстом реально непростая задача.
Atom:

Бывший Twitter:

iOS:

Mozilla:

YouTube:

Иногда иконка выигрывает у текста:

Иногда текст выигрывает у иконки:

Иногда оба проигрывают:

Некоторые иконки — это просто старые элементы управления HTML:

Некоторые стилизованы:

Спасибо bee [2] за скриншот
Иногда люди достигают точного выравнивания креативным способом:

Но в целом это безнадёжная игра:

Проблема в том, что CSS нам тут не поможет. У свойства vertical-align есть 13 возможных значений, но ни одно из них не выровняет иконку как следует:

Ближе всего text-align: middle, но это свойство выравнивает по x-height, а не cap-height, которая по-прежнему выглядит криво:

Именно поэтому люди так любят веб-программирование. Здесь для них всегда есть вызов.
Выравнивать прямоугольники относительно легко, а вот текст — трудно. Иконки прямоугольные. А что получится, если поместить их в файл шрифтов?
Теперь мы ничего не сможем выровнять:

Равно как и установить размер иконок. В примере выше для всех иконок были установлены одинаковые размер шрифта и высота строки. Как видите, в итоге все они получились разных размеров с разными отступами, и ни одна не выровнена как следует.
Несмотря на множество их недостатков и практически полное отсутствие плюсов, компании стремятся использовать иконки повсюду. И вот что мы получаем в итоге:

macOS 10.14 → macOS 10.15
Обратите внимание, что операторы утратили вертикальное выравнивание и получились размытыми. Всё из-за переключения на иконочный шрифт.
В Apple были настолько привержены к использованию иконочных шрифтов, что даже испортили кнопку записи в QuickTime:

Только посмотрите на неё:

Да, так она и выглядит по сей день. Как и калькулятор. Но это далеко не единственный пример. Вот ещё один:

Второй:

Третий:

Четвёртый:

Пятый:

Шестой:

Седьмой:

То же, что и в случае выравнивания текста — бесконечное число примеров криво выровненных иконок.
Но с выравниванием проблемы наблюдаются не только у программистов. То же касается и дизайнеров:

Текущая версия [3]/моё исправление
Проблема с иконками в том, что иногда для получения красивой картинки вам нужно учесть их форму:

Плохое выравнивание / хорошее выравнивание
Треугольники особенно проблематичны:

Иногда они уезжают влево:

Иногда вправо:

А могут оказаться задраны (здесь снова высота строки):

Вы можете решить, что трудно добиться выравнивания только по вертикали. Но нет — по горизонтали тоже бывают сложности:

Я не думаю, что для этого есть какие-то глубокие причины, помимо банальной неаккуратности самих людей:

Ну серьёзно!

Разве так можно сделать намеренно?

Ну не знаю. Причём иконок это тоже касается:

Как и текста:

Итак, в чём проблема?
Всё начинается со шрифта. Сейчас рамка текстового блока выглядит так:

Проблема в том, что она может выглядеть и так:

Или так:

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

Текст сместится! Несмотря на то, что прямоугольники идеально отцентрованы. Но даже если метрики шрифта и могут исказиться, это не значит, что так и есть.
Что же происходит в реальности?
В реальности метрики большинства шрифтов слегка искажены. Во многих эти искажения значительны:

Проценты указаны для cap-height
И 10% — это немало. При размере шрифта 13 — это целый пиксель. А при двухкратном масштабировании уже два! Это легко заметить.
По сути, именно из-за Segoe UI интерфейс GitHub в Windows выглядит так:

Решение здесь простое: использовать рамки вокруг текста. Тогда центрировать шрифт будет легко.

Если вы используете сервис Figma, то он это умеет (хоть и не по умолчанию):

Если вы дизайнер шрифтов, то можете упростить всем жизнь, настроив метрики так, чтобы ascender − cap-height = descender:

Вот тот же принцип наглядно:

Важно! Вам не обязательно реально растягивать восходящие/спусковые элементы букв до этих границ. Как видно по картинке, у меня область под восходящую часть используется мало. Просто сделайте так, чтобы их размеры совпадали.
Как в веб-, так и в нативной разработке для избежания лишней головной боли выбирайте шрифт, который уже соответствует этому правилу. Например, SF Pro Text, Inter и Martian Mono ему следуют, значит, будут отлично центрироваться без дополнительных хлопот.
Подробнее читайте в статье: Font size is useless; let’s fix it [4].
С позиции разработки ситуация несколько сложнее.
Первым делом вам нужно понимать, какой шрифт вы будете использовать. К сожалению, предложенное мной решение не сработает, если вы планируете подстановочные шрифты.
Возьмём используемый на этой странице IBM Plex Sans. Вот его метрики:

Устанавливая font-size, вы устанавливаете UPM (это значение также будет равно 1em). Тем не менее фактическое занимаемое текстовым блоком пространство находится между областями восхождения (ascender) и спуска (descender).

Путём простых расчётов мы выясняем, что нам поможет добавление padding-bottom: 0.052em:

Должно получиться так:

Либо в реальном CSS (в оригинале можно выделить текст, чтобы увидеть окружающую его рамку, — прим. пер.):

Нужные метрики шрифтов можно найти по ссылке opentype.js.org/font-inspector.html [5] (ascender, descender, sCapHeight).
Теперь, когда мы с этим разобрались, можно без особых проблем выравнивать и иконки. Вы устанавливаете vertical-align: baseline и затем смещаете их вниз на (iconHeight - capHeight) / 2:

К сожалению, для этого необходимо знать метрики шрифта и размер иконок. Но такое решение хотя бы работает:

Также в оригинале можно выделить текст, чтобы увидеть рамку, — прим. пер.
ПРЕКРАТИТЕ.
ИСПОЛЬЗОВАТЬ.
ШРИФТЫ.
ДЛЯ.
ИКОНОК.
Используйте обычный формат изображений. Тот самый — с шириной и высотой.
Я даже нарисовал для вас логическую блок-схему, чтобы было проще принять решение:

Вы только взгляните, как усердно в Apple стараются вписать галочку в прямоугольник, а прямоугольник разместить рядом с текстовой меткой:

И всё безуспешно!
Что может быть проще, чем выровнять два прямоугольника. Но что может быть сложнее, чем пытаться выровнять текст, вокруг которого есть произвольный объём пустого пространства.
Победить в этой игре невозможно.
Мы, как разработчики, можем математически выровнять лишь идеальные прямоугольники. Поэтому всё, что требует ручной подстройки, заключайте в достаточно большой прямоугольник и визуально выравнивайте иконку внутри:

Будьте внимательны. Будьте осторожны. Плохое выравнивание может испортить прекрасный интерфейс:

И напротив, с правильно выровненным текстом ваш интерфейс обретёт утончённую красоту:

Даже если это трудно. Даже если инструменты создают неудобства. Даже если приходится искать решения. Я верю, что вместе мы можем разобраться, как засунуть один прямоугольник в другой ровно.
Я, например, хочу жить в мире красиво выровненных пользовательских интерфейсов. И верю, что вы хотите того же.
В конце концов приложенные старания того стоят.
Всех благ!
Автор: Дмитрий Брайт
Источник [6]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/news/391206
Ссылки в тексте:
[1] Deep dive CSS: font metrics, line-height and vertical-align: https://iamvdo.me/en/blog/css-font-metrics-line-height-and-vertical-align
[2] bee: https://habr.com/ru/users/bee/
[3] Текущая версия: https://culturedcode.com/things/blog/2024/02/things-for-apple-vision-pro/
[4] Font size is useless; let’s fix it: https://tonsky.me/blog/font-size/
[5] opentype.js.org/font-inspector.html: https://opentype.js.org/font-inspector.html
[6] Источник: https://habr.com/ru/companies/ruvds/articles/810311/?utm_source=habrahabr&utm_medium=rss&utm_campaign=810311
Нажмите здесь для печати.