Introdução a fontes variáveis na Web

Uma nova especificação de fonte que pode reduzir significativamente os tamanhos dos arquivos de fonte

Neste artigo, veremos o que são fontes variáveis, os benefícios que elas oferecem e como podemos usá-las no nosso trabalho. Primeiro, vamos rever como a tipografia funciona na Web e quais inovações as fontes variáveis trazem.

Compatibilidade com navegadores

Desde maio de 2020, fontes variáveis são compatíveis com a maioria dos navegadores. Consulte Posso usar fontes variáveis? e Substitutos.

Introdução

Os termos "fonte" e "família tipográfica" costumam ser usados como sinônimos pelos desenvolvedores. No entanto, há uma diferença: uma família tipográfica é o design visual subjacente que pode existir em muitas tecnologias diferentes de tipografia, e uma fonte é uma dessas implementações, em formato de arquivo digital. Em outras palavras, uma família tipográfica é o que você , e a fonte é o que você usa.

Outro conceito que é frequentemente ignorado é a distinção entre um estilo e uma família. Um estilo é uma família tipográfica única e específica, como itálico e negrito, e uma família é o conjunto completo de estilos.

Antes das fontes variáveis, cada estilo era implementado como um arquivo de fontes separado. Com fontes variáveis, todos os estilos podem estar contidos em um único arquivo.

Uma composição de espécime e uma lista de diferentes estilos da família Roboto
Esquerda: um espécime da família tipográfica Roboto. Direita: estilos nomeados dentro da família.

Desafios para designers e desenvolvedores

Quando um designer cria um projeto de impressão, ele enfrenta algumas restrições, como o tamanho físico do layout da página, o número de cores que pode usar (que é determinado pelo tipo de impressão que será usado) e assim por diante. Mas eles podem usar quantos estilos de família tipográficos quiserem. Isso significa que a tipografia da mídia impressa geralmente é rica e sofisticada, de modo que a experiência de leitura seja realmente agradável. Pense na última vez que você gostou de ler uma revista excelente.

Web designers e desenvolvedores têm restrições diferentes dos designers de impressão, e uma importante é os custos de largura de banda associados de nossos designs. Esse tem sido um desafio para experiências tipográficas mais ricas, porque elas têm um custo. Com fontes da Web tradicionais, cada estilo usado nos nossos designs exige que os usuários façam o download de um arquivo de fonte separado, o que aumenta a latência e o tempo de renderização da página. A inclusão apenas dos estilos regular e negrito, além dos estilos em itálico, pode ultrapassar 500 KB ou mais de dados de fonte. Isso é mesmo antes de lidarmos com a forma como as fontes são renderizadas, os padrões de substituição que precisamos usar ou efeitos colaterais indesejáveis, como FOIT e FOUT.

Muitas famílias de fontes oferecem uma variedade muito mais ampla de estilos, de pesos finos a pretos, larguras estreitas e largas, vários detalhes estilísticos e até mesmo designs específicos para tamanhos (otimizados para textos grandes ou pequenos). Como é necessário carregar um novo arquivo de fonte para cada estilo (ou combinação de estilos), muitos desenvolvedores da Web optam por não usar esses recursos, reduzindo a experiência de leitura dos usuários.

Anatomia de uma fonte variável

As fontes variáveis resolvem esses desafios ao empacotar estilos em um único arquivo.

Isso funciona começando com um estilo central ou "padrão", geralmente o "Regular", um design romano vertical com peso e largura mais comuns, mais adequado para texto simples. Isso é conectado a outros estilos em um intervalo contínuo, chamado de "eixo". O eixo mais comum é Peso, que pode conectar o estilo padrão a um estilo em negrito. Qualquer estilo individual pode estar localizado ao longo de um eixo e é chamado de "instância" da variável font. Algumas instâncias são nomeadas pelo desenvolvedor da fonte. Por exemplo, o local do eixo de peso 600 é chamado de SemiBold.

A fonte variável Roboto Flex tem três estilos para o eixo Peso. O estilo regular está no centro, e há dois estilos nas extremidades opostas do eixo, um mais leve e o outro mais pesado. Entre elas, é possível escolher entre 900 instâncias:

