What is FOUC (flash of unstyled content)?
FOUC (flash of unstyled content): FOUC (flash of unstyled content) is when a browser briefly paints a page before its styles apply, so users see raw or wrong-looking content flicker.
A flash of unstyled content happens when HTML reaches the screen before the CSS that styles it. The user sees default fonts, stacked lists and blue links for a moment, then the layout snaps into place. The term dates from the early 2000s, when certain ways of loading stylesheets triggered it, but the underlying problem, painting before the right styles or state are ready, shows up in several modern forms.
Common causes
- Styles injected by JavaScript. CSS-in-JS without server-side extraction, or CSS loaded only by client code, applies after the first paint.
- Non-blocking stylesheets. A stylesheet loaded with a
mediaswap trick or added by a script does not block rendering, so the page paints without it. - Theme applied after hydration. A saved dark theme read in
useEffectproduces a flash of the wrong theme, usually also called FOUC. - Web fonts. A fallback font swapping to the web font is a related effect called FOUT (flash of unstyled text), and it can shift layout.
- Client-only content. Components that render nothing on the server and appear after mount cause visible jumps.
How to prevent it
Regular <link rel="stylesheet"> tags in the <head> are render-blocking, which is what you want for critical CSS: the browser waits for them before the first paint. Frameworks like Next.js extract CSS from your imports, including Tailwind CSS, and emit such links. For state that changes styling, such as the theme, decide it before paint with a small inline script:
<head>
<script>
try {
var t = localStorage.getItem("theme");
var dark = t ? t === "dark" : matchMedia("(prefers-color-scheme: dark)").matches;
if (dark) document.documentElement.classList.add("dark");
} catch (e) {}
</script>
<link rel="stylesheet" href="/app.css" />
</head>
For fonts, use font-display: swap or optional with a size-adjusted fallback (next/font generates one) so the swap does not move text. For client-only widgets, reserve their space with fixed dimensions or a skeleton screen so nothing jumps when they arrive. In React apps, also watch for hydration mismatches, which can force parts of the page to re-render on the client.
How MiniDev UI handles it
The ui.minidev.pro site uses one blocking head script to restore both the theme class and the data-material attribute before the first paint, the approach documented in Dark mode in Next.js without the flash. Components style themselves through tokens already defined in the stylesheet, so none of them injects CSS at runtime. Skeleton placeholders can match final dimensions to avoid layout shift while data loads.