Изучение структуры шрифта и схемы вертикального центрирования текста

CSS шрифт
Изучение структуры шрифта и схемы вертикального центрирования текста

Источник изображения:ООН splash.com/photos/GK в…

Автор: Фэн Хао

1. Введение

Вертикальное центрирование — это в основном проблема, которую необходимо решить, когда вы начинаете работать с CSS. Мы должны были видеть «N методов вертикального центрирования CSS» в различных учебниках. Вообще говоря, эти методы уже могут соответствовать различным сценариям использования. Однако, когда мы сталкиваемся с ситуации, когда нам нужно использовать некоторые специальные шрифты для перетасовки или выравнивания текста по значку, мы можем обнаружить, что независимо от того, какой метод вертикального центрирования используется, всегда кажется, что текст сдвинут вверх или вниз на несколько пикселей. , вы должны сдвинуть их специально, почему это происходит?

2. Распространенные методы вертикального центрирования

На следующем рисунке показан пример использования различных распространенных методов вертикального центрирования для центрирования текста, который включает в себя смешивание разных шрифтов.Можно видеть, что, хотя используется несколько распространенных методов вертикального центрирования, на самом деле с точки зрения внешнего вида ни один из них текст точно центрирован по вертикали, некоторый текст выглядит более центрированным, а некоторый текст сильно смещен.

垂直居中示例图

Посмотреть онлайн:CodePen(Файл шрифта напрямую ссылается на Google Fonts, если нет эффекта, нужно обратить внимание на ситуацию в сети)

установивvertical-align:middleПри вертикальном центрировании текста необходимо установить родительский элементfont-size: 0,потому чтоvertical-align:middleявляется средней точкой дочернего элемента относительно родительского элементаbaseline + x-height / 2Положение линии выравнивается, и установка размера шрифта на 0 может гарантировать, что позиции этих линий совпадают в средней точке.

Мы используем мышь, чтобы выбрать эти тексты, и мы можем обнаружить, что выделенная область действительно центрирована по вертикали в родительском контейнере, так почему же тексты имеют разную высоту? Это включает в себя создание самого шрифта и связанных с ним показателей.

3. Конструкция и размер шрифта

Вот вопрос первый, мы задаем текст в CSSfont-size, какое свойство шрифта на самом деле установлено этим значением?

На рисунке ниже показан пример, метки, на которых расположен текст,span, текст каждого шрифта становится краснымoutlineдля наблюдения иline-height: normal. Как видно из рисунка, хотя размер шрифта этих текстов составляет 40px, ширина и высота у них разные, поэтому размер шрифта не задает реальный размер текста.

文字大小示意图

Чтобы ответить на этот вопрос, нам необходимо иметь глубокое понимание шрифтов.Следующее содержание представляет собой связанные концепции западных шрифтов. Во-первых, шрифт будет иметь размер EM Square (также известный как UPM, em, em size) [4]. Это значение изначально используется при наборе для представления ширины прописной буквы M в шрифте. С этим значением квадрат сформирован, то все буквы могут быть размещены, и это значение фактически отражает высоту контейнера шрифта. В металлическом подвижном шрифте контейнер представляет собой металлический блок для каждого символа, а в шрифте они одинаковы по высоте, поэтому каждый шрифт можно поместить в печатный инструмент и напечатать. В цифровой типографике em — это квадрат с заданным размером. Единицей измерения является относительная единица, которая будет масштабироваться в соответствии с фактическим размером шрифта. Например, если для размера шрифта 1000 единиц установлено значение 16pt, то размер 1000 единиц 16pt. . Em обычно равен 1000 в шрифтах OpenType и 1024 или 2048 (2 в энной степени) в шрифтах TrueType.

金属活字

Металлический подвижный тип, фото издизайн со шрифтом forge.com/en-US/the_E…

3.1 Метрики шрифта

В самом шрифте есть много понятий и метрик, вот несколько общих понятий, на примере этой картинки из Википедии (единицы измерения ниже — все относительные единицы, основанные на em):

字体结构

  • базовая линия: Базовая линия — это горизонтальная линия, на которой размещаются буквы.
  • x высота: X высота (x высота) представляет собой высоту строчной буквы x на базовой линии.
  • высота заглавной буквы: высота заглавной буквы (высота заглавной буквы) указывает высоту заглавной буквы над базовой линией.
  • восход/восхождение: Ascender (возрастание) указывает на то, что строчные буквы превышают основу высоты x.Для идентификации высота асцендера может быть немного больше высоты заглавной. Подъем представляет собой расстояние от верхней части текста до базовой линии.

