Critical CSS is the small set of rules needed to draw what a visitor sees before scrolling. Paste a page's HTML and stylesheet here, choose a screen size, and this tool lays the page out in a locked frame, keeps rules matching visible elements, and gives you an inline style block plus a deferred stylesheet link.
| Rule type | Kept when | Why |
|---|---|---|
| Style rule | Its selector matches an element whose top edge is inside the chosen height | That element is painted on first view |
| html, body, :root, * | Always | Base fonts, colours and custom properties affect everything visible |
| @media block | Kept with only its matching inner rules | Other screen sizes still get the right first paint |
| @font-face | Always (can be switched off) | Visible text needs its font declared |
| @keyframes | Its name is used by a kept rule | Animations on visible elements still work |
Updated
Browsers wait for every stylesheet in the head before drawing anything. Inlining the few rules the first screen needs, then loading the full file without blocking, lets the page appear sooner. This tool does that selection for you from code you paste. It runs in your browser and never fetches a URL, so paste the page's final HTML and CSS rather than a link.
The tool loads with a sample bakery page so you can see the result before pasting your own code.
<header class="top"><a class="logo" href="/">Harbour Bakes</a><nav class="links"><a href="/menu">Menu</a><a href="/order">Order</a></nav></header>
<section class="hero"><h1>Sourdough baked at dawn</h1><p>Order by 9pm for next morning pickup.</p><a class="btn" href="/order">Order bread</a></section>
<section class="menu"><h2>This week</h2><div class="cards"><div class="card">Seeded rye</div><div class="card">Olive fougasse</div></div></section>
<footer class="foot">Open Tuesday to Sunday</footer>@font-face { font-family: "Body"; src: local("Georgia"); }
:root { --brand: #9a3412; }
body { margin: 0; font-family: "Body", serif; color: #1c1917; }
.top { display: flex; justify-content: space-between; padding: 16px 24px; }
.links a { margin-left: 16px; color: var(--brand); }
.hero { min-height: 420px; padding: 48px 24px; background: #fff7ed; animation: rise .6s ease-out; }
.hero h1 { font-size: 40px; margin: 0 0 12px; }
.btn { display: inline-block; padding: 12px 20px; background: var(--brand); color: #fff; border-radius: 8px; }
.btn:hover { background: #7c2d12; }
.menu { padding: 48px 24px; }
.cards { display: grid; grid-template-columns: repeat(2, 1fr); gap: 16px; }
.card { padding: 24px; border: 1px solid #e7e5e4; border-radius: 12px; }
.foot { padding: 24px; background: #1c1917; color: #fff; }
@media (max-width: 600px) { .hero h1 { font-size: 30px; } .cards { grid-template-columns: 1fr; } }
@keyframes rise { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@keyframes spin { to { transform: rotate(360deg); } }This is the pattern described on web.dev. The style block holds the extracted rules; the preload link fetches the full file and applies it on load, and the noscript line is the fallback.
<head>
<style>
/* paste the extracted critical CSS here */
</style>
<link rel="preload" href="/styles.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="/styles.css"></noscript>
</head>| Situation | What happens | What to do |
|---|---|---|
| Styles added by scripts | Not seen, scripts do not run in the frame | Paste the rendered HTML instead of the template |
| Images without width and height | May collapse to zero height and pull later content up | Add width and height attributes to images |
| Web fonts | Not downloaded, so text may wrap differently | Leave a margin below your fold height |
| Selectors the browser rejects | Dropped by the browser before checking | Fix the syntax; the stats list how many rules were read |
| Very long pages | Only the first screen is kept, as intended | Run again at each screen size you care about |
There is no single fold. A phone in portrait might show 650 pixels of height while a laptop shows 800 and a large monitor shows more. Pick the sizes your visitors use most, and allow a margin below the line because people often start scrolling immediately.
The extractor counts an element as visible when its top edge sits above the chosen height. A tall hero that starts on screen and ends below it is kept, which is what you want.
Place the inline style block in the head before anything else that renders. Replace your normal stylesheet link with the preload pattern so the rest of the CSS loads without holding up the first paint.
Check the result with throttled network in your browser's developer tools. If something jumps or restyles when the full file arrives, a rule for a visible element was missed; add it to the inline block.
It follows the same idea in a simpler way. Those command line tools drive a real headless browser against your built pages. This page uses your own browser and pasted code, so treat the result as a close approximation and test the page afterwards.
rel=preload with as=style downloads the stylesheet without applying it. The onload handler switches rel to stylesheet once the file arrives, which applies it without blocking the first paint. The noscript copy covers visitors with scripts disabled.
Inline rules are re-sent with every HTML page, which is why the block should stay small. The full stylesheet is still a separate file, so it is cached as usual after the first visit.
No. A static page in your browser cannot load another site's code, so nothing is fetched. Open your page, view its source and stylesheet, and paste both in. Nothing you paste is uploaded.
Paste the compiled CSS file your build produces, not the source with @tailwind or @import lines. The extractor works on finished rules, and utility classes in your HTML are matched like any other selector.
Related: Core Web Vitals guide, CSS minifier, Web font loading, How to link CSS to HTML, CSS formatter.
Start for free or see all free tools. We.Inc is free to start, with no card needed. AI building is on paid plans from $20 a month.
We.Inc is an AI-powered website builder you can resell under your own brand. Launch a branded client dashboard, bill on Stripe Connect, and deliver AI-generated websites in minutes. White-label plans start at $99 a month for 25 client sites, with a 7-day free trial and no per-site fees.