Introdução a fontes variáveis na Web

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

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

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

Introdução

Os termos "fonte" e "tipo de letra" são usados de forma intercambiável pelos desenvolvedores. No entanto, há uma diferença: uma família tipográfica é o design visual que pode existir em várias tecnologias diferentes, 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 muitas vezes é ignorado é a distinção entre um estilo e uma família. Um estilo é uma família tipográfica única e específica, como negrito e itálico, e uma família é o conjunto completo de estilos.

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

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

Desafios para o designer e o desenvolvedor

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 podem usar (que é determinado pelo tipo de prensa móvel que será usada) e assim por diante. Mas eles podem usar quantos estilos de tipo de letra quiserem. Isso significa que a tipografia da mídia impressa geralmente é rica e sofisticada, para que a experiência de leitura seja realmente agradável. Pense na última vez que você gostou de ler uma revista excelente.

Designers e desenvolvedores da Web têm restrições diferentes dos designers de impressão, e uma importante é o custo de largura de banda associado aos nossos designs. Isso tem sido um ponto de discórdia para experiências tipográficas mais ricas, já que elas têm um custo. Com as fontes da Web tradicionais, cada estilo usado nos 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 correspondentes em itálico, pode totalizar 500 KB ou mais de dados de fonte. Isso acontece mesmo antes de tratarmos de como as fontes são renderizadas, os padrões de fallback que precisamos usar ou efeitos colaterais indesejáveis, como FOIT e FOUT.

