Заявляю: «Мы, как цивилизация, разучились использовать центрирование». Ну то есть мы, конечно, знаем, как это делать — очень просто:
display: flex;
justify-content: center; /* Горизонтальное центрирование */
align-items: center; /* Вертикальное центрирование */
Не спрашивайте, почему вам нужно запомнить четыре слова вместо просто горизонтальное/вертикальное; всё равно лучше, чем было до этого.
Ещё можно использовать сетку:
display: grid;
justify-items: center; /* Горизонтальное центрирование */
align-items: center; /* Вертикальное центрирование */
Также не спрашивайте, почему выражение
justify-content
стало justify-items
.Если вы не прочь немного вспомнить школу, то можем опереться на фундаментальные принципы:
Да даже ChatGPT умеет центрировать контент:
ChatGPT: Чтобы центрировать один прямоугольник внутри другого, нужно совместить их центры. Предположим, у нас есть два прямоугольника — одни внутри другого.
Выберем обозначения:
- (x1, y1) будут координатами центра внешнего прямоугольника.
- w1, h1 будут шириной и высотой внешнего прямоугольника.
- (x2, y2) будут координатами центра внутреннего прямоугольника.
- w2, h2 будут шириной и высотой внутреннего прямоугольника.
Чтобы центрировать внутренний прямоугольник во внешнем, нужно установить координаты его центра (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.
Вот как это выглядит на практике. Slack:
Notion:
Airbnb:
YouTube:
Выровнять два элемента в разных контейнерах практически невозможно:
Многие пробовали:
Но немногие преуспели:
Помешать может CSS (разные элементы управления имеют разные значения, которые нужно отменить, прежде чем начать выравнивание):
И здесь нет лёгкого решения. Просто закатываем рукава и ныряем в спецификации.
▍ Иконки
Иконки подобны небольшим прямоугольникам, вставляемым в текст. Поэтому здесь актуальны все те же проблемы, которые связаны с текстом и высотой строки. Выравнивание иконок рядом с текстом реально непростая задача.
Atom:
Бывший Twitter:
iOS:
Mozilla:
YouTube:
Иногда иконка выигрывает у текста:
Иногда текст выигрывает у иконки:
Иногда оба проигрывают:
Некоторые иконки — это просто старые элементы управления HTML:
Некоторые стилизованы:
Спасибо bee за скриншот
Иногда люди достигают точного выравнивания креативным способом:
Но в целом это безнадёжная игра:
Проблема в том, что CSS нам тут не поможет. У свойства
vertical-align
есть 13 возможных значений, но ни одно из них не выровняет иконку как следует:Ближе всего
text-align: middle
, но это свойство выравнивает по x-height
, а не cap-height
, которая по-прежнему выглядит криво:Именно поэтому люди так любят веб-программирование. Здесь для них всегда есть вызов.
▍ Шрифты иконок
Выравнивать прямоугольники относительно легко, а вот текст — трудно. Иконки прямоугольные. А что получится, если поместить их в файл шрифтов?
Теперь мы ничего не сможем выровнять:
Равно как и установить размер иконок. В примере выше для всех иконок были установлены одинаковые размер шрифта и высота строки. Как видите, в итоге все они получились разных размеров с разными отступами, и ни одна не выровнена как следует.
Несмотря на множество их недостатков и практически полное отсутствие плюсов, компании стремятся использовать иконки повсюду. И вот что мы получаем в итоге:
macOS 10.14 → macOS 10.15
Обратите внимание, что операторы утратили вертикальное выравнивание и получились размытыми. Всё из-за переключения на иконочный шрифт.
В Apple были настолько привержены к использованию иконочных шрифтов, что даже испортили кнопку записи в QuickTime:
Только посмотрите на неё:
Да, так она и выглядит по сей день. Как и калькулятор. Но это далеко не единственный пример. Вот ещё один:
Второй:
Третий:
Четвёртый:
Пятый:
Шестой:
Седьмой:
То же, что и в случае выравнивания текста — бесконечное число примеров криво выровненных иконок.
▍ Недостаток навыков
Но с выравниванием проблемы наблюдаются не только у программистов. То же касается и дизайнеров:
Текущая версия/моё исправление
Проблема с иконками в том, что иногда для получения красивой картинки вам нужно учесть их форму:
Плохое выравнивание / хорошее выравнивание
Треугольники особенно проблематичны:
Иногда они уезжают влево:
Иногда вправо:
А могут оказаться задраны (здесь снова высота строки):
▍ Горизонтальное центрирование
Вы можете решить, что трудно добиться выравнивания только по вертикали. Но нет — по горизонтали тоже бывают сложности:
Я не думаю, что для этого есть какие-то глубокие причины, помимо банальной неаккуратности самих людей:
Ну серьёзно!
Разве так можно сделать намеренно?
Ну не знаю. Причём иконок это тоже касается:
Как и текста:
▍ Что делать: дизайнерам?
Итак, в чём проблема?
Всё начинается со шрифта. Сейчас рамка текстового блока выглядит так:
Проблема в том, что она может выглядеть и так:
Или так:
А что произойдёт, если попробовать выровнять текст, центрировав его рамку?
Текст сместится! Несмотря на то, что прямоугольники идеально отцентрованы. Но даже если метрики шрифта и могут исказиться, это не значит, что так и есть.
Что же происходит в реальности?
В реальности метрики большинства шрифтов слегка искажены. Во многих эти искажения значительны:
Проценты указаны для 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.
▍ Что делать: веб-разработчикам?
С позиции разработки ситуация несколько сложнее.
Первым делом вам нужно понимать, какой шрифт вы будете использовать. К сожалению, предложенное мной решение не сработает, если вы планируете подстановочные шрифты.
Возьмём используемый на этой странице IBM Plex Sans. Вот его метрики:
Устанавливая font-size, вы устанавливаете UPM (это значение также будет равно
1em
). Тем не менее фактическое занимаемое текстовым блоком пространство находится между областями восхождения (ascender) и спуска (descender).Путём простых расчётов мы выясняем, что нам поможет добавление
padding-bottom: 0.052em
:Должно получиться так:
Либо в реальном CSS (в оригинале можно выделить текст, чтобы увидеть окружающую его рамку, — прим. пер.):
Нужные метрики шрифтов можно найти по ссылке opentype.js.org/font-inspector.html (ascender, descender, sCapHeight).
Теперь, когда мы с этим разобрались, можно без особых проблем выравнивать и иконки. Вы устанавливаете
vertical-align: baseline
и затем смещаете их вниз на (iconHeight - capHeight) / 2
:К сожалению, для этого необходимо знать метрики шрифта и размер иконок. Но такое решение хотя бы работает:
Также в оригинале можно выделить текст, чтобы увидеть рамку, — прим. пер.
▍ Что делать: с иконочными шрифтами?
ПРЕКРАТИТЕ.
ИСПОЛЬЗОВАТЬ.
ШРИФТЫ.
ДЛЯ.
ИКОНОК.
Используйте обычный формат изображений. Тот самый — с шириной и высотой.
Я даже нарисовал для вас логическую блок-схему, чтобы было проще принять решение:
Вы только взгляните, как усердно в Apple стараются вписать галочку в прямоугольник, а прямоугольник разместить рядом с текстовой меткой:
И всё безуспешно!
Что может быть проще, чем выровнять два прямоугольника. Но что может быть сложнее, чем пытаться выровнять текст, вокруг которого есть произвольный объём пустого пространства.
Победить в этой игре невозможно.
▍ Что делать: с визуальной корректировкой?
Мы, как разработчики, можем математически выровнять лишь идеальные прямоугольники. Поэтому всё, что требует ручной подстройки, заключайте в достаточно большой прямоугольник и визуально выравнивайте иконку внутри:
▍ Что делать: всем?
Будьте внимательны. Будьте осторожны. Плохое выравнивание может испортить прекрасный интерфейс:
И напротив, с правильно выровненным текстом ваш интерфейс обретёт утончённую красоту:
Даже если это трудно. Даже если инструменты создают неудобства. Даже если приходится искать решения. Я верю, что вместе мы можем разобраться, как засунуть один прямоугольник в другой ровно.
Я, например, хочу жить в мире красиво выровненных пользовательских интерфейсов. И верю, что вы хотите того же.
В конце концов приложенные старания того стоят.
▍ Отдельная благодарность
Всех благ!
Telegram-канал со скидками, розыгрышами призов и новостями IT ?
Комментарии (43)
max851
26.04.2024 13:39+10Омг. Как развидеть статью? Я раньше не видел проблем, а теперь меня везде в интерфейсах раздражает то же самое
inkelyad
26.04.2024 13:39+6xkcd-1015: Kerning
VADemon
26.04.2024 13:39+5Нет, надо чтобы на всю жизнь въелось: https://method.ac/type/
Управление стрелками на клавиатуре.
abt33
26.04.2024 13:39+11В университете студент подходит к бородатому профессору и спрашивает:
— Добрый день! Извините, а можно вас спросить?
— Конечно, спрашивайте, молодой человек.
— Скажите, профессор, вот Вы, когда спать ложитесь, бороду на одеяло или под одеяло кладёте?
Профессор после небольшой паузы отвечает:
— А вот, знаете, молодой человек, ответить я вам не смогу. Как-то не задумывался.
— Ну, извините, пожалуйста.
Через неделю профессор с кругами под глазами встречает в коридоре того же студента и хватает за грудки:
— Ну ты и сволочь! Неделю уже спать не могу — и так неудобно, и так неудобно!
yri066
26.04.2024 13:39+8Давно слышал шутку про центрирование в css (примерно звучала так: в css есть 12 способов центрировать div, и ни один не работает), а тут этой теме посвящен целый пост, браво!
PsihXMak
26.04.2024 13:39Эта проблема встречается так часто, что я стал думать, что это такой новомодный дизайнерский стиль. Будто специально смещают центрирование.
IronLimon
26.04.2024 13:39Спасибо, что не скупился на примеры! Тоже мозолит глаза когда что-то не по центру в приложении, которое разрабатываем. На счет логотипа Apple и кнопок на GitHub'е думаю что это фича — иногда асимметрия выглядит более выигрышно, поскольку мы привыкли ее видеть в реальной жизни.
nin-jin
26.04.2024 13:39Надо ли говорить, что в $mol таких проблем нет, благодаря использованию MDD?
И, кстати, правильное центрирование блока в CSS выглядит так:
margin: auto
Spaceoddity
26.04.2024 13:39+2Это не правильное центрирование. Для подобного "центрирования" вам необходимо обойти довольно серьёзные ограничения:
Для того чтобы свойство
margin: auto
позволило бы нам соответствующим образом выровнять элемент, нужно, чтобы были бы выполнены следующие условия:Заданы ширина и высота элемента.
Задано свойство элемента
position: absolute
.
Самый простой работающий способ в CSS:
{ display: flex; justify-content: center; align-items: center; }
nin-jin
26.04.2024 13:39Не знаю, что вы цитируете, но этот текст устарел не менее чем на 10 лет. А ваш код может приводить к обрезанию контента. Перечитайте внимательнее доки по css-flexbox модели.
Spaceoddity
26.04.2024 13:39+1Не знаю, что вы цитируете
https://habr.com/ru/companies/ruvds/articles/494716/
Проблема с флексбоксами обычно как раз противоположная - не хотят они никак контент обрезать, так и норовят растянуться до максимума (название технологии как бы обязывает).
nin-jin
26.04.2024 13:39Вы бы хоть дочитали до конца статью, на которую ссылаетесь. И всё прекрасно они обрезают, просто поведение по умолчанию не самое практичное.
SadOcean
26.04.2024 13:39+3Пожалуй это можно занести в анналы:
Сложнейшие проблемы программирования:
- Инвалидация кеша
- Именование
- Нентрирование
Справедливости ради, во многих приведенных вами примерах было корректное центрирование либо по телу, либо по обводу шрифта.
К сожалению иногда и это смотрится криво.
SadOcean
26.04.2024 13:39+4Отличная статья, спасибо
Тоже постоянно вижу эту боль, пусть и держу ее внутри.
Как говорится, хочешь сделать плохо другу - научи его видеть плохой кернинг
0x2E757
26.04.2024 13:39+2Проблема очень актуальная и та еще головная боль для верстальщика, но корень проблемы в том, что всем плевать, особенно конечному пользователю. Людей нисколько не смущает в край уехавшая верстка, отвалившиеся шрифты, цветовые схемы и прочее, лишь бы данные отображались, кнопки нажимались. Современный тренд на ребрендинги так же усугубляет ситуацию, люди очень быстро привыкают, что не важно как и что выглядит, через время все равно поменяется...
Но главный нюанс в том, что такие вещи не то что беспокоят, а хотя бы оказываются замеченными в основном специалистами. Для обывателя это вещи из разряда "всю жизнь этого не замечал, но вот прочитал пост, и боже, как теперь это развидеть".
P.S. Параграф с "неправильным" и "исправленным" чекбоксом немного расстроил, ибо у дизайнера он как раз был "правильный". Центрирование это не всегда выравнивание по границам, порой это выравнивание по ключевой точке/элементу аля центру тяжести, с чем дизайнер как раз вполне себе справился, а в "исправленной" версии этот принцип нарушен.
Daimos
26.04.2024 13:39+1Возможно потому, что люди не идеальные и не симметричные сами по себе, как и окружающий мир вокруг и поэтому не видят в этом проблемы.
SemyonVyatskov
26.04.2024 13:39+2Посмотрел, практически всё можно либо не заметить (я специально вглядывался, чтобы понять, что же по мнению автора статьи не так с отдельными изображениями), либо посчитать легкой асимметрией, то есть самостоятельным дизайном, с которым все хорошо, так и задумывалось. Дизайнерский перфекционизм?...
wadowad
26.04.2024 13:39+2Вы затронули очень обширный пласт. Давайте для начала разберёмся с центрированием текста по вертикали в банальной кнопке. Сместить для какого-то конкретного шрифта не является проблемой. Но в какую сторону нужно смещать? Если центрировать по заглавным буквам, то надпись будет казаться ниже. Если центрировать по прописным, то надпись будет казаться выше. Т.е. нужно где-то посередине. Но как именно?
murkin-kot
26.04.2024 13:39+2Выравнивание иконок с текстом по baseline (нижний край текста без выступающих вниз "закорючек") выглядит очень даже хорошо. Не факт, что выравнивание иконок с центровкой какой-то части текста, без учёта baseline, выглядит лучше. Поэтому часть примеров в статье весьма спорные.
NikitaBogdanov
26.04.2024 13:39+1Что интересно никто даже не упомянул что в случае смены языка например на арабский то вся эта центровка вообще лесом)
polar_winter
26.04.2024 13:39Крутой совет - использовать изображение вместо шрифтов и прочее. А потом удивляемся почему у нас приложоение весит 1 гиг, а функционала на 10кб. Компрьютер спосбоной расчитать траекторию сотен ракетиза мгновенеие меньше секунды, не может открыть эксель. Неплоха иметь графические эти навороты за нулевую стоимость.
Но реальность такова, что я сейчас не могу пользоваться обычным вай-фай дома из-за перегрузки частот. Хоть сайт обычного сбербанка конечно похарашел. Но грузиться уже ощутимое время. С вот этой дебильной приветсвенной страницей. С учетом того, им стало пользоваться сложнее из-за, в целом изменения для меня - отрицательные.
Сейчас появляется стойкое чувство, что консоль - лучший человеко-машинный интерфейс. А не вот эти интерфейс от Татьяныча, не превращаюсь я в деда?
glycol
Очень правильная статья, я тоже постоянно везде замечаю кривое центрирование, но, к сожалению, вряд ли что-то изменится в ближайшем будущем, так как по моим прикидкам 90-95% людей этого просто не замечают пока не нарисуешь направляющие линии. Не знаю почему так, но факт - всем плевать
Alohahwi
Наверное потому что
Аналогично с остальными частями тела и общей симметрией.
seregadushka
Любого человека глаза с ассиметрией 0.5 см, а вы про руки
Spaceoddity
А не надо рисовать никаких направляющих. Речь как раз о визуальном восприятии, а направляющими вы пытаетесь подменить понятия))
Аналогия - заваленный горизонт в фотографии. Можно выставить линию горизонта по уровню, но если у вас одна часть кадра "визуально перегружена", то у зрителя будет создаваться стойкое ощущение заваленного горизонта. Азы композиции, как бы))
Earthsea
Один раз надо было быстро перенести отсканированную растровую электрическую схему в Autocad и сделать в ней существенные изменения. Цифровой оригинал неизвестно было у кого искать, у заказчика было только ТЗ в виде мутноватого скана. Надо было отразить внесенные изменения, приложить схему к паспортам изделия, ну и на производство передать тоже - в бумажном виде. Автоматически распознать не получилось, делать самому с нуля слишком долго. Скопировал в модель растровый рисунок и обвел его примитивами, потом этот рисунок удалил. Если смотреть на мониторе, то кажется что все жутко криво и косо, отклонения от прямых углов и от параллельности адские, но на распечатанном чертеже было вообще незаметно. Впоследствии еще несколько модификаций было.