Resumo
Este artigo é um mergulho profundo nos substitutos de fontes e nas APIs size-adjust
, ascent-override
, descent-override
e line-gap-override
. Essas APIs permitem usar fontes locais para criar fontes de substituição que correspondam exatamente ou de forma aproximada à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, confira algumas das ferramentas que podem ser usadas 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étrica de fonte esize-adjust
para fornecer substitutos de fonte correspondentes. - @nuxtjs/fontaine: a partir do Nuxt 3, é possível usar
nuxt/fontaine
para gerar e inserir automaticamente substitutos de fontes 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 repositório 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 nas folhas de estilo.
Contexto
Uma fonte de fallback é um tipo de fonte usado quando o tipo de fonte principal ainda não foi carregado 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
deve ser usada como substituto para "Roboto"
.
font-family: "Roboto" , sans-serif;
As fontes de fallback podem ser usadas para renderizar textos mais rapidamente (ou seja, usando font-display: swap
). Como resultado, o conteúdo da página fica legível e útil mais cedo. No entanto, historicamente, isso tem um custo de instabilidade do layout: as mudanças de layout geralmente ocorrem quando uma fonte de fallback é 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.
Melhorias nas fontes substitutas
Há duas abordagens possíveis para gerar substitutos de fontes "melhores". A abordagem mais simples usa apenas a métrica de fonte que substitui a API. A abordagem mais complicada (mas mais poderosa) usa a API de substituições de métricas de fonte e size-adjust
. Neste artigo, explicamos as duas abordagens.
Como funciona a substituição da métrica de fonte
Introdução
As substituições de métrica de fonte oferecem uma maneira de substituir a ascensão, a descida e o espaçamento entre linhas de uma fonte:
- O ascendente mede a distância mais longa 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 espaço entre linhas, também chamado de "leading", mede a distância entre linhas sucessivas de texto.
As substituições de métrica de fonte podem ser usadas para substituir a ascensão, a descida e o espaçamento entre linhas de uma fonte de fallback para corresponder à ascensão, a descida e o espaçamento entre 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 de métrica de fonte. No entanto, você também pode calcular esses valores.
Como calcular substituições de métricas de fonte
As equações a seguir geram as substituições de métrica de fonte para uma determinada fonte da Web. Os valores de 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
vêm 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étricas de fonte.
Confira algumas ferramentas que podem ser usadas 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 é uma biblioteca de dimensionamento e layout de fontes. 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 para computador muito conhecido. Para ver
ascent
,descent
eline-gap
: abra a caixa de diálogoFont Info
, selecione o menuOS/2
e a guiaMetrics
. Para verUPM
: abra a caixa de diálogoFont Info
e selecione o menuGeneral
.
Como entender as tabelas de fontes
Você pode notar que conceitos como "ascensão" são mencionados por várias métricas. Por exemplo, há as 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 da tabela "hhea". | Usa as 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 definido. Caso contrário, vai usar métricas da tabela "hhea". | Usa métricas da tabela "typo" se "USE_TYPO_METRICS" tiver sido definido. Caso contrário, vai usar métricas da tabela "win". |
Safari | Usa métricas da tabela "hhea". | Usa as 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 fonte funcionam em vários sistemas operacionais, consulte este artigo sobre métricas verticais.
Compatibilidade com vários dispositivos
Para a maioria das fontes (por exemplo, cerca de 90% das fontes hospedadas pelo Google Fonts), as substituições de métricas de fonte 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 de as métricas hhea
, typo
ou win
serem aplicadas. Este repo fornece informações sobre a quais fontes isso se aplica ou não.
Se você estiver usando uma fonte que exige 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 as 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 medições provenientes dos metadados da fonte da Web (e não da fonte de substituição), elas permanecem as mesmas, independentemente de qual fonte for usada como padrão. 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 da fonte para o dobro do tamanho original. size-adjust: 50%
dimensiona os glifos da fonte para metade do tamanho original.
Por si só, size-adjust
tem aplicações limitadas para melhorar os substitutos de fonte: na maioria dos casos, uma fonte substituta precisa ser estreitada ou alargada um pouco (em vez de ser dimensionada proporcionalmente) para corresponder a uma fonte da Web. No entanto, a combinação de size-adjust
com substituições de métrica de fonte permite que duas fontes sejam correspondentes horizontal e verticalmente.
Confira 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 (explicado na próxima seção), o valor de size-adjust
(e as substituições de métrica de fonte correspondentes) muda dependendo da fonte de fallback 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 tamanho e 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, ascensão, descida e espaçamento entre linhas) pode ser lida diretamente dos metadados da fonte da Web. No entanto, o valor de avgCharacterWidth
precisa ser aproximado.
Aproximação da largura média de caracteres
Em geral, a largura média dos 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 simplista para calcular avgCharacterWidth
é usar a largura média de todos os caracteres [a-z\s]
.
No entanto, dar peso igual a todos os caracteres provavelmente vai subestimar a largura das letras usadas com frequência (por exemplo, e
) e superestimar a largura das letras usadas com pouca frequência (por exemplo, z
).
Uma abordagem mais complexa que melhora a precisão é considerar a frequência das letras e calcular a largura média ponderada pela frequência dos caracteres [a-z\s]
. 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 substituições de métrica de fonte por conta própria é uma boa abordagem se você estiver começando a otimizar as fontes alternativas. Embora essa seja a abordagem mais simples, ela geralmente é poderosa o suficiente para reduzir significativamente a magnitude das mudanças de layout relacionadas à fonte.
Por outro lado, se você quiser mais precisão e estiver disposto a fazer um pouco mais de trabalho e testes, incorporar
size-adjust
é uma boa abordagem. 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 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 aproxima 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 no Android).
O exemplo abaixo usa três fontes de fallback para garantir a cobertura de dispositivos mais ampla: uma fonte de fallback para dispositivos Windows/Mac, uma para dispositivos Android e uma 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
.