Resumo
Este artigo é uma análise detalhada dos substitutos de fontes e das 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, 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 de framework:
- Fontaine: a 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;
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 anteriormente. No entanto, historicamente, isso tem o custo da 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, permitindo a criação de fontes de fallback que ocupam a mesma quantidade de espaço que a fonte da Web.
Melhorias nas fontes substitutas
Há duas abordagens possíveis para gerar substitutos de fontes "melhores". A abordagem mais simples usa apenas a API de substituição de métricas de fonte. A abordagem mais complicada, mas mais eficiente, usa a métrica de fonte que substitui a API e a size-adjust
. Neste artigo, explicamos 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 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 descida mede a distância mais longa 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 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 assim:
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 família 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étricas 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 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 verUPM
: abra a caixa de diálogoFont Info
e selecione o menuGeneral
.
Noções básicas sobre 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 métricas da tabela "typo" se "USE_TYPO_METRICS" tiver sido definido. Caso contrário, vai usar métricas da tabela "win". |
Firefox | Usa as métricas da tabela "typo" se "USE_TYPO_METRICS" tiver sido definida. Caso contrário, usa as 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". |
Safari | Usa 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". |
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 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 quais fontes se aplicam e não se aplicam.
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é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 da 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.
É 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 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 a substituição de size-adjust
e a métrica da 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, 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 de letras e o comprimento médio das palavras 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 a fontes.
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 nesse sistema operacional).
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 usando substituições de métricas de fonte e size-adjust
.