字符升部

  • Дессер/спуск: Дессендер представляет основу строчных букв, простирающуюся ниже базовой линии, например, нижнюю часть букв, таких как j, g и т. д. Спуск представляет собой расстояние от нижней части текста до базовой линии.
  • разрыв линии: разрыв линии представляет собой расстояние от нижней точки спуска до вершины следующего подъема линии. Я не нашел подходящего китайского перевода для этого слова.Следует отметить, что это значение не является интерлиньяжем, что означает расстояние между базовыми линиями двух строк текста.

Далее мыFontForgeПосмотрите значения этих значений в софте, здесьArialШрифты приведу пример:

Arial Font Information

Как видно из рисунка, в меню General размер em Arial равен 2048, подъем шрифта 1638, спуск 410. В Metrics information меню OS/2 его можно получить что высота заглавной буквы равна 1467, а высота x равна 1062. , межстрочный интервал равен 67.

Однако здесь следует отметить, что хотя значения подъема и спуска мы получили в меню Общие, это значение следует использовать только для оформления шрифта, а их сумма всегда равна размеру em, а компьютер фактически рендерит по ОС. Рассчитывается соответствующее значение в меню / 2. Как правило, операционная система будет использовать HHead Ascent и HHead Descent таблицы hhea (Горизонтальная таблица заголовков), в то время как Windows является особым случаем и будет использовать Win Ascent и Win Descent . Вообще говоря, фактические значения подъема и спуска, используемые для рендеринга, больше, чем те, которые используются для дизайна шрифта, потому что дополнительная область обычно зарезервирована для фонетических символов или используется для управления межстрочным интервалом, как показано на рисунке ниже, в верхней части буква Горизонтальная линия — это высота подъема 1638 на первом рисунке, и все фонетические символы превышают эту область. По данным [5], в некоторых программах, если текстовое содержимое превышает восхождение и спуск, используемые для рендеринга, оно будет усечено, но поэкспериментировав в браузере, я обнаружил, что браузер не делает этого усечения (Edge 86.0 608.0 Canary (64 бит), MacOS 10.15.6).

ascent

В этой статье мы рассматриваем восхождение и спуск, упомянутые позже, как значения подъема и спуска, считываемые в опциях OS/2 для рендеринга, и называем областью содержимого значение восхождения + спуска.

Теоретически шрифт должен отображаться одинаково в Windows и MacOS, т. е. восхождение и спуск должны быть одинаковыми в соответствующих системах, однако некоторые шрифты разрабатываются без видимой причины, поэтому они различаются между двумя системами. Производительность. Вот пример от Roboto:

Differences between Win and HHead metrics cause the font to be rendered differently on Windows vs. iOS (or Mac I assume) · Issue #267 · googlefonts/roboto

Итак, вернемся к вопросу в начале этого раздела, в CSSfont-sizeЧто представляет собой установленное значение?У нас уже должен быть ответ, то есть размер, соответствующий размеру шрифта em, и текст установленline-height: normal, значение высоты строки равно области содержимого + разрыв строки, что является фактической высотой текста.

Зная это, нам нетрудно рассчитать эффект отображения шрифта.line-height: normalа такжеfont-size: 100pxВысота при поддержке составляет(1854 + 434 + 67) / 2048 * 100px = 115px.

В ходе эксперимента было установлено, что для встроенного элемента высота выделения, натянутого мышью, является текущей строкой.line-heightСамое высокое значение элемента. Если это блочный элемент, когдаline-heightКогда значение больше, чем содержание области, высота выбораline-height, когда он меньше или равен области содержимого, его высота равна высоте области содержимого.

3.2 Проверка влияния метрик на отрисовку текста

Вставьте вопрос в середине, мы должны были все использоватьline-heightчтобы центрировать текст по вертикали, затемline-heightКакая часть шрифта на самом деле рассчитывается от середины? Чтобы проверить эту проблему, я создал новый шрифт с очень «дизайнерским смыслом», установил размер em на 1000, подъем на 800, спуск на 200 и установил для него нормальные и преувеличенные метрики соответственно:

TestGap normal

TestGap exaggerate