A letra "A" em diferentes pesos
Acima: ilustração do eixo de peso da família tipográfica Roboto.

O desenvolvedor de fontes pode oferecer um conjunto de eixos diferentes. É possível combiná-los, porque todos compartilham os mesmos estilos padrão. Roboto tem três estilos em um eixo de largura: o regular está no centro do eixo, e dois estilos, mais estreitos e mais largos, estão em cada extremidade. Eles fornecem todas as larguras do estilo normal e combinam com o eixo de peso para fornecer todas as larguras de cada peso.

Roboto Flex em combinações aleatórias de largura e peso

Isso significa que há milhares de estilos! Isso pode parecer um exagero, mas a qualidade da experiência de leitura pode ser incrivelmente aprimorada por essa diversidade de estilos de tipografia. E, se não prejudicar a performance, os desenvolvedores da Web podem usar alguns ou quantos estilos quiserem. O design depende dos estilos disponíveis.

Itálico

A maneira como os itálicos são tratados em fontes variáveis é interessante, porque há duas abordagens diferentes. Famílias tipográficas como Helvetica ou Roboto têm contornos compatíveis com interpolação. Dessa forma, os estilos romano e itálico podem ser interpolados entre e o eixo Inclinar pode ser usado para mudar de romano para itálico.

Outras famílias tipográficas (como Garamond, Baskerville ou Bodoni) têm contornos de glifos romanos e itálicos que não são compatíveis com interpolação. Por exemplo, os contornos que normalmente definem um "n" minúsculo romano não correspondem aos usados para definir um "n" em itálico e minúsculo. Em vez de interpolar um contorno ao outro, o eixo Itálico alterna do contorno romano para o itálico.

Exemplo de eixos de peso para a família tipográfica Amstelvar
Contornos em "n" de Amstelvar em itálico (12 pontos, peso normal, largura normal) e em romano. Imagem fornecida por David Berlow, designer de tipografia e tipografia da Font Bureau.

Após a mudança para o itálico, os eixos disponíveis ao usuário precisam ser os mesmos do romano, assim como o conjunto de caracteres precisa ser o mesmo.

A capacidade de substituição de glifos também pode ser vista para glifos individuais e usada em qualquer lugar no espaço de design de uma fonte variável. Por exemplo, um design de cifrão com duas barras verticais funciona melhor em tamanhos de ponto maiores, mas, em pontos menores, um design com apenas uma barra é melhor. Quando temos menos pixels para renderizar o glifo, um design de duas barras pode ficar ilegível. Para combater isso, assim como no eixo itálico, pode ocorrer uma substituição de glifo de um glifo por outro ao longo do eixo de Tamanho óptico em um ponto decidido pelo designer de tipografia.

Em resumo, quando os contornos permitirem, os designers de tipografia podem criar fontes que interpolam entre vários estilos em um espaço de design multidimensional. Isso dá a você um controle granular sobre a tipografia e muita potência.

Definições de eixos

Há cinco eixos registrados, que controlam recursos conhecidos e previsíveis da fonte: peso, largura, tamanho óptico, inclinação e itálico. Além disso, uma fonte pode conter eixos personalizados. Eles podem controlar qualquer aspecto de design da fonte que o designer de tipografia quiser: o tamanho das serifas, o comprimento das páginas, a altura das ascendentes ou o tamanho do ponto no i.

Mesmo que os eixos possam controlar o mesmo atributo, eles podem usar valores diferentes. Por exemplo, nas fontes variáveis Oswald e Hepta Slab, há apenas um eixo disponível, Peso, mas os intervalos são diferentes. Oswald tem o mesmo intervalo de antes do upgrade para ser variável, de 200 a 700, mas Hepta Slab tem um peso excesso de linha do cabelo em 1, que chega a 900.

Os cinco eixos registrados têm tags em letras minúsculas de quatro caracteres, usadas para definir os valores no CSS:

Nomes de eixo e valores CSS
Peso wght
Largura wdth
Incerto slnt
Tamanho óptico opsz
Itálico ital

