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, você vai descobrir o que são fontes variáveis, os benefícios delas e como usá-las no seu trabalho. Primeiro, revise como a tipografia funciona na Web e quais inovações as fontes variáveis trazem.

Compatibilidade com navegadores

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

Introdução

Os termos "fonte" e "família tipográfica" são usados como sinônimos por desenvolvedores. No entanto, há uma diferença: um tipo de letra é o design visual subjacente que pode existir em muitas tecnologias de composição diferentes, e uma fonte é uma dessas implementações, em um 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 fonte única e específica, como negrito 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 incluídos em um único arquivo.

Uma composição de amostra e uma lista de diferentes estilos da família Roboto.
À esquerda: um exemplo da família tipográfica Roboto. Certo: estilos nomeados na 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 ser usadas (determinado pelo tipo de impressora que será usada) e assim por diante. mas podem usar quantos estilos de fonte 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 navegar em uma revista excelente.

Web designers e desenvolvedores têm restrições diferentes dos designers de impressão, e uma delas é o custo de largura de banda associado aos nossos designs. Isso tem sido um problema para experiências tipográficas mais ricas, já que elas têm um custo. Com as fontes da Web tradicionais, cada estilo usado nos nossos designs exige que os usuários baixem um arquivo de fonte separado, o que aumenta a latência e o tempo de renderização da página. Incluir apenas os estilos normal e negrito, além das versões em itálico, pode resultar em 500 KB ou mais de dados de fontes. Isso é antes mesmo de lidarmos com a renderização das fontes, 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 maior de estilos, desde pesos finos até pretos, larguras estreitas e largas, uma variedade de detalhes estilísticos e até mesmo designs específicos para tamanhos (otimizados para tamanhos de texto grandes ou pequenos). Como você teria que 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 a espessura e a largura mais típicas que são mais adequadas para texto simples. que é 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 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 600 do eixo de peso é 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 pesado. Entre elas, você pode escolher entre 900 instâncias:

A letra "A" mostrada em diferentes pesos.
Anatomia ilustrada do eixo "Peso" da família tipográfica Roboto.

O desenvolvedor da fonte pode oferecer um conjunto de eixos diferentes. É possível combiná-los porque todos compartilham os mesmos estilos padrão. A 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. Elas fornecem todas as larguras do estilo Regular e se combinam com o eixo "Peso" para fornecer todas as larguras para 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 muito melhorada com essa diversidade de estilos de fonte. E, se não houver penalidade de desempenho, os desenvolvedores da Web poderão usar quantos estilos quiserem, dependendo do design.

Itálico

A maneira como o itálico é processado 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 interpolação. Assim, os estilos normal e itálico podem ser interpolados entre si, e o eixo Inclinação pode ser usado para passar do normal 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" minúsculo romano não correspondem aos contornos usados para definir um "n" minúsculo em itálico. 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 "n" da Amstelvar em itálico (12 pontos, peso normal, largura normal) e em romano. Imagem fornecida por David Berlow, designer de tipos e tipógrafo da Font Bureau.

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

Uma 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 cifrão com duas barras verticais funciona melhor em tamanhos de ponto 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 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 oferece controle granular sobre sua 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 disso, 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 dos traços ornamentais, a altura das ascendentes ou o tamanho do ponto no i.

Embora os eixos possam controlar o mesmo recurso, eles podem usar valores diferentes. Por exemplo, nas fontes variáveis Oswald e Hepta Slab, há apenas um eixo disponível, o peso, mas os intervalos são diferentes. A Oswald tem o mesmo intervalo de antes da atualização para variável, de 200 a 700, mas a Hepta Slab tem um peso de linha extrema em 1 que vai até 900.

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

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

Como o desenvolvedor da fonte 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 essa informação. Também é possível inspecionar a fonte usando uma ferramenta como o Wakamai Fondue (link em inglês).

Casos de uso e benefícios

Definir os valores dos eixos depende do gosto pessoal e da aplicação das práticas recomendadas tipográficas. O perigo de qualquer nova tecnologia é o 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 é interessante, mas para o texto principal, isso corre o risco de tornar o texto ilegível.

Expressão de entusiasmo

Exemplo de grama de Mandy Michael
Confira este exemplo no CodePen.

Este ótimo exemplo de expressão artística é uma exploração da família tipográfica Decovar de Mandy Michael.

Animação

A família tipográfica Zycon, criada para animação por David Berlow, designer de tipos e tipógrafo da Font Bureau.

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

Anicons (link em inglês) é a primeira fonte de ícones coloridos animados do mundo, baseada nos ícones do Material Design. O Anicons é um experimento que combina duas tecnologias de fontes de ponta: fontes variáveis e fontes coloridas.

Alguns exemplos de animações de passar o cursor do conjunto de ícones coloridos do Anicon

Finesse

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

Roboto Flex e 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. Assim como as cores primárias podem ser misturadas com qualquer outra cor para ajustar, esses quatro aspectos podem ser usados para ajustar qualquer outro eixo.

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

Fontes variáveis em CSS

Carregando arquivos de fontes variáveis

As fontes variáveis são carregadas pelo mesmo mecanismo @font-face das fontes da Web estáticas 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 for compatível com fontes variáveis. Por isso, adicionamos descrições format e tech: uma na sintaxe futura (format('woff2') tech('variations')) e outra na sintaxe descontinuada, mas compatível entre navegadores (format('woff2-variations')). Se o navegador for compatível com fontes variáveis e com a sintaxe futura, ele usará a primeira declaração. Se ele for compatível com fontes variáveis e a sintaxe atual, usará a segunda declaração. Ambos apontam para o mesmo arquivo de fonte.

