Skip to content

Concepts

The ideas keel is built on. Everything else in these docs assumes them; nothing else re-explains them.

Five layers, one job each

keel is one stylesheet organized as five native cascade layers, declared once at the top of the file:

@layer tokens, base, layout, components, utilities;

Each layer has exactly one job. tokens is the only place visual decisions live. base styles semantic HTML so classless content already looks designed. layout arranges — full-bleed bands, containers, structural classes, never positional. components are thin classes that consume tokens. utilities is a small, token-bound escape hatch, deliberately last.

Because every keel rule is layered and your CSS is not, your CSS always wins. Unlayered styles beat layered ones regardless of specificity — no !important, no selector arms races, structurally. Overriding keel is just writing CSS.

Design-system-first

Most frameworks give you their look and a way to override it. keel inverts that: the tokens layer is the product, and the defaults you see are just its starting values. Seed a system from your brand on the design system page — a color, a mood, a font pairing — and every token derives from the seed by math: neutrals, surfaces, status colors, spacing density, corner radius.

The same seed → derive principle runs inside the stylesheet. Shades are relationships, not swatches: strong, light, soft, and the transparencies are all color-mix() expressions over the seed, so re-theming is often two lines:

@layer tokens {
  :root { --k-accent: hsl(160 84% 32%); }
}

Override --k-accent alone and every derived variant follows. Only --k-on-accent stays explicit — contrast is a judgment the math can't make safely. The full map is on the tokens page.

Fluid by default

Type and section spacing are clamp() expressions that breathe with the viewport — every text step and the larger space steps interpolate smoothly between a phone floor and a desktop ceiling, with no breakpoint declarations at all.

Where layout genuinely has to snap — columns collapsing, a sidebar stacking — keel uses three fixed, documented breakpoints: sm 640px, md 820px, lg 1080px. They are not tokens because they cannot be: media queries can't read custom properties, so pretending otherwise would be a lie in the API. Three honest constants instead.

Zero JavaScript

keel ships no scripts, because the platform already ships the behavior: <dialog> for modals and drawers, popover for overlays, <details> for accordions and dropdowns. keel styles these natives; it does not reinvent them.

When you need more, climb the ladder one rung at a time:

  • Semantic HTML first. Links, forms, details, dialog, popover — most interactivity is already in the parser.
  • Then CSS. States, tooltips, the scroll-snap gallery, scroll-driven reveals — presentation logic stays in the stylesheet.
  • Then a few lines of your own JS. Tab panels, a live filter — small, owned by you, styled by keel.
  • Then a framework, if the app earns it. keel still styles the output; the framework handles the runtime.

The design-system tool and the search on this site are site JavaScript, not framework JavaScript.

The grammar

Everything in keel is written in one grammar, and anything you add should be too. Names are BEM with a prefix: k-block__element--modifier. Values are tokens, never raw numbers — if a value matters, it has a name in the tokens layer. And every component reads local knobs with token defaults, so a custom variant is plain CSS:

.btn-sale {
  --k-btn-bg: var(--k-warn);
  --k-btn-bg-hover: color-mix(in oklab, var(--k-warn), black 15%);
}

That is keel's mixin system — native custom properties, no build step, no plugin API. The components page ends with a worked recipe for building a new component in the same grammar.

Semantics & SEO

Stylesheets are invisible to search engines — but a CSS framework decides what HTML people write, and that is SEO. keel's base layer only rewards real elements: an <h1>, a <p>, a <table>, a <details> look designed with zero classes, so semantic markup is the path of least resistance instead of an afterthought. Semantic HTML is keel's API.

The performance half is structural too: one small file, no JavaScript runtime, no hydration shift, lazy self-hosted fonts with font-display: swap — the things Core Web Vitals measure. And clean, semantic, static HTML is what generative engines read best, so the same choices serve GEO.

What a stylesheet honestly cannot do: meta and OG tags, sitemaps, structured data, content. keel owns semantics and performance; the rest of the SEO machinery belongs to the tool that builds the pages.

How keel compares

keel is plain to use — one file, no build — but modern underneath. It leans on native platform features (@layer, color-mix(), :has(), the popover API, scroll-driven animation, field-sizing) that the established frameworks were built before. "Plain" describes how you ship it, not how old the CSS is.

  keel Tailwind Bootstrap Bulma
Build step to useNoneRequiredOptional (Sass)Optional (Sass)
Framework JavaScriptNoneNoneShips JSNone
ThemingNative tokens, liveConfig + rebuildSass rebuildSass rebuild
Styles semantic HTMLYes — the base layerNoPartlyPartly
Contrast enforced in codeYes — WCAG AANoNoNo
Design-system generatorYesNoNoNo
Made for AI toolsMCP + llms.txtNoNoNo

The honest trade: keel's floor is evergreen browsers from 2022 (it needs @layer, with no legacy fallback). Bootstrap reaches further back. keel's bet is the opposite of legacy support — use the platform as it is now.

And where each one wins, plainly: Tailwind for a utility-first workflow and a huge ecosystem; Bootstrap for broad legacy support and batteries-included JS components; keel for a real design system, accessible by default, with no toolchain — usable by a person or an AI.

Honest limits

  • Not 1.0 yet. Class names and tokens may still tighten before 1.0; changes land in the changelog, not as surprises.
  • Browser floor: @layer. Every major browser since 2022. The layer model is the architecture, not an enhancement.
  • No tab-panel runtime. .k-tabs is the visual bar; switching panels is separate pages, a details accordion, or three lines of your JS.
  • Refused on purpose: arbitrary utility values, responsive prefix systems, a JavaScript runtime, vendored icons-as-requests, and theming by override. Each one would trade the design system for convenience.