Critical CSS Inlining Guide

May 28, 20266 min read

What Is Critical CSS?

When a browser loads a page, it must download and parse every linked CSS file before it can render any content. A stylesheet in the <head> blocks rendering — even if 90% of its rules apply to elements below the fold. This delay is visible as a blank white screen, especially on slow connections.

Critical CSS is the subset of styles needed to render the above-the-fold content — everything visible in the viewport on initial load without scrolling. By inlining this CSS directly in the HTML <head> and loading the remaining stylesheet asynchronously, you eliminate the render-blocking delay.

The Render-Blocking Problem

A typical page loads CSS like this:

<head>
  <link rel="stylesheet" href="/styles.css">
</head>

The browser timeline looks like:

  1. Download HTML — wait for network
  2. Parse HTML, find <link> — stop rendering
  3. Download styles.css — wait for network again
  4. Parse CSS, build CSSOM
  5. Combine with DOM, render first pixel

Steps 2–4 add latency proportional to your CSS file size and network speed. A 200KB stylesheet on a 3G connection adds over one second of blank screen.

How Critical CSS Inlining Works

The optimized approach replaces the blocking link with inline styles and an asynchronous load:

<head>
  <style>
    /* Critical CSS: only above-the-fold rules */
    body { font-family: system-ui, sans-serif; margin: 0; }
    .hero { background: #1e1b4b; color: white; padding: 4rem 2rem; }
    .nav { display: flex; justify-content: space-between; padding: 1rem; }
  </style>
  <link rel="preload" href="/styles.css" as="style"
        onload="this.rel='stylesheet'">
  <noscript><link rel="stylesheet" href="/styles.css"></noscript>
</head>

Now the browser:

  1. Downloads HTML
  2. Parses inline <style> — renders first pixel immediately
  3. Preloads styles.css in the background
  4. Applies full stylesheet when ready — no visible flash if critical CSS was accurate

Extracting Critical CSS

Manual extraction is impractical for real projects. Use one of these tools:

ToolHow It WorksBest For
CriticalHeadless browser renders the page, captures used CSSStatic sites, SSG builds
PenthouseOpens URL at specific viewport, extracts matching rulesMulti-viewport extraction
crittersWebpack plugin, integrates into build pipelineNuxt, Next.js, Vite projects

For Nuxt projects, the nuxt-critical module automates extraction during generate:

npm install nuxt-critical
// nuxt.config.ts
export default defineNuxtConfig({
  modules: ['nuxt-critical'],
})

It extracts critical CSS per route during SSG and inlines it automatically.

Avoiding the Flash of Unstyled Content

If your critical CSS misses rules for above-the-fold elements, users see a brief flash of unstyled content (FOUC) before the full stylesheet loads. To minimize this:

  • Extract critical CSS at the most common viewport (1366×768 or 1440×900).
  • Include base typography — body, h1h6, p, a.
  • Include layout containers visible without scrolling.
  • Include any above-the-fold images or backgrounds referenced in CSS.

A good rule of thumb: if an element occupies space above the fold, its layout and typography styles belong in critical CSS.

Measuring the Impact

Use Lighthouse or Chrome DevTools to measure First Contentful Paint (FCP) before and after inlining:

npx lighthouse https://your-site.com --view --output=html

Typical improvements:

MetricBefore InliningAfter Inlining
FCP2.4s0.9s
Render-blocking resources2 CSS files0
Largest Contentful Paint3.1s1.8s

Results vary by site, but FCP improvements of 40–60% are common when moving from a single large blocking stylesheet to critical CSS inlining.

Limitations and Trade-offs

  • HTML size increases — inline CSS adds kilobytes to every HTML response and cannot be cached separately. Keep critical CSS under 14KB (the typical TCP window size) for maximum benefit.
  • Maintenance burden — critical CSS must be re-extracted when above-the-fold design changes. Automate this in your build pipeline.
  • Not needed for HTTP/2 multiplexed small files — if your architecture already splits CSS into many small, cached chunks, the render-blocking delay is minimal and inlining provides less benefit.

Key Takeaways

  • Critical CSS is the minimum CSS needed to render above-the-fold content.
  • Inlining critical CSS eliminates render-blocking stylesheet delays.
  • Load remaining CSS asynchronously via rel="preload" with a stylesheet fallback.
  • Automate extraction with tools like Critical, Penthouse, or nuxt-critical.
  • Keep inline critical CSS under 14KB to stay within the initial TCP window.
  • Re-extract critical CSS whenever your design changes — integrate into your build pipeline.

Try It Yourself

Shrink your CSS payload by minifying your stylesheets with the CSS Minifier.