Como o desenvolvedor de fontes define quais eixos estão disponíveis em uma fonte variável e quais valores eles podem ter, é essencial descobrir o que cada fonte oferece. A documentação da fonte precisa informar isso. Se preferir, inspecione a fonte usando uma ferramenta como o Wakamai Fondue.

Casos de uso e benefícios

Definir os valores dos eixos se resume a gosto pessoal e aplicar práticas recomendadas tipográficas. O perigo de qualquer nova tecnologia é um possível uso indevido, e configurações excessivamente artísticas ou exploratórias também podem diminuir a legibilidade do texto real. Para títulos, explorar diferentes eixos para criar ótimos designs artísticos é empolgante, mas, para o corpo do texto, isso pode tornar o texto ilegível.

Expressão animada

Exemplo do Grass por Mandy Michael

Um ótimo exemplo de expressão artística é uma análise detalhada da família tipográfica Decovar, de Mandy Michael.

Você pode ver o exemplo de trabalho e o código-fonte para o exemplo acima aqui.

Animação

Typeface Zycon, projetado para animação de David Berlow, designer de tipografia e tipografia da Font Bureau.

Também é possível animar personagens com fontes variáveis. Acima está um exemplo de diferentes eixos sendo usados com a família tipográfica Zycon. Confira o exemplo de animação em tempo real no eixo praxis.

Anicons é a primeira fonte de ícones de cores animadas do mundo, baseada nos ícones do Material Design. Anicons é um experimento que combina duas tecnologias de fonte modernas: fontes variáveis e fontes de cores.

Alguns exemplos de animações ao passar o cursor da fonte do ícone colorido do Anicon

Refinamento

A Amstelvar usa pequenos pedaços de XTRA em direções opostas para que a largura das palavras seja uniforme.

A Roboto Flex e o Amstelvar oferecem um conjunto de "Eixos paramétricos". Nesses eixos, as letras são desconstruídas em quatro aspectos fundamentais da forma: formas pretas ou positivas, formas brancas ou negativas e as dimensões x e y. Da mesma forma que as cores primárias podem ser mescladas com qualquer outra cor para ajustá-las, esses quatro aspectos podem ser usados para ajustar qualquer outro eixo.

O eixo XTRA em Amstelvar permite ajustar o "branco" por valor mil, conforme mostrado acima. Usando pequenos pedaços de XTRA em direções opostas, as larguras das palavras são niveladas.

Fontes variáveis no CSS

Como carregar arquivos de fontes variáveis

As fontes variáveis são carregadas usando o mesmo mecanismo @font-face que as fontes estáticas da Web tradicionais, mas com duas novas melhorias:

@font-face {
    font-family: 'Roboto Flex';
    src: url('RobotoFlex-VF.woff2') format('woff2-variations');
    src: url('RobotoFlex-VF.woff2') format('woff2') tech('variations');
    font-weight: 100 1000;
    font-stretch: 25% 151%;
}

1. Formatos de fonte: não queremos que o navegador faça o download da fonte se não oferecer suporte a fontes variáveis. Por isso, adicionamos as descrições format e tech: uma vez na sintaxe futura (format('woff2') tech('variations')), uma vez na sintaxe descontinuada, mas compatível com os navegadores (format('woff2-variations')). Se o navegador oferecer suporte a fontes variáveis e oferecer suporte à próxima sintaxe, ele usará a primeira declaração. Se for compatível com fontes de variáveis e a sintaxe atual, ele usará a segunda declaração. Os dois apontam para o mesmo arquivo de fonte.

2. Intervalos de estilo: estamos fornecendo dois valores para font-weight e font-stretch. Em vez de informar ao navegador o peso específico dessa fonte (por exemplo, font-weight: 500;), agora fornecemos o intervalo de pesos com suporte à fonte. Para a Roboto Flex, o eixo de peso varia de 100 a 1.000, e o CSS mapeia diretamente o intervalo do eixo para a propriedade de estilo font-weight. Ao especificar o intervalo em @font-face, qualquer valor fora desse intervalo será "limitado" para o valor válido mais próximo. O intervalo do eixo de largura é mapeado da mesma maneira para a propriedade font-stretch.

