O font-display: swap manda o navegador mostrar o texto na hora com uma fonte de reserva e trocar pela fonte web assim que ela chegar. Ele elimina a espera do texto invisível, mas não elimina o deslocamento de layout: quando a fonte web é mais larga ou mais alta que a de reserva, o texto reflui na troca. Para ter texto rápido e layout estável ao mesmo tempo, use swap, carregue a fonte cedo e ajuste o tamanho da fonte de reserva ao da fonte web com size-adjust. As seções abaixo comparam os cinco valores de font-display e mostram o código de cada passo.
O que o font-display swap faz
O swap dá à face da fonte «um período de bloqueio extremamente curto e um período de troca infinito» (MDN, última modificação em 10 de setembro de 2026). Em termos simples, o texto nunca fica escondido por muito tempo, e a fonte web é usada assim que termina de carregar, mesmo um minuto depois.
O MDN define os dois períodos assim. Durante o período de bloqueio, um elemento que usa uma fonte ainda não carregada deve renderizar uma fonte de reserva invisível. Durante o período de troca, ele renderiza uma fonte de reserva visível, e uma fonte que carrega a tempo é usada normalmente. Os nomes comuns são FOIT (flash of invisible text, o período de bloqueio) e FOUT (flash of unstyled text, a troca).
Sem o font-display, quem decide é o navegador. O guia de fontes do web.dev (outubro de 2022) diz que os navegadores baseados em Chromium e o Firefox bloqueiam a renderização do texto por até 3 segundos se a fonte não tiver carregado, e que o Safari a bloqueia indefinidamente (web.dev). Trate isso como o comportamento dessas versões e confira os navegadores que você suporta.
O font-display é Baseline recentemente disponível desde janeiro de 2020 e amplamente disponível desde julho de 2022; o web-features o lista a partir do Chrome 60, Firefox 58, Safari 11.1 e Safari iOS 11.3 (web-features 3.44.0, 22 de outubro de 2026).
@font-face {
font-family: "Brand";
src: url("/fonts/brand.woff2") format("woff2");
font-weight: 400;
font-style: normal;
font-display: swap;
}
Comparação dos valores de font-display
Os cinco valores diferem só no tempo que o texto fica invisível e no tempo em que uma fonte atrasada ainda pode ser trocada. Períodos da tabela do web.dev:
| Valor | Período de bloqueio | Período de troca | Use para |
|---|---|---|---|
auto |
Decidido pelo navegador | Decidido pelo navegador | Sem escolha explícita (o padrão) |
block |
2 a 3 segundos | Infinito | Raramente: o texto fica oculto enquanto a fonte carrega |
swap |
0 ms | Infinito | Títulos e textos de marca que devem usar a fonte web |
fallback |
100 ms | 3 segundos | Um meio-termo: bloqueio muito curto, troca curta |
optional |
100 ms | Nenhum | Texto corrido, quando o layout estável importa mais que a fonte exata |

O web.dev recomenda swap quando o texto deve aparecer rápido na fonte web, desde que a fonte seja entregue cedo o bastante para não causar deslocamento de layout. Sua escolha mais performática é optional, com o custo de que a fonte web não será usada se chegar tarde. Ele sugere swap para a marca e elementos distintivos, e optional para o texto corrido (web.dev). Essa divisão é uma recomendação; nenhuma especificação a exige.
O Lighthouse também verifica isso. O insight Font display dele (outubro de 2025) pede que você defina font-display como swap ou optional para que o texto fique visível, e para swap aponta para os overrides de métricas de fonte para reduzir o deslocamento de layout (Chrome for Developers).
Pré-carregue a fonte que importa
O pré-carregamento inicia o download da fonte mais cedo, o que reduz o tempo gasto na fonte de reserva. Um preload para uma fonte hospedada por você precisa de as="font", do tipo MIME e de crossorigin:
<link rel="preload" href="/fonts/brand.woff2" as="font" type="font/woff2" crossorigin>
O MDN diz que crossorigin é obrigatório nos preloads de fonte e que deve corresponder ao modo CORS da requisição «mesmo quando a requisição não é entre origens», porque fontes são buscadas em modo CORS anônimo (MDN, maio de 2026).
Pré-carregue só o que a primeira tela precisa. O web.dev alerta que o preload ignora declarações unicode-range e que, se usado com cuidado, deve carregar um único formato de fonte. Para fontes que não são necessárias de imediato, dispense o preload. O preload é Baseline recentemente disponível desde janeiro de 2021 e amplamente disponível desde julho de 2023 (web-features 3.44.0).
Google Fonts ou hospedagem própria
Para o Google Fonts, adicione o parâmetro display à URL da folha de estilo e conecte-se cedo às duas origens de fonte:
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Crimson+Pro&display=swap" rel="stylesheet">
O parâmetro display aceita os mesmos cinco valores, e a documentação do Google diz que o padrão é auto e que outro valor costuma ser mais adequado (Google Fonts, atualizada em julho de 2024). Os arquivos de fonte precisam de crossorigin no preconnect porque, «diferentemente das folhas de estilo, os arquivos de fonte precisam ser enviados por uma conexão CORS» (web.dev).
Qual é mais rápido, Google Fonts ou hospedagem própria? O web.dev diz que a diferença é «menos clara» do que parece: nos dados do Web Almanac que ele cita, fontes de terceiros renderizaram mais rápido que as próprias, e a hospedagem própria tende a ganhar com um CDN e HTTP/2. Se você hospeda, você cuida das otimizações: sirva WOFF2 (o web.dev informa que ele comprime 30% melhor que o WOFF), faça subconjuntos com unicode-range e confira a licença da fonte antes.
Evite o deslocamento com uma fonte de reserva
O deslocamento na troca acontece porque a fonte de reserva e a fonte web têm métricas diferentes, e a correção é ajustar a reserva para combinar. O guia de CLS do web.dev aponta «fontes que renderizam maiores ou menores que a reserva inicial» como causa de deslocamento de layout, e uma boa pontuação de CLS é 0,1 ou menos (web.dev, abril de 2023). Para mais sobre todas as causas, veja o guia de cumulative layout shift.