Muitas famílias de fontes oferecem uma variedade muito maior de estilos, desde pesos finos a pretos, larguras estreitas e largas, uma variedade de detalhes estilísticos e até mesmo designs específicos de tamanho, otimizados para tamanhos de texto grandes ou pequenos. Como seria preciso carregar um novo arquivo de fonte para cada estilo (ou combinações 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 o peso e a largura mais típicos que são mais adequados para texto simples. Em seguida, ele é 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 Negrito. Qualquer estilo individual pode ser localizado ao longo de um eixo e é chamado de "instância" da fonte variável. Algumas instâncias são nomeadas pelo desenvolvedor da fonte. Por exemplo, o local da 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 claro e outro mais escuro. Você pode escolher entre 900 instâncias:

A letra "A" mostrada em diferentes pesos
Na imagem acima, a anatomia ilustrada do eixo "Weight" para a família tipográfica Roboto.

O desenvolvedor de fontes pode oferecer um conjunto de eixos diferentes. Você pode combiná-las porque todas compartilham os mesmos estilos padrão. O Roboto tem três estilos em um eixo de largura: o Regular está no centro do eixo, e dois estilos, mais estreito e mais largo, estão em cada extremidade. Elas fornecem todas as larguras do estilo Regular e se combinam com o eixo "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 notadamente aprimorada por essa diversidade de estilos de tipografia. E, se não houver queda de desempenho, os desenvolvedores da Web podem usar alguns ou quantos estilos quiserem, a critério do próprio design.

Itálico

A maneira como os itálicos são processados em fontes variáveis é interessante, já que há duas abordagens diferentes. Famílias tipográficas como Helvetica ou Roboto têm contornos compatíveis com a interpolação, então os estilos romano e itálico podem ser interpolados entre si, e o eixo Slant pode ser usado para passar do romano para o 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 a interpolação. Por exemplo, os contornos que normalmente definem um "n" romano em letras minúsculas não correspondem aos contornos usados para definir um "n" itálico em letras minúsculas. Em vez de interpolar um contorno para o outro, o eixo Itálico alterna entre contornos romanos e itálicos.

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

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

Um recurso de substituição de glifo também pode ser visto para glifos individuais e usado em qualquer lugar do espaço de design de uma fonte variável. Por exemplo, um design de cifrão com duas barras verticais funciona melhor em pontos maiores, mas em tamanhos 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 o eixo itálico, uma substituição de glifo por outro pode ocorrer ao longo do eixo Tamanho óptico em um ponto decidido pelo designer de tipo.

Em resumo, quando os contornos permitem, os designers de tipos 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 muito poder.

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 desses, uma fonte pode conter eixos personalizados. Eles podem controlar qualquer aspecto do design da fonte que o designer de tipos quiser: o tamanho das serifas, o comprimento das curvas, a altura das ascendentes ou o tamanho do ponto no i.

Embora os eixos possam controlar o mesmo elemento, 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. A Oswald tem o mesmo intervalo antes de ser atualizada para ser variável, de 200 a 700, mas a Hepta Slab tem um peso extremo de 1 que vai até 900.

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

Nomes de eixos 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 deve fornecer isso, ou você pode inspecionar a fonte usando uma ferramenta como o Wakamai Fondue.

Casos de uso e benefícios

A definição dos valores dos eixos depende do gosto pessoal e da aplicação de práticas tipográficas recomendadas. O perigo de qualquer nova tecnologia é o uso indevido, e configurações excessivamente artísticas ou exploratórias também podem diminuir a legibilidade do texto real. Para títulos, a exploração de eixos diferentes para criar designs artísticos incríveis é empolgante, mas, para o corpo do texto, isso pode tornar o texto ilegível.

Expressão empolgante

Exemplo de grama por Mandy Michael

Um ótimo exemplo de expressão artística é mostrado acima, uma exploração da fonte Decovar de Mandy Michael.

Confira o exemplo funcional e o código-fonte do exemplo acima aqui.

Animação

Tipo de letra Zycon, criado para animação de David Berlow, designer de tipografia e tipográfico do Font Bureau.

Também é possível animar caracteres com fontes variáveis. Acima, temos um exemplo de diferentes eixos usados com a família tipográfica Zycon. Confira o exemplo de animação ao vivo no Axis Praxis.

Anicons é a primeira fonte de ícones coloridos animados do mundo, baseada nos ícones do Material Design. Os anicons são um experimento que combina duas tecnologias de fonte de ponta: fontes variáveis e coloridas.

Alguns exemplos de animações de cursor da fonte de ícones coloridos do Anicon

Finesse

Amstelvar usando pequenos pedaços de XTRA em direções opostas para que as larguras das palavras sejam niveladas

A Roboto Flex e o Amstelvar oferecem um conjunto de "Eixos paramétricos". Nesses eixos, as letras são decompostas 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 misturadas com qualquer outra cor para fazer ajustes, esses quatro aspectos podem ser usados para ajustar qualquer outro eixo.

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

Fontes variáveis em CSS

Como carregar arquivos de fontes variáveis

As fontes variáveis são carregadas pelo 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 origem: não queremos que o navegador faça o download da fonte se ela não oferecer suporte a fontes de variáveis. Por isso, adicionamos descrições format e tech: uma vez na sintaxe futura (format('woff2') tech('variations')), uma vez na sintaxe descontinuada, mas compatível com a sintaxe do navegador (format('woff2-variations')). Se o navegador oferecer suporte a fontes variáveis e à sintaxe futura, ele vai usar a primeira declaração. Se ele oferecer suporte a fontes variáveis e à sintaxe atual, ele vai usar a segunda declaração. Ambos apontam para o mesmo arquivo de fonte.

2. Estilos de intervalo: você vai notar que estamos fornecendo dois valores para font-weight e font-stretch. Em vez de informar ao navegador qual peso específico essa fonte oferece (por exemplo, font-weight: 500;), agora fornecemos o intervalo de pesos aceitos pela fonte. No Roboto Flex, o eixo "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" ao 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, isso será feito automaticamente. Além de conter os formatos e intervalos de origem adequados, o CSS do Google Fonts também envia fontes de substituição estáticas caso não haja suporte para fontes variáveis.

Usar pesos e larguras

Atualmente, os eixos que você pode definir com segurança no CSS são o eixo wght por font-weight e o eixo wdth por font-stretch.

Tradicionalmente, você definiria font-weight como uma palavra-chave (light, bold) ou como um valor numérico entre 100 e 900, em incrementos 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;
}
Alteração do eixo de peso da Roboto Flex do mínimo para o 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 da Roboto Flex muda do mínimo para o máximo.

Como usar itálico e oblíquos

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

O eixo slnt é diferente dos itálicos porque não é um novo estilo, mas apenas inclina o estilo normal. Por padrão, o valor é 0, o que significa as formas de letras verticais padrão. O Roboto Flex tem uma inclinação máxima de -10 graus, o que significa que as letras se inclinam para a direita ao passar de 0 para -10.

Seria intuitivo definir esses eixos pela propriedade font-style, mas, em abril de 2020, ainda não sabemos exatamente como fazer isso. Ainda estamos trabalhando nisso. Por enquanto, trate-as como eixos personalizados e defina-as usando 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 de inclinação da Roboto Flex muda 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 12 px) ou muito grande (um título de 80 px). As fontes podem responder a essas mudanças de tamanho mudando as formas das letras para se adaptar melhor ao tamanho. 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 e dimensionadas para o mesmo tamanho mostra as diferenças de design. Teste no Codepen