Se você estiver usando a API Google Fonts, tudo isso será resolvido. O CSS não só vai conter os formatos e intervalos de origem adequados, mas o Google Fonts também vai enviar fontes alternativas estáticas caso as fontes variáveis não sejam compatíveis.

Como usar pesos e larguras

No momento, os eixos que podem ser definidos de maneira confiável a partir do CSS são os eixos wght pelo font-weight e wdth pelo font-stretch.

Tradicionalmente, font-weight é definido como uma palavra-chave (light, bold) ou como um valor numérico entre 100 e 900, em etapas de 100. Com fontes variáveis, é possível definir qualquer valor dentro do intervalo de largura da fonte:

.kinda-light {
  font-weight: 125;
}

.super-heavy {
  font-weight: 1000;
}
O eixo de peso de Roboto Flex está sendo alterado de mínimo para máximo.

Da mesma forma, podemos definir font-stretch com palavras-chave (condensed, ultra-expanded) ou com valores percentuais:

.kinda-narrow {
  font-stretch: 33.3%;
}

.super-wide {
  font-stretch: 151%;
}
O eixo de largura de Roboto Flex está sendo alterado do mínimo para o máximo.

Uso de itálico e oblíquo

O eixo ital é destinado a fontes que contêm um estilo normal e um itálico. O eixo precisa ser um interruptor de ativação/desativação: o valor 0 está desativado e mostra o estilo normal, e o valor 1 mostra itálico. Ao contrário de outros eixos, não há transição. Um valor de 0.5 não fornecerá "metade itálico".

O eixo slnt é diferente do itálico, já que não é um novo estilo, apenas se inclina ao estilo normal. Por padrão, o valor dele é 0, o que significa que as formas padrão de letras verticais estão na vertical. A inclinação máxima de Roboto Flex é de -10 graus, o que significa que as letras vão inclinar para a direita quando vão de 0 a -10.

Seria intuitivo definir esses eixos usando a propriedade font-style, mas desde abril de 2020, ainda está sendo resolvido como fazer isso. Por enquanto, trate-os como eixos personalizados e os defina com font-variation-settings:

i, em, .italic {
    /* Should be font-style: italic; */
    font-variation-settings: 'ital' 1;
}

.slanted {
    /* Should be font-style: oblique 10deg; */
    font-variation-settings: 'slnt' 10;
}
O eixo inclinado de Roboto Flex está sendo alterado do mínimo para o máximo.

Como usar tamanhos ópticos

Uma família tipográfica pode ser renderizada muito pequena (uma nota de rodapé de 12px) ou muito grande (um título de 80px). As fontes podem responder a essas mudanças mudando as formas das letras para se adaptarem melhor a elas. Um tamanho pequeno pode ser melhor sem detalhes, enquanto um tamanho grande pode se beneficiar de mais detalhes e traços mais finos.

A letra "a" mostrada em diferentes tamanhos ópticos
A letra "a" no Roboto Flex em diferentes tamanhos de pixel, depois redimensionadas para o mesmo tamanho, mostra as diferenças no design. Faça um teste no Codepen

Uma nova propriedade CSS foi introduzida para este eixo: font-optical-sizing. Por padrão, ele é definido como auto, o que faz com que o navegador defina o valor do eixo com base em font-size. Isso significa que o navegador escolherá o melhor tamanho óptico automaticamente, mas, se você quiser desativar esse recurso, defina font-optical-sizing como none.

Também é possível definir um valor personalizado para o eixo opsz, se você quiser deliberadamente um tamanho óptico que não corresponda ao tamanho da fonte. O CSS a seguir faria o texto aparecer em um tamanho grande, mas em um tamanho óptico, como se fosse impresso em 8pt:

.small-yet-large {
  font-size: 100px;
  font-variation-settings: 'opsz' 8;
}

Usar eixos personalizados

Ao contrário dos eixos registrados, os eixos personalizados não serão mapeados para uma propriedade CSS existente. Portanto, sempre será necessário defini-los com font-variation-settings. As tags para eixos personalizados estão sempre em maiúsculas, para distingui-las dos eixos registrados.

