A single-file HTML magazine
The Browser Is Already a UI Library
Native elements, selectors and APIs that replace entire component libraries. No framework required.
01
Open
Disclosure, modals and floating UI — all built into the platform.
details / summary
Native accordion. No JS required for open/close.
What is progressive enhancement?
Start with working HTML, then layer CSS and JS. The core experience never breaks.
Why prefer native controls?
Accessibility, keyboard support, and platform conventions come free.
dialog
Modal with focus trap, backdrop and Escape handling.
popover
Lightweight floating UI. Top-layer, light dismiss.
Click outside or press Escape to dismiss.
command / invoker
Declarative actions via command & commandfor (emerging).
Use popovertarget today; command buttons are landing in browsers for even cleaner invokers.
02
Input
Form controls that already know about dates, colours, ranges and validation.
date · colour · range
datalist · validation · inputmode
03
Reveal
Show and hide content with pure CSS and a couple of attributes.
:target
Style the element whose ID matches the URL hash.
hidden="until-found" · inert
until-found keeps content searchable. inert removes interactivity.
Use hidden="until-found" so find-in-page can still discover the content.
Apply inert to background UI when a modal is open.
05
Move
Scrolling, snapping and page transitions handled by the browser.
scroll-snap
Swipe or scroll horizontally — cards snap into place.
Card 01
scroll-snap-align: center
Card 02
Native momentum & physics
Card 03
No carousel library needed
Card 04
Works with keyboard too
Card 05
Accessible by default
View Transitions API
Smooth morph between states. Click to toggle.
Scroll-driven animation
Animate tied to scroll progress with animation-timeline: scroll().
Progress bars, parallax and reveal effects can now be driven by scroll position with pure CSS — no IntersectionObserver required for many cases.
06
Style
Selectors and colour functions that make component CSS far simpler.
:has()
Parent reacts to its children. Check the box.
Container queries
This card changes layout based on its own width.
No media-query breakpoint needed.
color-mix · light-dark
This page uses light-dark() and color-mix() for theme-aware colours. Toggle your OS dark mode to see it adapt.
corner-shape · custom properties
Squircle-ish corners (where supported) and design tokens via custom properties.
07
Let the browser work
Stop re-implementing what the platform already does well.
loading="lazy"
Images below the fold load only when needed.
Semantic HTML & native controls
Prefer <button>, <a>, <input>, <dialog>,
<details> over div + role soup. The browser gives you
keyboard support, focus management and accessibility tree mappings for free.
08
Adapt
Light and dark is one axis. A data attribute per axis turns custom properties into full design modes — density, contrast, fidelity, entitlement — with no extra CSS architecture.
Mode switches
Every switch sets one attribute on <html>. The whole magazine re-renders, and your choices survive a reload.
One attribute per axis
Each axis overrides only the tokens it owns, so five independent switches need five small rules — not thirty-six combined classes.
:root {
--density: 1;
--fidelity: solid;
}
:root[data-theme="dark"] { color-scheme: dark; }
:root[data-density="compact"] { --density: 0.65; }
:root[data-contrast="high"] { --ink: light-dark(#000, #fff); }
:root[data-fidelity="wireframe"] { --fidelity: dashed; }
:root[data-plan="pro"] { --accent: light-dark(#4c5fd7, #8fa0ff); }
.card {
border: 1px var(--fidelity) var(--border);
padding: calc(1.35rem * var(--density));
}
Themes without a theme file
The theme axis sets color-scheme rather than redefining colours — every
light-dark() token in the page already knows what to do, so an explicit
light/dark switch costs two declarations.
Density and contrast are the accessibility axes people actually ask for. Fidelity turns the page into a wireframe for design review. Plan is a product axis: the same tokens, gated on what the account is entitled to.
Persistence is localStorage plus a small script in <head>
that applies the saved modes before the first paint — no flash of the wrong theme.
No framework required
The browser already ships a capable UI library. Reach for a framework when you need complex state, routing or a design system — not for a modal, an accordion or a colour picker.
Built as a single HTML file · Works offline · Zero dependencies