Version 4.0.7 is out

Write HTML.
It comes out finished.

fertig turns semantic HTML into polished interfaces. Forms, data views, dialogs, and popovers arrive themed and responsive from one 9.3 KB CSS file — no runtime.

Start building See every componentComponents

Terminal npm install fertig
invoice.html Live preview
Edit the HTML to update the preview beside it.
Previewfertig.css

Edit HTMLPreview instantly

9.3 KB
gzipped
0
JavaScript
0
dependencies
0
required classes

01 — Live system

A finished UI, from one file.

Try a category or accent. Every control is real semantic HTML styled by the same file you came here to download.

Sign in

Settings

Switches read as switches to assistive tech.
Controls

  • default paid overdue

    No classes on any of it.

    02 — Native behaviour

    No runtime. Real behaviour.

    fertig uses the browser features you already ship — popover, command, anchor positioning — so menus, dialogs, drawers, and disclosures work without a JavaScript controller. The table records an audit with scripting disabled.

    Popover menuworks — anchored to its button
    Dialogworks — opens and closes through command
    Drawerworks — the same dialog, docked to an edge
    Toastworks — a non-modal popover in the corner
    Tooltipworks — one attribute, pure CSS
    Disclosureworks — native <details>, animated to auto height
    Tabsstyled only — honest selection and keyboard behavior need a controller

    Tabs are the deliberate exception: CSS cannot update aria-selected, manage roving focus or implement arrow-key navigation. The short controller is in the docs.

    03 — Design principles

    Small enough to forget. Finished enough to ship.

    Most are either too plain to ship or too heavy to justify. fertig sits between them: opinionated enough to look finished, small enough that you never think about it again.

    Bidirectional

    Written in logical properties throughout, so dir="rtl" mirrors the whole sheet — Persian and Arabic get the same layout, not a patched one. Verified by rendering a Persian page in both directions.

    Classless

    Semantic tags are styled directly. Seven optional classes and a compact set of layout utilities exist if you want them — you can ignore every one and the page still looks finished.

    Modern only

    OKLCH, light-dark(), cascade layers, anchor positioning, container queries, @property. No vendor prefixes except the three no engine has replaced.

    Accessible

    Every colour pair the sheet uses clears WCAG AA in both themes, at rest and on hover — measured, not assumed. The tightest pairing is text on the amber fill in light mode at 5.41:1.

    Overridable

    The sheet is wrapped in @layer fertig, so your own unlayered CSS wins at any specificity. There is no !important anywhere in it.

    04 — Component layer

    Modern primitives. Still just HTML.

    Compound fields, selectable lists, surfaces, items, and avatars use native elements and ARIA as their API. The result feels like a UI kit without adding a component runtime.

    Compound fields
    https:// .com
    One focus surface, no wrapper library.
    data-input-group · data-otp
    Items & surfaces
    AM
    Ada MorrisProduct design
    online
    LK
    Lin KimEngineering
    data-surface · data-item
    Selectable lists
    • AMAda Morris
    • LKLin Kim
    • SRSam Rivera
    role="listbox" · aria-selected

    Explore the full component catalogue →

    05 — Your system

    Tune the system, not every component.

    Move a few tokens and the live panel follows. Accent contrast is measured as you go, so the result stays usable in both themes.

    Accent · oklch

    Shape and measure

    Preview

    Invoices

    Three overdue, two awaiting approval.

    paid

    A link, in the accent

    06 — Questions

    Does it really need no classes?

    None. Every element in the semantic set is styled by its tag. The seven classes and the layout utilities are there for the cases where HTML has no element for what you mean — a row of buttons, a card — and you can build a whole site without touching them.

    How do I override something?

    Write ordinary CSS. The sheet lives in @layer fertig, so any unlayered rule of yours wins regardless of specificity. Most customisation is a token: set --fertig-ac for the accent, --fertig-w for the toolbar column, --fertig-f for the type.

    What about older browsers?

    They get plain but readable HTML. The sheet runs in any browser released since August 2024 — Chrome 123, Safari 17.5, Firefox 129 — and the only thing it carries for the ones before them is a flat sRGB palette, so a missing light-dark() cannot leave a page unreadable. No polyfills, no fallback build. That policy is the reason it is 9.3 KB rather than 20.

    Can I change the colours?

    Yes. The palette is seven OKLCH ramps of five steps, and the semantic tokens are built from them with light-dark(). Override --fertig-ac alone and the buttons, focus rings, links, selection and caret all follow.

    07 — Install

    One stylesheet. Start shipping.

    Package

    npm install fertig

    CDN

    <link rel="stylesheet"
      href="https://cdn.jsdelivr.net/npm/fertig/fertig.min.css">

    Read the documentation