A Roboto Flex oferece alguns eixos personalizados, e o mais importante é Grau (GRAD). Um eixo de classificação é interessante, porque muda o peso da fonte sem mudar a largura, de modo que as quebras de linha não sejam alteradas. Ao brincar com um eixo de classificação, você pode evitar ser forçado a mexer nas mudanças no eixo de peso que afetam a largura geral e, em seguida, mudanças no eixo de largura que afetam o peso geral.

O eixo de grau de Roboto Flex está sendo alterado de mínimo para máximo.

Como GRAD é um eixo personalizado, com um intervalo de -200 a 150 em Roboto Flex. Precisamos resolver isso com font-variation-settings:

.grade-light {
    font-variation-settings: `GRAD` -200;
}

.grade-normal {
    font-variation-settings: `GRAD` 0;
}

.grade-heavy {
    font-variation-settings: `GRAD` 150;
}

Fontes variáveis no Google Fonts

O Google Fonts expandiu o catálogo com fontes variáveis e adicionamos novas regularmente. No momento, a interface é voltada para escolher instâncias únicas da fonte: você seleciona a variação desejada, clique em "Selecionar este estilo" e ela é adicionada ao elemento <link>, que busca o CSS e as fontes do Google Fonts.

Para usar todos os eixos ou intervalos de valores disponíveis, é necessário escrever manualmente o URL para a API Google Fonts. A visão geral das fontes variáveis lista todos os eixos e valores.

A ferramenta Google Variable Fonts Links também pode fornecer os URLs mais recentes das fontes variáveis completas.

Herança de configurações de variação de fonte

Em breve, todos os eixos registrados serão compatíveis com as propriedades CSS existentes, mas, por enquanto, talvez seja necessário usar font-variation-settings como substituto. E, se a fonte tiver eixos personalizados, você também precisará de font-variation-settings.

No entanto, temos um pequeno pegadinha com font-variation-settings. Todas as propriedades não definidas de forma explícita são redefinidas automaticamente para o padrão. Os valores definidos anteriormente não são herdados. Isso significa que o seguinte não vai funcionar como esperado:

<span class="slanted grade-light">
    I should be slanted and have a light grade
</span>

Primeiro, o navegador vai aplicar font-variation-settings: 'slnt' 10 da classe .slanted. Em seguida, ele aplicará font-variation-settings: 'GRAD' -200 da classe .grade-light. No entanto, isso redefinirá o slnt para o padrão 0. O resultado será um texto com uma nota leve, mas não inclinado.

Felizmente, podemos contornar isso usando variáveis CSS:

/* Set the default values */
:root {
    --slnt: 0;
    --GRAD: 0;
}

/* Change value for these elements and their children */
.slanted {
    --slnt: 10;
}

.grade-light {
    --grad: -200;
}

.grade-normal {
    --grad: 0;
}

.grade-heavy {
    --grad: 150;
}

/* Apply whatever value is kept in the CSS variables */
.slanted,
.grade-light,
.grade-normal,
.grade-heavy {
    font-variation-settings: 'slnt' var(--slnt), 'GRAD' var(--GRAD);
}

As variáveis CSS serão aplicadas em cascata. Portanto, se um elemento ou um dos pais dele tiver definido o slnt como 10, ele manterá esse valor, mesmo que você defina GRAD como outro elemento. Consulte Como corrigir a herança de fontes variáveis para ver uma explicação detalhada dessa técnica.

A animação de variáveis CSS não funciona (por padrão), então algo semelhante a este não funciona:

@keyframes width-animation {
   from { --wdth: 25; }
   to   { --wdth: 151; }
}

Essas animações precisam acontecer diretamente no font-variation-settings.

Ganhos de desempenho

As fontes variáveis OpenType permitem armazenar diversas variações de uma família de tipos em um único arquivo de fonte. O Monotype realizou um experimento combinando 12 fontes de entrada para gerar oito pesos, em três larguras, nos estilos itálico e romano. Armazenar 48 fontes individuais em um único arquivo de fonte variável significava uma redução de 88% no tamanho do arquivo.

No entanto, se você estiver usando uma única fonte, como Roboto Regular, e nada mais, talvez não note um ganho líquido no tamanho da fonte ao mudar para uma fonte variável com muitos eixos. Como sempre, isso depende do caso de uso.