Uma nova propriedade CSS foi introduzida para esse 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 no font-size. Isso significa que o navegador vai escolher o melhor tamanho óptico automaticamente, mas se você quiser desativar essa opção, defina font-optical-sizing como none.

Também é possível definir um valor personalizado para o eixo opsz, se você quiser um tamanho óptico que não corresponda ao tamanho da fonte. O CSS a seguir faria com que o texto fosse mostrado 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 são mapeados para uma propriedade CSS existente. Portanto, eles sempre precisam ser definidos por font-variation-settings. As tags dos eixos personalizados são sempre em maiúsculas, para diferenciá-los dos eixos registrados.

A Roboto Flex oferece alguns eixos personalizados, e o mais importante é Nota (GRAD). Um eixo de Nota é interessante, porque altera o peso da fonte sem alterar as larguras, portanto as quebras de linha não mudam. Ao usar uma Grade, é possível evitar mudanças na eixo Peso que afetam a largura geral e, em seguida, mudanças no eixo Largura que afetam o peso geral.

Eixo de grau da Roboto Flex mudando do mínimo para o máximo.

Como GRAD é um eixo personalizado, com um intervalo de -200 a 150 no 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 ampliou o catálogo com fontes variáveis, adicionando novas regularmente. No momento, a interface tem como objetivo selecionar instâncias únicas da fonte: selecione a variação desejada, clique em "Selecionar este estilo" e ela será 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, você terá que escrever manualmente o URL para a API Google Fonts. A visão geral de fontes variáveis lista todos os eixos e valores.

A ferramenta Links de fontes variáveis do Google também pode fornecer os URLs mais recentes para as fontes variáveis completas.

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

Embora todos os eixos registrados tenham suporte em breve nas propriedades CSS atuais, por enquanto talvez seja necessário usar font-variation-settings como alternativa. E se a fonte tiver eixos personalizados, você também vai precisar de font-variation-settings.

No entanto, há um problema com font-variation-settings. Todas as propriedades que você não definir explicitamente serã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 vai aplicar font-variation-settings: 'GRAD' -200 da classe .grade-light. Mas isso vai redefinir o slnt para o valor padrão de 0. O resultado será um texto com um grau claro, mas não inclinado.

Felizmente, podemos resolver 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 vão ser aplicadas em cascata. Portanto, se um elemento (ou um dos pais dele) definir slnt como 10, ele vai manter esse valor, mesmo que você defina GRAD como outro valor. Consulte Como corrigir a herança da fonte da variável para ver uma explicação detalhada dessa técnica.

A animação de variáveis CSS não funciona (por design), então algo como isto 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 várias variações de uma família de tipos em um único arquivo de fonte. A 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 significa uma redução de 88% no tamanho do arquivo.

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

Por outro lado, animar a fonte entre as configurações pode causar problemas de performance. Embora isso melhore quando o suporte a fontes variáveis nos navegadores ficar mais maduro, o problema pode ser reduzido de certa forma animando apenas as fontes que estão atualmente na tela. Este snippet útil do Dinamo pausa animações em elementos com a classe vf-animation quando eles 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 debouncear os eventos de entrada. Isso vai impedir que o navegador renderize instâncias da fonte variável que mudaram tão pouco da instância anterior que o olho humano não percebe a diferença.

Se você estiver usando o Google Fonts, é recomendável fazer a pré-conexão com https://fonts.gstatic.com, o domínio em que as fontes do Google estão hospedadas. Isso garante que o navegador saiba desde o início onde encontrar as fontes quando elas forem encontradas no CSS:

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

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

Confira mais dicas de desempenho sobre o carregamento do Google Fonts no artigo The mais rápido Google Fonts (em inglês).

Suporte a navegadores e substitutos

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 melhoria progressiva:

/* 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 as fontes variáveis são compatíveis, podemos usar o peso mais pesado de 1.000.

A regra @supports não tem suporte do Internet Explorer. Por isso, esse navegador não mostraria nenhum estilo. Se isso for um problema, você sempre poderá usar um dos truques antigos para segmentar navegadores mais antigos relevantes.

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

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

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

Obrigado

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

Imagem principal de Bruno Martins no Unsplash.