Левая часть приведенного выше рисунка — это метрики, установленные в FontForge, правая сторона — фактический эффект отображения, размер текста установлен на 100 пикселей, а четыре буквы вертикально центрированы под гибкой компоновкой родительского слоя.line-height0, 1em, normal, 3em соответственно, красная рамка — это элементoutline, желтый фон — это фон, выбранный мышью. Как видно из двух приведенных выше рисунков, метрики шрифта имеют большое влияние на позицию рендеринга текста. В то же время видно, что в настройкахline-heightКогда, несмотря на то, что разрыв строки участвует в поддержании значенияnormalпробел, но не участвует в вычислении вертикального центрирования текста, то есть середина вертикального центрирования всегда является серединой области содержимого.

TestGap trimming

Мы еще раз доработали шрифт, чтобы восхождение имело определенное смещение, в это время видно, что контур текста с высотой строки 1em находится ровно посередине, поэтому можно сделать вывод, что когда браузер выполняет рендеринг, квадрат em всегда относительно центрируется по вертикали в области содержимого.

После разговора о структуре шрифта вернемся к вопросу из предыдущего раздела: почему тексты в разных шрифтах центрированы по вертикали, когда тексты смешаны, а тексты имеют разную высоту?

По этому вопросу в данной статье делается вывод о том, что, поскольку значения измерений разных шрифтов различны, при выполнении макета с вертикальным центрированием средняя точка области содержимого не соответствует визуальной средней точке, что приводит к фактическому Кажется, есть позиционное смещение.На следующем рисунке показаны несколько позиций срединной линии шрифта Arial:

Arial center line

Из рисунка видно, что между визуальной средней линией прописных и строчных букв и средней линией всего символа все же есть некоторое смещение. Здесь я не нашел заключения смежных с набором дисциплин.Какая линия больше подходит для центрирования человеческого глаза.С моей личной точки зрения центральная линия прописных букв может выглядеть более удобной(особенно когда нет строчных букв ) при перемешивании содержимого).

Следует отметить, что выбранный здесь шрифт Arial имеет относительно небольшое смещение, поэтому общее ощущение при его использовании относительно центрировано, что не означает, что другие шрифты такие же.

3.3 Китайский шрифт

Для китайских шрифтов в самом дизайне нет базовой линии, восходящей части, нисходящей части и т. д., и каждый символ находится в квадратной рамке. Однако при отображении на компьютере концепция западных шрифтов также в определенной степени используется.Вообще говоря, нижняя часть китайского шрифта в квадратной рамке китайских шрифтов находится между базовой линией и нижним выносным элементом, а верхняя находится за надстрочным элементом, а знаки препинания находятся точно на базовой линии.

4. CSS-решения

Мы разобрались с родственными концепциями шрифтов, так как же решить проблему смещения при использовании шрифтов?

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

Для достижения этой цели мы можем использовать егоvertical-alignэто свойство для завершения. когдаvertical-alignКогда значение является значением, значение представляет собой расстояние между базовой линией дочернего элемента и базовой линией родительского элемента, с положительными числами, указывающими вверх, и отрицательными числами, указывающими вниз.

Представленная здесь схема состоит в том, чтобы установить текст под определенный шрифт расчетным путем.vertical-alignЧисловое смещение , чтобы визуальная середина прописных букв совпадала с точкой, используемой для вычисления вертикального центрирования, чтобы свойства самого шрифта больше не влияли на вычисление центрирования.

В частности, мы получим его с помощью следующих методов расчета: Во-первых, нам нужно знать значения размера em, восхождения, спуска и высоты прописной буквы текущего шрифта (если вы не знаете размер em, вы можете также укажите другие значения и соотношение em-size), в следующем примере в качестве примера по-прежнему используется Arial:

const emSize = 2048;
const ascent = 1854;
const descent = 434;
const capitalHeight = 1467;

// 计算前需要已知给定的字体大小
const fontSize = FONT_SIZE;

// 根据文字大小,求得文字的偏移
const verticalAlign = ((ascent - descent - capitalHeight) / emSize) * fontSize;

return (
	<span style={{ fontFamily: FONT_FAMILY, fontSize }}>
		<span style={{ verticalAlign }}>TEXT</span>
	</span>
)

С этой настройкой внешний диапазон будет вести себя как обычный заменяемый элемент, участвующий во встроенной компоновке, в определенной степени игнорируя различия в метриках шрифта, и может быть центрирован по вертикали с использованием различных методов.