A ferramenta é um segundo @font-face que aponta para uma fonte local e a redimensiona. O size-adjust escala os contornos dos glifos e as métricas por uma porcentagem, e ascent-override, descent-override e line-gap-override definem a caixa da linha:
@font-face {
font-family: "Poppins fallback";
src: local("Arial");
size-adjust: 60.85%;
}
body {
font-family: "Poppins", "Poppins fallback", sans-serif;
}
O 60,85% vale para um par de fontes, Poppins sobre Arial, então você precisa calcular o seu. O artigo do Chrome diz que o size-adjust é a largura média dos caracteres da fonte web dividida pela da fonte de reserva (538,01 / 884,14 = 60,85% neste caso), que na maioria das vezes isso só pode ser aproximado, e que os três descritores de override são calculados a partir do ascender, do descender e do line gap da fonte web divididos pelas unidades por em e pelo valor de size-adjust. Calcule-os para a sua fonte com uma das ferramentas que o artigo cita (atualizado em fevereiro de 2023): Fontaine, Capsize, next/font (desde o Next 13) ou @nuxtjs/fontaine (Chrome for Developers), e confira o resultado no navegador antes de confiar nele.
O suporte varia por descritor, segundo o MDN browser-compat-data 8.1.7 (outubro de 2026):
| Descritor | Chrome | Firefox | Safari |
|---|---|---|---|
size-adjust |
92 | 92 | 17 |
ascent-override, descent-override, line-gap-override |
87 | 89 | não suportado |
O web-features não lista os três overrides como Baseline, então o Safari no iPhone os ignora e ainda pode deslocar um pouco. A fonte de reserva também muda conforme o dispositivo: o artigo do Chrome observa que uma reserva Roboto no Android precisa de valores diferentes dos de Arial.
O efeito no texto do LCP no celular
As fontes web podem atrasar o Largest Contentful Paint quando o maior elemento é texto. O guia de LCP do web.dev diz que o texto só conta como renderizado depois do período de bloqueio; então um elemento menor pode ser reportado como LCP até que o texto com a fonte web apareça. Ele considera candidatos a LCP elementos de texto em nível de bloco, como <p> e <h1>, e um bom LCP é de 2,5 segundos ou menos (web.dev, setembro de 2025).
Em uma página cujo LCP é um título em fonte web, o download da fonte disputa espaço com todo o resto em uma conexão móvel lenta, o que torna o swap ou um preload valiosos. Como ler o elemento LCP está no guia de auditoria mobile com Lighthouse, e as outras causas de um LCP lento no guia de teste de velocidade mobile.
Confira o resultado em uma página de tamanho de celular
Depois da mudança, olhe a página em um carregamento a frio. Recarregue com o cache desativado em larguras de celular e observe se o título pula quando a fonte chega. O Mobile View Extension recarrega a aba com o user agent, o tamanho de tela e a densidade de pixels de um celular, então você vê o layout mobile e qual fonte de reserva aparece. Ele não mede tempo de carregamento, deslocamento de layout nem nenhuma métrica de velocidade, e usa as fontes e a conexão do seu computador, então a fonte de reserva de um celular pode parecer diferente. Meça com o Lighthouse e com dados de campo.
Perguntas frequentes
O que faz o font-display swap?
Ele mostra o texto imediatamente em uma fonte de reserva e a substitui pela fonte web quando ela carrega, sem limite de quão tarde essa troca pode acontecer. O período de bloqueio é extremamente curto e o período de troca é infinito (MDN).
Melhor usar swap ou optional?
Nenhum é melhor em todos os casos: o swap sempre termina com a sua fonte web, mas pode deslocar o layout, enquanto o optional evita o deslocamento e pode pular a fonte web em um carregamento lento. O web.dev sugere swap para a marca e optional para o texto corrido.
O font-display swap causa deslocamento de layout?
Pode causar. Quando a reserva e a fonte web têm métricas diferentes, a troca muda o tamanho e a altura de linha do texto e pode mover o conteúdo, o que o web.dev lista como causa de deslocamento. Ajustar a reserva com size-adjust reduz isso.
Devo pré-carregar fontes web?
Pré-carregue a uma ou duas fontes que a primeira tela precisa, com as="font" e crossorigin. O web.dev recomenda usar com moderação, porque o preload ignora unicode-range.