Por outro lado, animar a fonte entre as configurações pode causar problemas de desempenho. Embora isso melhore quando o suporte a fontes variáveis nos navegadores ficar mais maduro, o problema pode ser reduzido um pouco apenas animando as fontes que estão atualmente na tela. Este snippet útil do Dinamo pausa as animações nos elementos com a classe vf-animation quando elas não estão na tela:

var observer = new IntersectionObserver(function(entries, observer) {
  entries.forEach(function(entry) {
    // Pause/Play the animation
    if (entry.isIntersecting) entry.target.style.animationPlayState = "running"
    else entry.target.style.animationPlayState = "paused"
  });
});

var variableTexts = document.querySelectorAll(".vf-animation");
variableTexts.forEach(function(el) { observer.observe(el); });

Se a fonte responder à interação do usuário, é recomendável limitar ou reduzir os eventos de entrada. Isso vai impedir que o navegador renderize instâncias da fonte variável que mudou tão pouco desde a instância anterior que o olho humano não perceberia a diferença.

Se você estiver usando o Google Fonts, recomendamos pré-conectar ao https://fonts.gstatic.com, o domínio onde as fontes do Google estão hospedadas. Isso garante que o navegador saiba cedo onde conseguir as fontes quando se deparar com elas no CSS:

<link rel="preconnect" href="https://fonts.gstatic.com" />

Essa dica também funciona para outras CDNs: quanto mais cedo você permitir que o navegador configure uma conexão de rede, mais rápido ele poderá fazer o download das fontes.

Confira mais dicas de desempenho para o carregamento do Google Fonts no artigo As fontes mais rápidas do Google.

Substitutos e suporte ao navegador

Todos os navegadores modernos são compatíveis com fontes variáveis. Caso você precise oferecer suporte a navegadores mais antigos, crie seu site com fontes estáticas e use fontes variáveis como aprimoramento progressivo:

/* Set up Roboto for old browsers, only regular + bold */
@supports not (font-variation-settings: normal) {
  @font-face {
    font-family: Roboto;
    src: url('Roboto-Regular.woff2');
    font-weight: normal;
  }

  @font-face {
    font-family: Roboto;
    src: url('Roboto-Bold.woff2');
    font-weight: bold;
  }

  body {
    font-family: Roboto;
  }

  .super-bold {
    font-weight: bold;
  }
}

/* Set up Roboto for modern browsers, all weights */
@supports (font-variation-settings: normal) {
  @font-face {
    font-family: 'Roboto';
    src: url('RobotoFlex-VF.woff2') format('woff2 supports variations'),
         url('RobotoFlex-VF.woff2') format('woff2-variations');
    font-weight: 100 1000;
    font-stretch: 25% 151%;
  }

  .super-bold {
    font-weight: 1000;
  }
}

Para navegadores mais antigos, o texto com a classe .super-bold será renderizado em negrito normal, porque essa é a única fonte em negrito disponível. Quando fontes variáveis são compatíveis, podemos usar o peso mais pesado de 1.000.

A regra @supports não é compatível com o Internet Explorer. Por isso, esse navegador não exibiria nenhum estilo. Se isso for um problema, você pode usar uma das hacks à moda antiga para segmentar navegadores mais antigos relevantes.

Se você estiver usando a API Google Fonts, ela vai carregar as fontes adequadas para os navegadores do visitante. Digamos que você solicite a fonte Oswald no intervalo de peso de 200 a 700, assim:

<link href="https://fonts.googleapis.com/css2?family=Oswald:wght@200..700&display=swap" rel="stylesheet">

Os navegadores mais recentes que podem processar fontes variáveis terão a fonte variável e terão todos os pesos entre 200 e 700 disponíveis. Navegadores mais antigos recebem fontes estáticas individuais para cada peso. Nesse caso, isso significa que ele fará o download de seis arquivos de fontes: um para o peso 200, outro para o peso 300 e assim por diante.

Até logo!

Este artigo só teria sido possível com a ajuda das seguintes pessoas:

Imagem principal de Bruno Martins no Unsplash.