Поскольку этот вариант осуществления имеет фиксированный шаг расчета, может быть разработан в соответствии с конкретными потребностями, будет упакован в виде компонентов, использование пользовательских атрибутов или препроцессор CSS CSS для обработки текста, информация о шрифте путем передачи может изменить вертикальное смещение текста.

5. Ограничения решения

Хотя приведенное выше решение может в определенной степени решить проблему вертикального центрирования текста, все же есть неудобства в реальном использовании.Нам нужно знать метрики шрифта перед использованием шрифта.В некоторых случаях разработчики могут вручную использовать такие инструменты, как как FontForge для просмотра, но когда шрифтов много, просматривать их по одному сложнее.

Одна из текущих идей заключается в том, что мы можем использовать Canvas для получения информации о шрифтах.Например, существует библиотека с открытым исходным кодом для получения метрик шрифтов.FontMetrics.js. Его основная идея состоит в том, чтобы использовать Canvas для отображения текста соответствующего шрифта, а затем использоватьgetImageDataПроанализируйте визуализированный контент. В реальном проекте это решение может привести к потенциальным проблемам с производительностью, и этот метод получает результат после рендеринга Некоторые авторы шрифтов не строго соответствуют разработанным метрикам и символам при построении шрифтов, что также являются недостаточно точными.

Другая идея состоит в том, чтобы напрямую проанализировать файл шрифта и получить информацию о метриках шрифта, напримерopentype.jsэтот проект.不过这种做法也不够轻量,不适合在实际运行中使用,不过可以考虑在打包过程中自动执行这个过程。

Кроме того, текущее решение является скорее теоретическим подходом: когда размер шрифта самого текста мал, браузер может отображать его не так, как ожидалось, и текст будет иметь смещение в 1 пиксель в соответствии с DOM-окружением, в котором он находится. находится [9].

6. Возможные будущие решения — CSS Houdini

CSS Houdini предложил проект Font Metrics [6], который может настраивать связанные со шрифтом метрики для рендеринга текста. Из текущего дизайна вы можете настроить положение базовой линии, размер шрифта em и размер границы шрифта (то есть области содержимого), что может решить проблему набора текста, вызванную атрибутами шрифта.

[Exposed=Window]
interface FontMetrics {
  readonly attribute double width;
  readonly attribute FrozenArray<double> advances;

  readonly attribute double boundingBoxLeft;
  readonly attribute double boundingBoxRight;

  readonly attribute double height;
  readonly attribute double emHeightAscent;
  readonly attribute double emHeightDescent;
  readonly attribute double boundingBoxAscent;
  readonly attribute double boundingBoxDescent;
  readonly attribute double fontBoundingBoxAscent;
  readonly attribute double fontBoundingBoxDescent;

  readonly attribute Baseline dominantBaseline;
  readonly attribute FrozenArray<Baseline> baselines;
  readonly attribute FrozenArray<Font> fonts;
};

css houdini

отishoudinireadyyet.com/На этом веб-сайте видно, что Font Metrics все еще находится в стадии предложения, и конкретное содержание его API все еще неясно, или будет ли эта функция существовать в будущем, поэтому можно только сказать, что это набор текста. решение, которое может быть реализовано в будущем.

7. Резюме

Проблема вертикального центрирования текста всегда была самой распространенной проблемой в CSS, но ее трудно привлечь к себе внимание. Я лично думаю, что это потому, что наши часто используемые шрифты, такие как Microsoft Yahei и Pingfang, относительно стандартизированы по дизайну и обычно выглядят Относительно центрирован. Но когда шрифт не такой уж «канонический», традиционные методы кажутся немного бессильными.

В этой статье анализируются факторы, вызывающие смещение текста, и дается решение для нахождения вертикального центрального положения текста.

Поскольку вопросы, связанные с IFC, по своей сути сложны [7], использование встроенных элементовline-heightа такжеvertical-alignПоскольку различные советы по центрированию не имеют прямого отношения к этой статье, они не упоминаются в ней.Если вас больше интересует это содержание, вы также можете найти соответствующие введения в следующих ссылках.

Релевантная информация

Эта статья была опубликована сКоманда внешнего интерфейса NetEase Cloud Music, Любое несанкционированное воспроизведение статьи запрещено. Мы набираем front-end, iOS и Android круглый год.Если вы готовы сменить работу и любите облачную музыку, присоединяйтесь к нам на grp.music-fe(at)corp.netease.com!