Resumo
Este artigo apresenta uma análise detalhada dos substitutos de fonte e das APIs size-adjust
, ascent-override
, descent-override
e line-gap-override
. Essas APIs possibilitam o uso de fontes locais para criar fontes substitutas que correspondem exatamente às dimensões de uma fonte da Web. Isso reduz ou elimina as mudanças de layout causadas pela troca de fontes.
Se você preferir pular a leitura deste artigo, estas são algumas das ferramentas que podem ser usadas para começar a usar essas APIs imediatamente:
Ferramentas do framework:
- @next/font: a partir do Next 13,
next/font
usa automaticamente substituições de métricas de fonte esize-adjust
para oferecer substitutos de fonte correspondentes. - @nuxtjs/fontaine: a partir do Nuxt 3, você pode usar
nuxt/fontaine
para gerar e inserir substitutos de fonte correspondentes automaticamente nas folhas de estilo usadas pelo app Nuxt.
Ferramentas que não são do framework:
- Fontaine: é uma biblioteca que gera e insere automaticamente fontes substitutas que usam substituições de métricas de fonte.
- Este repositório (link em inglês) contém as substituições de métrica de fontes para todas as fontes hospedadas pelo Google Fonts. Esses valores podem ser copiados e colados em suas folhas de estilo.
Contexto
A fonte substituta é usada quando a 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 substituto de fonte para "Roboto"
.
font-family: "Roboto" , sans-serif;
Fontes substitutas podem ser usadas para renderizar texto mais rapidamente, ou seja, usando font-display: swap
. Como resultado, o conteúdo da página passa a ser legível e útil mais cedo. No entanto, historicamente, isso causou a instabilidade do layout: 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 fontes substitutas que ocupam a mesma quantidade de espaço que as fontes da Web.
Fontes substitutas aprimoradas
Há duas abordagens possíveis para gerar substitutos de fonte "aprimorados". 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 o size-adjust
. Este artigo explica as duas abordagens.
Como funcionam as substituições de métrica de fonte
Introdução
As substituições de métrica de fonte oferecem uma maneira de substituir os níveis em ordem crescente, descendente e intervalo de linha de uma fonte:
- Ascent mede a maior distância que os glifos de uma fonte se estendem acima da linha de base.
- Descida mede a maior distância que os glifos de uma fonte se estendem abaixo da linha de base.
- O intervalo de linha, também chamado de "livre", 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 em ordem crescente, descendente e a lacuna de linha de uma fonte substituta para que eles correspondam aos graus de subida, descida e intervalo 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 por conta própria.
Calcular substituições de métricas de fonte
As equações a seguir geram as substituições da métrica 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.
Ler tabelas de fontes
Os metadados de uma fonte (especificamente, as tabelas de fonte) contêm todas as informações necessárias para calcular as substituições de métrica da fonte.
Aqui estão algumas ferramentas que podem ser usadas para ler os metadados de uma fonte:
- O fontkit é um mecanismo de fontes criado para o Node.js. Este snippet de código mostra como usar o fontkit para calcular as substituições de métrica da fonte.
- O Capsize (link em inglês) é uma biblioteca de layout e tamanho de fontes. O Capsize fornece uma API para receber informações sobre várias métricas de fonte.
- fontdrop.info é um site que permite ver tabelas de fontes e outras informações relacionadas a fontes no navegador.
- O Font Forge é um editor de fontes conhecido para computador. Para conferir
ascent
,descent
eline-gap
: abra a caixa de diálogoFont Info
, selecione o menuOS/2
e 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 "ascente" são referidos por várias métricas. Por exemplo, há métricas hheaAscent
, typoAscent
e winAscent
. Isso é resultado de diferentes sistemas operacionais que adotam abordagens diferentes 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 é renderizada usando as métricas hhea
, typo
ou win
.
Mac | Windows | |
Chromium | Usa métricas da tabela "hhea". | Usa métricas da tabela "typo" se "USE_TYPO_METRICS" tiver sido definida. Caso contrário, usa as métricas da tabela "win". |
Firefox | Usa métricas da tabela "typo" se "USE_TYPO_METRICS" tiver sido definida. Caso contrário, usa as métricas da tabela "hhea". | Usa métricas da tabela "typo" se "USE_TYPO_METRICS" tiver sido definida. Caso contrário, usa as métricas da tabela "win". |
Safari | Usa métricas da tabela "hhea". | Usa métricas da tabela "typo" se "USE_TYPO_METRICS" tiver sido definida. Caso contrário, usa as métricas da tabela "win". |
Para mais informações sobre como as métricas de fontes funcionam em todos os sistemas operacionais, consulte este artigo sobre métricas verticais.
Compatibilidade entre 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, independente da aplicação das métricas hhea
, typo
ou win
. Este repositório (link em inglês) fornece informações sobre quais fontes isso se aplica ou não.
Se você estiver usando uma fonte que exija o uso de 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étricas de fonte
Como as substituições de métrica de fonte são calculadas usando medidas provenientes dos metadados da fonte da Web (e não da fonte substituta), elas permanecem as mesmas, independentemente de qual 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 da fonte. Por exemplo, size-adjust: 200%
dimensiona os glifos de fonte para o dobro do tamanho original; size-adjust: 50%
dimensiona os glifos de fonte para 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 estreita ou ampliada um pouco (em vez de dimensionada proporcionalmente) para corresponder a uma fonte da Web. No entanto, a combinação de size-adjust
com substituições de métricas de fonte possibilita fazer com que duas fontes correspondam horizontal e verticalmente.
Veja como size-adjust
é usado em 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 (o que é explicado na próxima seção), o valor de size-adjust
(e as substituições da 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 substituições de métricas de fonte e ajuste de tamanho
Estas são as equações para calcular size-adjust
e substituições 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 intervalo de linha) pode ser lida diretamente dos metadados da fonte da Web. No entanto, avgCharacterWidth
precisa ser aproximado.
Largura média aproximada de caracteres
Em geral, a largura média de caracteres só pode ser aproximada, mas há alguns cenários em que isso pode ser calculado exatamente. Por exemplo, ao usar uma fonte monoespaçada ou quando o conteúdo de uma string de texto é conhecido com antecedência.
Um exemplo de abordagem simples para calcular avgCharacterWidth
é usar a largura média de todos os caracteres [a-z\s]
.
No entanto, ponderar todos os caracteres da mesma forma provavelmente diminuirá o peso das letras usadas com frequência (por exemplo, e
) e da largura das letras usadas com pouca frequência (por exemplo, z
).
Uma abordagem mais complexa que melhora a precisão é considerar a frequência de letras e calcular a largura média ponderada com frequência de [a-z\s]
caracteres. Este artigo é uma boa referência sobre a frequência das letras e o comprimento médio das palavras em textos em inglês.
Como escolher uma abordagem
Cada uma das duas abordagens discutidas neste artigo tem vantagens e desvantagens:
Usar apenas substituições de métricas de fonte é uma boa abordagem se você está começando a otimizar seus substitutos de fonte. Embora essa seja a mais simples das duas abordagens, ela normalmente é poderosa o suficiente para reduzir visivelmente a magnitude das mudanças de layout relacionadas à fonte.
Por outro lado, se você quiser maior precisão e quiser se esforçar um pouco mais, incorporar
size-adjust
é uma boa abordagem. Quando implementada corretamente, essa abordagem pode eliminar as mudanças de layout relacionadas a fontes de forma eficaz.
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 lembrar 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 no Android).
O exemplo abaixo usa três fontes substitutas para garantir uma cobertura de dispositivo ampla: uma para dispositivos Windows/Mac, outra destinada a dispositivos Android e uma alternativa que usa uma família genérica de fontes.
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%;
}
Solicitação de feedback
Entre em contato se tiver feedback sobre sua experiência com as substituições de métricas de fonte e size-adjust
.