Resumo
Este artigo apresenta uma análise detalhada dos substitutos de fontes e das APIs size-adjust
, ascent-override
, descent-override
e line-gap-override
. Essas APIs possibilitam o uso de fontes locais para criar tipos de fontes substitutos que correspondam ou exatamente às dimensões de uma fonte da Web. Isso reduz ou elimina as mudanças de layout causadas pela troca de fontes.
Se preferir ignorar a leitura deste artigo, estas são algumas das ferramentas que você pode usar para começar a usar essas APIs imediatamente:
Ferramentas de framework:
- @next/font: a partir do Next 13, o
next/font
usa automaticamente substituições de métricas de fonte esize-adjust
para fornecer substitutos de fonte correspondentes. - @nuxtjs/fontaine: a partir do Nuxt 3, você pode usar
nuxt/fontaine
para gerar e inserir automaticamente substitutos de fonte correspondentes nas folhas de estilo usadas pelo app Nuxt.
Ferramentas que não são estrutura:
- Fontaine: é uma biblioteca que gera e insere automaticamente substitutos de fonte que usam substituições de métrica de fonte.
- Este repo contém as substituições de métrica de fonte para todas as fontes hospedadas pelo Google Fonts. Esses valores podem ser copiados e colados em suas folhas de estilo.
Contexto
Uma fonte substituta é usada quando a fonte principal ainda não foi carregada ou não tem os glifos necessários para renderizar o conteúdo da página. Por exemplo, o CSS abaixo indica que a família de fontes sans-serif
precisa ser usada como substituta para "Roboto"
.
font-family: "Roboto" , sans-serif;
As fontes substitutas podem ser usadas para renderizar texto mais rapidamente, ou seja, usando font-display: swap
. Como resultado, o conteúdo da página é legível e útil desde o início. No entanto, historicamente, isso acarretou a instabilidade do layout: as mudanças de layout geralmente ocorrem quando uma fonte substituta é trocada pela fonte da Web. No entanto, as novas APIs discutidas abaixo podem reduzir ou eliminar esse problema, possibilitando a criação de tipos de fonte de fallback que ocupam a mesma quantidade de espaço que a fonte da Web correspondente.
Substitutos de fonte aprimorados
Há duas abordagens possíveis
para gerar melhorias substitutos de fonte. A abordagem mais simples usa apenas a métrica de fonte que substitui a API. A abordagem mais complicada, mas mais eficiente, usa a métrica de fonte que substitui a API e a size-adjust
. Este artigo explica as duas abordagens.
Como funcionam as substituições de métricas de fonte
Introdução
As substituições de métrica de fonte oferecem uma maneira de substituir a subida, a descida e o intervalo de linha de uma fonte:
- A Ascent mede a distância máxima que os glifos de uma fonte se estendem acima da linha de base.
- A descendência mede a maior distância que os glifos de uma fonte se estendem abaixo da linha de base.
- O intervalo entre linhas, também chamado de "início", mede a distância entre linhas sucessivas de texto.
As substituições de métrica de fonte podem ser usadas para substituir os níveis ascendente, descendente e lacuna de linha de uma fonte substituta a fim de corresponder aos níveis ascendente, descendente e de linhas da fonte da Web. Como resultado, a fonte da Web e a fonte substituta ajustada sempre terão as mesmas dimensões verticais.
As substituições de métrica de fonte são usadas em uma folha de estilo como esta:
body {
font-family: Poppins, "fallback for poppins";
}
@font-face {
font-family: "fallback for poppins";
src: local("Times New Roman");
ascent-override: 105%;
descent-override: 35%;
line-gap-override: 10%;
}
As ferramentas listadas no início deste artigo podem gerar os valores corretos de substituição da métrica de fonte. No entanto, você também pode calcular esses valores sozinho.
Como calcular substituições de métrica de fonte
As equações a seguir geram substituições de métricas de fonte para uma determinada fonte da Web. Os valores das substituições de métricas de fonte precisam ser escritos como porcentagens (por exemplo, 105%
) em vez de decimais.
ascent-override = ascent/unitsPerEm
descent-override = descent/unitsPerEm
line-gap-override = line-gap/unitsPerEm
Por exemplo, estas são as substituições de métrica de fonte para a fonte Poppins:
/*
Poppins font metrics:
ascent = 1050
descent = 350
line-gap = 100
UPM: 1000
*/
ascent-override: 105%; /* = 1050/1000 */
descent-override: 35%; /* = 350/1000 */
line-gap-override: 10%; /* = 100/1000 */
Os valores de ascent
, descent
, line-gap
e unitsPerEm
são provenientes dos metadados da fonte da Web. A próxima seção deste artigo explica como conseguir esses valores.
Leitura de tabelas de fontes
Os metadados de uma fonte (especificamente, as tabelas de fontes) contêm todas as informações necessárias para calcular as substituições de métrica de fonte.
Aqui estão algumas ferramentas que você pode usar para ler os metadados de uma fonte:
- O fontkit é um mecanismo de fontes criado para Node.js. Este snippet de código mostra como usar o Fontkit para calcular substituições de métrica de fonte.
- Capsize é um dimensionamento de fonte e uma biblioteca de layout. O Capsize fornece uma API para receber informações sobre várias métricas de fonte.
- fontdrop.info é um site que permite visualizar tabelas de fontes e outras informações relacionadas a fontes no navegador.
- O Font Forge é um editor de fontes muito usado para computadores. Para visualizar
ascent
,descent
eline-gap
: abra a caixa de diálogoFont Info
, selecione o menuOS/2
e depois a guiaMetrics
. Para conferir oUPM
: abra a caixa de diálogoFont Info
e selecione o menuGeneral
.
Noções básicas sobre tabelas de fontes
Conceitos como "crescente" são referenciados por várias métricas. Por exemplo, há métricas hheaAscent
, typoAscent
e winAscent
. Esse é o resultado de diferentes sistemas operacionais adotando abordagens distintas para a renderização de fontes: os programas em dispositivos OSX geralmente usam métricas de fonte hhea*
, enquanto os programas em dispositivos Windows geralmente usam métricas de fonte typo*
(também chamadas de sTypo*
) ou win*
.
Dependendo da fonte, do navegador e do sistema operacional, uma fonte será renderizada usando as métricas hhea
, typo
ou win
.
Mac | Windows | |
Chromium | Usa métricas de "hhea" tabela. | Usa métricas de "erro de digitação" tabela se "USE_TYPO_METRICS" foi definido. Caso contrário, usa métricas de "win" tabela. |
Firefox | Usa métricas de "erro de digitação" tabela se "USE_TYPO_METRICS" foi definido. Caso contrário, usa métricas de "hhea" tabela. | Usa métricas de "erro de digitação" tabela se "USE_TYPO_METRICS" foi definido. Caso contrário, usa métricas de "win" tabela. |
Safari | Usa métricas de "hhea" tabela. | Usa métricas de "erro de digitação" tabela se "USE_TYPO_METRICS" foi definido. Caso contrário, usa métricas de "win" tabela. |
Para mais informações sobre como as métricas de fontes funcionam nos sistemas operacionais, consulte este artigo sobre métricas verticais.
Compatibilidade com vários dispositivos
Para a grande maioria das fontes (por exemplo, cerca de 90% das fontes hospedadas pelo Google Fonts) as substituições de métricas podem ser usadas com segurança sem conhecer o sistema operacional do usuário. Em outras palavras, para essas fontes, os valores de ascent-override
, descent-override
e linegap-override
permanecem exatamente os mesmos, independentemente das métricas hhea
, typo
ou win
. Este repo fornece informações sobre a quais fontes isso se aplica ou não.
Se você usa uma fonte que exige conjuntos separados de substituições de métricas de fonte para dispositivos OSX e Windows, o uso de substituições de métricas de fonte e size-adjust
só é recomendado se você puder variar suas folhas de estilo com base no sistema operacional do usuário.
Como usar substituições de métrica de fonte
Como as substituições de métricas de fonte são calculadas usando medidas dos metadados da fonte da Web (e não da fonte substituta), elas permanecem as mesmas, independentemente da fonte usada como substituta. Exemplo:
body {
font-family: "Poppins", "fallback for Poppins", "another fallback for Poppins";
}
@font-face {
font-family: "fallback for Poppins";
src: local("Arial");
ascent-override: 105%;
descent-override: 35%;
line-gap-override: 10%;
}
@font-face {
font-family: "another fallback for Poppins";
src: local("Roboto");
ascent-override: 105%;
descent-override: 35%;
line-gap-override: 10%;
}
Como o ajuste de tamanho funciona
Introdução
O descritor CSS size-adjust
dimensiona proporcionalmente a largura e a altura dos glifos de fonte. Por exemplo, size-adjust: 200%
dimensiona os glifos de fonte para o dobro do tamanho original. O size-adjust: 50%
dimensiona os glifos da fonte para a metade do tamanho original.
Por si só, o size-adjust
tem aplicativos limitados para melhorar os substitutos de fonte: na maioria dos casos, uma fonte substituta precisa ser reduzida ou ampliada um pouco (em vez de dimensionada proporcionalmente) para corresponder a uma fonte da Web. No entanto, combinar size-adjust
com substituições de métricas de fonte possibilita fazer com que duas fontes correspondam na horizontal e na vertical.
É assim que size-adjust
é usado nas folhas de estilo:
@font-face {
font-family: "fallback for poppins";
src: local("Arial");
size-adjust: 60.85099821%;
ascent-override: 164.3358416%;
descent-override: 57.51754455%;
line-gap-override: 16.43358416%;
}
Devido à forma como size-adjust
é calculado (explicado na próxima seção), o valor de size-adjust
(e as substituições de métrica de fonte correspondente) muda dependendo de qual fonte substituta é usada:
body {
font-family: "Poppins", "fallback for Poppins", "another fallback for Poppins";
}
@font-face {
font-family: poppins-fallback;
src: local("Arial");
size-adjust: 60.85099821%;
ascent-override: 164.3358416%;
descent-override: 57.51754455%;
line-gap-override: 16.43358416%;
}
@font-face {
font-family: poppins-fallback-android;
src: local("Roboto");
size-adjust: 55.5193474%:
ascent-override: 180.1173909%;
descent-override: 63.04108683%;
line-gap-override: 18.01173909%;
}
Como calcular as substituições de métrica de tamanho e de fonte
Estas são as equações para calcular as substituições de size-adjust
e de métricas de fonte:
size-adjust = avgCharacterWidth of web font / avgCharacterWidth of fallback font
ascent-override = web font ascent / (web font UPM * size-adjust)
descent-override = web font descent / (web font UPM * size-adjust)
line-gap-override = web font line-gap / (web font UPM * size-adjust)
A maioria dessas entradas (ou seja, subida, descida e lacuna de linha) pode ser lida diretamente dos metadados da fonte da Web. No entanto, o valor de avgCharacterWidth
precisa ser aproximado.
Aproximar a largura média de caracteres
Em geral, a largura média dos caracteres só pode ser aproximada, mas existem algumas situações em que isso pode ser calculado com exatidão, por exemplo, ao usar uma fonte monocromática ou quando o conteúdo de uma string de texto é conhecido com antecedência.
Um exemplo de uma abordagem simples para calcular avgCharacterWidth
é usar a largura média de todos os caracteres de [a-z\s]
.
No entanto, ponderar todos os caracteres igualmente provavelmente diminuirá a largura das letras usadas com frequência (por exemplo, e
) e aumentará o peso de letras usadas com pouca frequência (por exemplo, z
).
Uma abordagem mais complexa que aumenta a precisão é considerar a frequência de letras e calcular a largura média ponderada com a frequência de [a-z\s]
caracteres. Este artigo é uma boa referência para a frequência das letras e o tamanho médio da palavra em textos em inglês.
Como escolher uma abordagem
As duas abordagens discutidas neste artigo têm vantagens e desvantagens:
Usar as substituições de métrica de fonte por si só é uma boa abordagem se você está começando a otimizar suas fontes substitutas. Embora essa seja a mais simples das duas abordagens, ela normalmente é eficiente o suficiente para reduzir visivelmente a magnitude das mudanças de layout relacionadas à fonte.
Por outro lado, se você quer mais precisão e quer realizar um pouco mais de trabalho e testes, é recomendável incorporar
size-adjust
. Quando implementada corretamente, essa abordagem pode eliminar efetivamente as mudanças de layout relacionadas à fonte.
Como escolher fontes substitutas
As técnicas descritas neste artigo dependem do uso de substituições de métricas de fonte e size-adjust
para transformar fontes locais amplamente disponíveis, em vez de tentar encontrar uma fonte local que se aproxime da fonte da Web. Ao escolher fontes locais, é importante ter em mente que poucas fontes têm disponibilidade local generalizada e nenhuma fonte vai existir em todos os dispositivos.
Arial
é a fonte substituta recomendada para fontes sem serifa e Times New Roman
é a fonte substituta recomendada para fontes com serifa. No entanto, nenhuma dessas fontes está disponível no Android (Roboto
é a única fonte do sistema nesse sistema operacional).
O exemplo abaixo usa três fontes substitutas para garantir uma cobertura ampla em dispositivos: uma substituta destinada a dispositivos Windows/Mac, uma fonte substituta destinada a dispositivos Android e uma substituta que usa uma família de fontes genérica.
body {
font-family: "Poppins", poppins-fallback, poppins-fallback-android, sans-serif;
}
/*
Poppins font metrics:
- ascent = 1050
- descent = 350
- line-gap = 100
- UPM: 1000
AvgCharWidth:
- Poppins: 538.0103768
- Arial: 884.1438804
- Roboto: 969.0502537
*/
@font-face {
font-family: poppins-fallback;
src: local("Arial");
size-adjust: 60.85099821%;
ascent-override: 164.3358416%;
descent-override: 57.51754455%;
line-gap-override: 16.43358416%;
}
@font-face {
font-family: poppins-fallback-android;
src: local("Roboto");
size-adjust: 55.5193474%:
ascent-override: 180.1173909%;
descent-override: 63.04108683%;
line-gap-override: 18.01173909%;
}
Pedido de feedback
Entre em contato se tiver algum feedback sobre sua experiência com o uso de substituições de métricas de fonte e size-adjust
.