Critical CSS View
A page-shaped visualiser of the critical CSS optimisation. Pass in a flat list of layout zones tagged with fold: "above" | "below"; the view stacks them as a mini mock page split by a fold line, with a coverage overlay that totals inline vs deferred bytes and an action button that flips between the un-optimised state (everything dim) and the extracted state (above-the-fold crisp, below-the-fold muted).
Pair with CriticalCssWidget (which is the rules-list view) — CriticalCssView is the page-shape view of the same optimisation.
Preview
Critical CSS extractor
Above-the-fold zones land in the inline tier; the rest stream behind.
nav
hero
hero img
card grid
footer
Coverage22% inline · 78% deferred
inline 13.0 KBdeferred 44.9 KB
Customize
Zone sizes (KB)
4.7KB
5.3KB
27.3KB
17.6KB
Layout
Installation
npx shadcn@latest add https://craftbits.dev/r/critical-css-view.jsonUsage
import { useState } from "react";
import { CriticalCssView, type CriticalCssViewZone } from "@craft-bits/core";
const zones: CriticalCssViewZone[] = [
{ id: "nav", label: "nav", fold: "above", kind: "nav", bytes: 4_800 },
{ id: "hero", label: "hero", fold: "above", kind: "hero", bytes: 5_400 },
{ id: "cards", label: "card grid", fold: "below", kind: "grid", bytes: 28_000 },
{ id: "footer", label: "footer", fold: "below", kind: "footer", bytes: 18_000 },
];
export function Demo() {
const [extracted, setExtracted] = useState(false);
return (
<CriticalCssView
title="Critical CSS extractor"
zones={zones}
extracted={extracted}
onToggle={() => setExtracted((p) => !p)}
/>
);
}Omit onToggle to render the view as a presentational diagram — the consumer drives the extracted flag from a step counter or playback timeline.
Anatomy
- Header. Optional
title(rendered with thecb-labelstyle) anddescription. Omit both for a chromeless panel. - Page mock. A stack of zone rows clipped by a dashed fold divider. Each row paints a tiny illustration matched to
kind— pill row fornav, two-line block forhero, image placeholder forimage, three-column skeleton forgrid, single line forfooter. - Fold line. A dashed border with an inline "fold" label, centred between the above and below tiers. Set
hideFoldLineto drop the divider. - Coverage overlay. A short strip beneath the mock page — left side prints
inline %, right side printsdeferred %, with a meter that grows to the inline ratio. Tints green onceextractedflips true. - Action button. When
onToggleis provided, renders a "Extract critical CSS / Reset extraction" toggle on the right. Carriesdata-cb-armed="true"while the un-optimised state is live so consumers can style the "next action" affordance.
Understanding the component
- Fold partition. Zones are partitioned on
fold— above zones stack at the top, below zones stack under the fold line. Bytes are summed per tier and surfaced in the coverage overlay. - Tone inversion. Above-the-fold rows paint crisp only once
extractedflips true; below-the-fold rows paint crisp in the un-optimised state and dim when extraction lands — that's the visual story for "this content used to load with the page, now it streams in behind the paint". - Illustration registry.
kindpicks the mini-illustration painted inside each row. Defaults to"block"(a plain skeleton). Heights default to a sensible value per kind and clamp to a 12-72 px range to keep the panel compact. - Motion. Each row crossfades between the crisp and muted tones with the
SPRINGS.smoothtoken, and the coverage meter grows with the same spring. Animations short-circuit underprefers-reduced-motion.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
zones | CriticalCssViewZone[] | required | Ordered list of mock page zones. |
extracted | boolean | required | true puts the view in the post-extraction state. |
onToggle | () => void | — | Optional click handler for the action button. Omit to hide it. |
title | ReactNode | — | Optional heading above the panel. |
description | ReactNode | — | Optional sub-headline under the title. |
actionLabels | { armed: string; disarmed: string } | sensible defaults | Override the action button copy. |
unit | string | 'KB' | Display unit suffix for byte counts. |
hideOverlay | boolean | false | Hide the coverage overlay strip. |
hideFoldLine | boolean | false | Hide the dashed fold divider. |
headingAs | 'h2' | 'h3' | 'h4' | 'h3' | Tag for the title element. |
className | string | — | Merged onto the root via cn(). |
CriticalCssViewZone
| Field | Type | Description |
|---|---|---|
id | string | Stable identifier. |
label | ReactNode | Visible row label. Pass empty for a chromeless block. |
fold | 'above' | 'below' | Which side of the fold the zone lives on. |
kind | 'nav' | 'hero' | 'image' | 'grid' | 'footer' | 'block' | Mini-illustration hint. Defaults to 'block'. |
heightPx | number | Row height; defaults per kind. Clamped to 12-72 px. |
bytes | number | Bytes contributed to the inline / deferred totals. Defaults to 0. |
Accessibility
- The wrapper is a
<section>withdata-cb-edu="critical-css-view"anddata-cb-extracted="true | false"mirroring the extraction state. - The mock page carries an
aria-labeldescribing it as the page layout split by the fold line; the fold divider itself isaria-hiddenbecause the divider text duplicates information that's already conveyed structurally. - Every zone row carries an
aria-labelof the form "Above the fold — 4.7 KB" so screen readers convey both the tier and the byte cost without depending on colour. - The coverage overlay lives in an
aria-live="polite"region so the percent updates are announced whenextractedflips. - The action button has visible text, a
focus-visiblering, and a subtleactive:scale-[0.98]press state. - Animations short-circuit under
prefers-reduced-motion.
Credits
- Extracted from:
terminal-dreams(src/components/frontend-design/perf-css/ui/CriticalCSSView.tsx). The original was wired to thecss-perf-simulatorengine (a fixedCSSRuleMockshape with hardcodedaboveFoldflags, a built-in rules list, and an FCP callout reading fromPerfContext). This rewrite strips the engine coupling and the rules-list double — consumers pass an arbitrary list of{ id, label, fold, kind, bytes }zones so the view can model any page layout, and the rules-side of the optimisation lives in the siblingCriticalCssWidget.