2. Intervalos de estilo: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 compatíveis com a 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 dele será limitado ao valor válido mais próximo. O intervalo do eixo de largura é mapeado da mesma forma para a propriedade font-stretch.

Se você estiver usando a API Google Fonts, tudo isso será feito. Além de conter os formatos e intervalos de origem adequados, o CSS também envia fontes estáticas de substituição caso as fontes variáveis não sejam compatíveis.

Como usar pesos e larguras

No momento, os eixos que podem ser definidos de forma confiável no CSS são o wght usando font-weight e o wdth usando font-stretch.

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

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

.super-heavy {
  font-weight: 1000;
}
O eixo de peso da Roboto Flex sendo alterado 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 sendo alterado do mínimo para o máximo.

Como usar itálico e oblíquo

O eixo ital é destinado a fontes que contêm um estilo regular e um estilo itálico. O eixo é um botão liga/desliga: o valor 0 está desativado e mostra o estilo normal, enquanto o valor 1 mostra o itálico. Ao contrário de outros eixos, não há transição. Um valor de 0.5 não vai dar a você "meio itálico".

O eixo slnt é diferente do itálico 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. A Roboto Flex tem uma inclinação máxima de -10 graus, o que significa que as letras vão se inclinar para a direita ao passar de 0 para -10.

Seria intuitivo definir esses eixos usando a propriedade font-style, mas, em abril de 2020, a forma exata de fazer isso ainda está sendo definida. Por enquanto, trate-os como eixos personalizados e defina-os 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 está sendo alterado do mínimo para o máximo.

Como usar tamanhos ópticos

Um tipo de letra pode ser renderizado muito pequeno (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 alterando o formato das letras para se adequar 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" em Roboto Flex em diferentes tamanhos de pixels, depois dimensionada para ter o mesmo tamanho, mostra as diferenças no design. Teste por conta própria 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.

Você também pode definir um valor personalizado para o eixo opsz se quiser deliberadamente um tamanho óptico que não corresponda ao tamanho da fonte. O CSS a seguir faria com que o texto fosse exibido 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, você sempre terá que defini-los usando font-variation-settings. As tags para eixos personalizados estão sempre em maiúsculas para diferenciá-las dos eixos registrados.

A Roboto Flex oferece alguns eixos personalizados, e o mais importante é o Grade (GRAD). Um eixo Grade é interessante porque muda a espessura da fonte sem alterar as larguras, então as quebras de linha não mudam. Ao usar um eixo de graduação, você evita ter que fazer mudanças no eixo de peso que afetam a largura geral e, em seguida, no eixo de largura que afeta o peso geral.

O eixo de grau da Roboto Flex sendo alterado do mínimo para o máximo.

Como GRAD é um eixo personalizado, com um intervalo de -200 a 150 na Roboto Flex. Para resolver isso, use 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 adiciona novas regularmente. No momento, a interface tem como objetivo escolher instâncias únicas da fonte: você seleciona a variação desejada, clica 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, crie manualmente o URL da API Google Fonts. A visão geral das 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 font-variation-settings

Embora todos os eixos registrados sejam compatíveis em breve com as propriedades CSS atuais, por enquanto talvez seja necessário usar font-variation-settings como substituto. Se a fonte tiver eixos personalizados, você também vai precisar de font-variation-settings.

No entanto, há um pequeno 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 padrão de 0. O resultado será um texto em um tom 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 são transmitidas em cascata. Portanto, se um elemento (ou um dos pais dele) tiver definido slnt como 10, ele vai manter esse valor, mesmo que você defina GRAD como outra coisa. Consulte Correção da herança de fontes variáveis para uma explicação detalhada dessa técnica.

A animação de variáveis CSS não funciona (por design). Portanto, algo como isto não funciona:

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

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

Ganhos de desempenho

As fontes variáveis OpenType permitem armazenar várias variações de uma família tipográfica em um único arquivo de fonte. A Monotype fez 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 significou uma redução de 88% no tamanho do arquivo.

No entanto, se você estiver usando uma única fonte, como Roboto Regular, e mais nada, 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 desempenho. Embora isso melhore quando o suporte a fontes variáveis em navegadores ficar mais maduro, o problema pode ser reduzido um pouco animando apenas as fontes que estão na tela no momento. 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, é uma boa ideia limitar ou remover duplicações de eventos de entrada. Isso evita 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 veria a diferença.

Se você estiver usando o Google Fonts, é recomendável fazer uma 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 buscar as fontes quando as encontrar no CSS:

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

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

Encontre mais dicas de desempenho para carregar o Google Fonts em The Fastest Google Fonts.

Substituições e suporte a navegadores

Todos os navegadores modernos são compatíveis com fontes variáveis. Se você precisar 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;
  }
}

Em navegadores mais antigos, o texto com a classe .super-bold será renderizado em negrito normal, já que essa é a única fonte em negrito disponível. Quando as fontes variáveis são compatíveis, podemos usar a formatação mais pesada de 1.000.

A regra @supports não é compatível com o Internet Explorer, então esse navegador não mostraria nenhum estilo. Se isso for um problema, use um dos truques da velha guarda para segmentar navegadores mais antigos relevantes.

Se você estiver usando a API Google Fonts, ela vai carregar as fontes adequadas para os navegadores dos visitantes. Suponha 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 recebem a fonte variável e têm todos os pesos entre 200 e 700 disponíveis. Navegadores mais antigos vão receber fontes estáticas individuais para cada peso. Nesse caso, isso significa que eles vão baixar seis arquivos de fontes: um para peso 200, um para peso 300 e assim por diante.

Obrigado

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