Qué son FOUT y FOIT
Son dos problemas relacionados con la carga de fuentes web (@font-face) en webs:
FOUT (Flash of Unstyled Text)
El texto aparece con una fuente fallback mientras se descarga la fuente web. Cuando la fuente web carga, el texto “salta” a esa fuente. Visible como un cambio de estilo en el texto.
FOIT (Flash of Invisible Text)
El texto no aparece en absoluto hasta que la fuente web termina de cargar. Pantalla con texto invisible durante unos cientos de ms.
Cuál es peor
FOIT es peor porque oculta contenido. El usuario espera con incertidumbre.
FOUT es feo pero al menos el contenido es visible y legible inmediatamente.
Por qué pasan
Comportamiento por defecto del navegador con @font-face:
@font-face {
font-family: 'Inter';
src: url('/inter.woff2') format('woff2');
/* Sin font-display: el navegador decide */
}
Sin font-display, navegadores modernos usan FOIT con timeout de 3 segundos. Si la fuente no carga en 3s, usan fallback. Pero los 3s de invisibilidad son terribles.
Cómo controlarlo: font-display
font-display: swap
@font-face {
font-family: 'Inter';
src: url('/inter.woff2') format('woff2');
font-display: swap;
}
Significa:
- Mostrar fallback inmediatamente (texto visible desde el primer frame)
- Cuando la fuente web carga, swap a esa fuente (cambio visible: FOUT)
Lo más recomendado. UX > estética inicial.
font-display: fallback
Similar a swap pero con tiempo limitado de swap:
- Bloqueo invisible breve (~100ms)
- Swap si la fuente llega a tiempo
- Si tarda más de 3s, ignora la fuente y usa fallback permanentemente
font-display: optional
- Bloqueo invisible muy breve (~100ms)
- Si la fuente no llega → usa fallback PERMANENTEMENTE (no swap)
- Usuario solo verá la fuente web en visitas posteriores cuando esté en caché
Ideal para fuentes web cuya carga rápida no es crítica.
font-display: block
Comportamiento clásico: FOIT con timeout 3s. NO recomendado.
Cómo reducir el FOUT al máximo
1. Preload de fuentes críticas
<link rel="preload" href="/inter.woff2" as="font" type="font/woff2" crossorigin>
Empieza descarga antes de parsear CSS.
2. Usar size-adjust para minimizar shift
@font-face {
font-family: 'Inter';
src: url('/inter.woff2') format('woff2');
font-display: swap;
size-adjust: 100.06%; /* ajusta para que coincida con fallback */
ascent-override: 90%;
descent-override: 22.43%;
line-gap-override: 0%;
}
Hace que la fuente fallback se parezca dimensionalmente a la final, reduciendo el “salto” visual al swap.
Herramienta: Fontaine para Vue/Astro, automatiza esto.
3. Subset de la fuente
Si solo usas caracteres latinos, no descargues toda la fuente con CJK + cirílico:
@font-face {
font-family: 'Inter';
src: url('/inter-latin.woff2') format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
Reduce tamaño de fuente un 80-90%.
4. Formato WOFF2
Compresión moderna. 30% más pequeño que WOFF.
5. Self-host (no Google Fonts CDN)
Servir fuentes desde tu propio dominio:
- Sin latencia DNS extra
- Sin SSL handshake extra
- Mejor caché
Impacto en CLS
El “salto” del FOUT puede causar layout shifts visibles (texto cambia de tamaño → empuja párrafos abajo).
Combinar font-display: swap + size-adjust minimiza este shift.
Audita CLS con Test de Velocidad Web.