Прежде чем читать. Я не профессионал в области шрифтов, и я даю ответ, основываясь на своих нескольких часах исследований по этой теме. В некоторых местах я могу ошибаться и с удовольствием приму любое улучшение ответа.
TL; DR
На мой взгляд, самым безопасным подходом было бы создание изображений +
и −
и использование их вместо кнопок.
Как работают шрифты
Чтобы ответить на ваш вопрос, вам нужно знать, как сначала работают шрифты.
Каждый символ шрифта помещается в свой собственный контейнер. В традиционном металлическом типе этот контейнер был фактическим металлическим блоком каждого персонажа. Высота каждой части символа была одинаковой, что позволяло аккуратно расставлять символы по строкам и блокам. Это пространство называется «em-space» и происходит от ширины заглавного M
символа. Это было сделано для того, чтобы пропорции этой буквы были квадратными.
В цифровом типе em-space определяется следующим образом:
- В шрифте OpenType он обычно устанавливается на 1000 единиц.
- В шрифтах TrueType условно это степень два, обычно равная 1024 или 2048 единицам.
Когда шрифт используется для установки типа, em масштабируется до желаемого размера точки.
Каждый символ в вашем шрифте также имеет следующие элементы:
- Базовая линия - это линия, определяющая основание символа. За некоторыми исключениями, такими как
g
и q
символы не пересекают базовую линию.
- Высота колпачка - это линия, которая определяет верх заглавной буквы. Обычно это плоские буквы, такие как
H
или I
, тогда как O
или A
могут перескочить.
- X-высота - высота строчной буквы. Как правило, это высота буквы
x
в шрифте, отсюда и название.
- Ascender - это часть буквы в нижнем регистре, которая выше, чем x-высота шрифта. Подумайте о
b
и d
символах.
- Descender - это часть буквы, которая простирается ниже базовой линии шрифта. Я уже упоминал
g
и q
.
Все эти элементы содержатся внутри em-space.
Теперь, что происходит, когда вы пытаетесь уменьшить шрифт до 10 пикселей (в зависимости от настроек font-size: 10px;
). Если вы не изменили настройки браузера, размер шрифта браузера по умолчанию составляет 16 пикселей (1 em = 2048 единиц для Times New Roman, который вы, похоже, используете).
Но Times New Roman использует 1825 подъема и 443 спуска, что составляет 2268 единиц в 2048 единицах квадрата на Windows. Mac, кажется, использует значения HHead
, которые одинаковы для Times New Roman. Вот скриншот, показывающий эти значения:
Что это значит? Это означает, что при указании font-size: 10px
фактический размер Times New Roman будет совершенно другим. Если я прав в своих расчетах, то оно будет 11.07421875
округлено до 11px
(уже "ой", верно?)
line-height
и vertical-align
Хорошо, затем, когда ваш button
отображается на экране, он может состоять из множества строк в зависимости от ширины. Каждая строка состоит из одного или нескольких встроенных элементов (например, span
элементов с различными настройками шрифта) и называется строковым блоком. Высота линейного бокса зависит от роста его детей. Браузер вычисляет высоту для каждого встроенного элемента и выбирает самый высокий дочерний элемент в качестве «шаблона» для линейного блока. Это гарантирует, что вы видите все символы на вашем экране, когда элемент отображается.
Это поведение отличается от Word или Photoshop. В этих программах line-height
не основано на линейном блоке. Вместо этого это расстояние между базовыми линиями. Но в CSS это не так. В css ваш line-height
- это ваш line-box.
Следует отметить, что CSS не указывает значение по умолчанию line-height
. Значение по умолчанию normal
:
Сообщает пользовательским агентам установить «разумное» значение для используемого значения на основе шрифта элемента. Значение имеет то же значение, что и. Мы рекомендуем использовать значение для «нормального» в диапазоне от 1,0 до 1,2. Вычисленное значение является «нормальным».
А это спецификации для vertical-align
:
Это свойство влияет на вертикальное расположение в линейном блоке блоков, сгенерированных встроенным элементом уровня.
Из всей вышеприведенной информации мы можем сделать вывод, что это область содержимого, центрированная вертикально, а не символ.
Действительно
Я проверил +
и -
в программном обеспечении для редактирования шрифтов, и это выглядит так:
Хотя +
кажется симметричным, он все еще немного опущен внутри своей области содержимого; и -
понижается к базовой линии. Так что ответ на -
очевиден. Исходя из всего, что я исследовал и опубликовал выше - вы не сможете центрировать его по вертикали, оно всегда будет немного ниже. На маленьких размерах шрифта это может быть пиксель или два; на большом размере шрифта вы увидите это сразу.
Обратите внимание, что -
, который вы привыкли печатать (верхняя правая клавиша на цифровой клавиатуре или правая клавиша 0
) - это не минус, а hyphen
. Минус и дефис выглядят по-разному: −
против -
.
Будет ли − (minus)
выглядеть по-другому? Это, безусловно, имеет больше симметрии к нему:
Здесь вы можете видеть более четко, что +
и − (minus)
находятся ближе к базовой линии.
Флексбоксы как возможное решение?
Давайте посмотрим на flexbox. Когда вы определяете display: flex
, генерируется окно с именем flex container
. Дочерние потоки гибкого контейнера называются flex items
и располагаются внутри гибких линий.
В отличие от блочной и встроенной компоновки, расчеты компоновки которой смещены к блоку и линейным направлениям потока, гибкая компоновка смещена к направлениям прогиба.
Теперь гибкие линии, кроме линейных блоков, работают по-другому:
Как только содержимое разбито на строки, каждая строка раскладывается независимо; гибкая длина и свойства justify-content и align-self учитывают только элементы в одной строке за раз.
В многострочном гибком контейнере (даже в одном, содержащем только одну строку) размер креста каждой строки - это минимальный размер, необходимый для размещения гибких элементов в строке (после выравнивания из-за align-self), и линии выровнены внутри контейнера flex с помощью свойства align-content. В гибком контейнере, состоящем из одной строки, размер поперечного сечения строки - это размер поперечного сечения гибкого контейнера, а выравнивание содержимого не оказывает влияния. Основной размер строки всегда совпадает с основным размером поля содержимого гибкого контейнера.
Итак, когда вы определяете align-items: center
,
Поле для полей гибкого элемента центрируется по оси креста в пределах линии.
И, наконец, , если я правильно понял спецификацию , когда вы указываете align-items: center
, базовая линия генерируется динамически, что позволяет вам фактически идеально центрировать +
и −
.
В заключение
Вы должны использовать flexbox и использовать div
, а не button
, так как button
ведет себя иначе (я бы приветствовал задокументированное предложение, почему). Даже если вы укажете огромные числа (например, width
и height
до 400px
и font-size
до 750px
), вы увидите небольшое смещение вниз. Но на небольших размерах все, кажется, работает отлично.
На мой взгляд, самым безопасным подходом было бы создание изображений +
и −
и использование их вместо кнопок.
Источники Я исследовал:
Приложение для отображения информации о шрифте - https://fontforge.github.io/en-US/