Sumi.css: Een minimalistisch, 'classless-first' CSS-framework

Het framework bestaat uit één enkel bestand en vereist geen build-stap. De geminificeerde en gegzipped versie is slechts 6,7 KB, bevat geen JavaScript en heeft geen afhankelijkheden.

Belangrijkste kenmerken:

  • Standaard klasseloos: Koppen, formulieren, tabellen, kaarten, accordeons, modals en navigatie worden gestyled op basis van het HTML-element alleen.
  • Lichte en donkere modus: Het volgt automatisch de systeeminstellingen van de bezoeker; via data-theme kan een specifieke modus worden afgedwongen.
  • Eenvoudig thema's aanpassen: Elke kleur, lettertype, grootte en radius is gedefinieerd als een CSS custom property.
  • Eenvoudig te overschrijven: Elementstijlen hebben een specificiteit van nul, waardoor je eigen CSS altijd voorrang krijgt zonder dat !important nodig is.
  • Toegankelijk: Voorzien van zichtbare focus-ringen, ARIA-gestuurde statussen (aria-invalid, aria-busy, aria-current) en ondersteuning voor verminderde beweging (reduced motion).

Installatie

Download

Download sumi.min.css, kopieer dit in je project en link ernaar:

<link rel="stylesheet" href="sumi.min.css">

CDN

Laad het framework direct vanuit de repository via jsDelivr:

<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/vladocar/Sumi.css/sumi.min.css">

Tip: Gebruik sumi.css (niet-geminificeerd) tijdens de ontwikkeling; de commentaren in het bestand leggen elke sectie uit.

Snelstart

<!doctype html>
<html lang="nl">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Mijn pagina</title>
<link rel="stylesheet" href="sumi.min.css">
</head>
<body>
<header>
<nav>
<ul><li><strong>Mijn site</strong></li></ul>
<ul>
<li><a href="/" aria-current="page">Home</a></li>
<li><a href="/about">Over</a></li>
</ul>
</nav>
</header>
<main>
<hgroup>
<h6>Welkom</h6>
<h1>Hallo, inkt.</h1>
</hgroup>
<p class="lead">Deze pagina is gestyled met Sumi, met bijna geen klassen.</p>
<a href="#start" role="button">Aan de slag</a>
</main>
<footer>
<p>© 2026 Mijn site</p>
</footer>
</body>
</html>

De elementen <header>, <main> en <footer> centreren zichzelf wanneer ze directe kinderen zijn van <body>. Behoud de viewport meta-tag voor mobiele apparaten en stel lang correct in, zodat de browser lange woorden correct kan afbreken.

Wat wordt er gestyled?

ElementResultaat
h1–h6, p, lijsten, blockquote, code, kbd, pre, markVloeiende typografische schaal en consistente verticale spatiëring
<nav> met twee <ul>Navigatiebalk met linker- en rechtergroepen. Verticaal binnen een <aside>
<button>, [type=submit], <a role="button">Knoppen
<input>, <select>, <textarea>, <label>, <fieldset>Volledig breedte velden met focus-ringen en helpteksten
type="checkbox", type="radio", type="range", type="file", type="color"Custom controls die passen bij het thema
<table>Strakke lijnen en tabulaire cijfers
<article>Kaart. Een directe <header> en <footer> worden gearceerde banden
<details> / <summary>Accordeon met een geanimeerde chevron
<dialog>Modal met een vervaagde achtergrond
<progress>, <meter>Bepaalde en onbepaalde voortgangsbalken

Klassen en attributen

Naast standaard HTML reageert Sumi op de volgende klassen en attributen:

Layout en Structuur

Class of attribuutToegepast opEffect
.container, .container-fluid, .narrowelk blokGecentreerde paginabreedte (72rem), volledige breedte, leesbreedte (44rem)
.gridwrapperAuto-fitting kolommen, elk minimaal --s-grid-min (14rem) breed
.cols-2, .cols-3, .cols-4, .cols-6, .cols-12.gridVaste kolommen vanaf 48rem breedte, één kolom daaronder
.span-2 … .span-9, .span-fullgrid-childBeslaat meerdere kolommen
.row, .spread, .stackwrapperWrapping flex-rij, rij met ruimte ertussen, verticale stapel

Typografie en Inhoud

Class of attribuutToegepast opEffect
.display, .leadkop, paragraafHero-koptekst, grotere introductieparagraaf
.prose, .seriftekstwrapperKolom voor lange teksten, serif-lettertype

Interactie en Componenten

Class of attribuutToegepast opEffect
.secondary, .contrast, .outlineknopKleuren voor knoppen en outline-stijl
.small, .large, .fullknopGroottes, volledige breedte
role="button"<a>Link gestyled als knop
role="group"wrapperVoegt knoppen samen, of een input en een knop
role="switch"checkboxToggle-switch
aria-invalid="true" / "false"veldRode of groene validatiestatus
aria-busy="true"elk elementLaad-spinner
aria-current="page"nav-linkMarkeert de huidige pagina
data-tooltip="…", data-placement="bottom"elk elementTooltip, boven of onder
data-theme="light" / "dark"<html> of elk elementForceert een kleurmodus
.dropdown, .right<details>Dropdown-menu, rechts uitgelijnd
.callout + .success, .warning, .dangerblokBerichtvenster
.striped<table>Zebra-rijen
.muted, .small, .center, .sr-only, .overflow-autoelk elementUtilities

Voorbeelden

Knoppen

<button>Opslaan</button>
<button class="secondary outline">Annuleren</button>
<button aria-busy="true">Opslaan...</button>

Veld met helptekst en validatie

<label>Email
<input type="email" name="email" aria-invalid="true" aria-describedby="email-help">
<small id="email-help">Voer een geldig e-mailadres in.</small>
</label>

Switch

<label><input type="checkbox" role="switch" checked> E-mail herinneringen</label>

Kaart (Card)

<article>
<header><strong>Cursus van zes weken</strong></header>
<p>Van de eerste penseelstreken tot een voltooide hangende rol.</p>
<footer><a href="#book" role="button" class="full">€180</a></footer>
</article>

Dropdown

<details class="dropdown">
<summary>Exporteren als…</summary>
<ul>
<li><a href="#">PNG</a></li>
<li><a href="#">SVG</a></li>
</ul>
</details>

Modal

Openen met dialog.showModal(); het formulier sluit de modal.

<dialog id="confirm">
<article>
<header><h3>Dit bestand verwijderen?</h3></header>
<p>Deze actie kan niet ongedaan worden gemaakt.</p>
<footer>
<form method="dialog" class="row">
<button class="secondary outline">Behouden</button>
<button class="contrast">Verwijderen</button>
</form>
</footer>
</article>
</dialog>

Lay-out

Automatische kolommen (stapelt op mobiel):

<div class="grid">
<div>Eén</div>
<div>Twee</div>
<div>Drie</div>
</div>

12-koloms lay-out vanaf tabletbreedte:

<div class="grid cols-12">
<div class="span-8">Hoofdinhoud</div>
<div class="span-4">Zijbalk</div>
</div>

Minimale kolombreedte aanpassen voor één specifieke grid:

<div class="grid" style="--s-grid-min: 10rem">…</div>

Kaarten binnen een .grid worden automatisch uitgerekt naar gelijke hoogte en houden hun footers onderaan uitgelijnd.

Typografie

Koppen volgen een vloeiende schaal. De ratio groeit van 1.2 op telefoons naar 1.28 op desktop, en de basisgrootte loopt op van 16px naar 17px. Er zijn geen media queries nodig aan jouw kant. De regelafstand en letterspatiëring worden kleiner naarmate de koppen groter worden.

  • <hgroup> koppelt een kop aan een 'eyebrow' (<h6> ervoor) en een ondertitel (<p> erna).
  • .lead vergroot een introductieparagraaf.
  • .display maakt een hero-koptekst.
  • .prose stelt een leeskolom in van ongeveer 68 tekens met afbrekingen. Een <article class="prose"> blijft platte tekst in plaats van een kaart te worden.
  • .serif schakelt een element, of de gehele <body>, om naar een systeem-serif stack.

Theming

Elke ontwerpbeslissing is een custom property die begint met --s-. Je kunt deze overschrijven in een stylesheet die na Sumi wordt geladen:

:root {
--s-primary: #0f766e;
--s-radius: .25rem;
--s-font-body: "Inter", system-ui, sans-serif;
--s-font-heading: "Fraunces", Georgia, serif;
--s-container: 64rem;
}

Tokens werken ook op een enkel element:

<div class="row" style="--s-primary: #b4235a; --s-radius: 999px">
<button>Nu boeken</button>
<button class="outline">Cadeaubon</button>
</div>

Belangrijkste tokens

TokenControleert
--s-primary, --s-on-primaryKnoppen, links, focus-ringen, geselecteerde controls en de tekst daarop
--s-secondary, --s-contrastKleuren voor secundaire en contrastknoppen
--s-bg, --s-surface, --s-cardPagina, gearceerde gebieden, kaarten
--s-text, --s-mutedBody-tekst, secundaire tekst
--s-border, --s-border-strongLijnen, kaartranden, veldranden
--s-success, --s-warning, --s-dangerValidatie en callouts
--s-font-body, --s-font-heading, --s-font-mono, --s-font-serifLettertypes
--s-font-size, --s-line-height, --s-heading-weightBasisgrootte, regelafstand, gewicht van koppen
--s-text-display, --s-text-h1 … --s-text-h4, --s-text-leadStappen in de typografische schaal
--s-flow, --s-spaceRuimte na tekstblokken, ruimte na formulieren en componenten
--s-container, --s-narrow, --s-measure, --s-gutterPaginabreedte, leesbreedte, regelbreedte, zij-padding
--s-radius, --s-shadow, --s-shadow-lgHoeken en schaduwen (elevatie)

De volledige lijst is bovenaan in sumi.css te vinden.

Donkere modus

Sumi volgt de systeeminstellingen van de bezoeker zonder extra code. Om een modus te forceren, zet je data-theme op <html>:

<html lang="nl" data-theme="dark">

data-theme werkt ook op elk willekeurig element, waardoor één sectie donker kan zijn binnen een lichte pagina.

Voorbeeld van een thema-switch die de keuze van de bezoeker onthoudt:

const root = document.documentElement;
const saved = localStorage.getItem('theme');
if (saved) root.dataset.theme = saved;

document.querySelector('#theme-toggle').addEventListener('click', () => {
const dark = matchMedia('(prefers-color-scheme: dark)').matches;
const current = root.dataset.theme || (dark ? 'dark' : 'light');
const next = current === 'dark' ? 'light' : 'dark';
root.dataset.theme = next;
localStorage.setItem('theme', next);
});

Het donkere palet komt twee keer voor in sumi.css: één keer voor de systeeminstelling en één keer voor data-theme="dark". Als je de donkere kleuren aanpast, wijzig dan beide blokken.

Stijlen overschrijven

Elementstijlen zijn ingepakt in :where(), wat een specificiteit van nul heeft. Een gewone selector is dus voldoende om ze te overschrijven:

/* Sumi: :where(blockquote) { border-left: 3px solid … } */
blockquote { border-left-color: var(--s-warning); }

Je kunt eigen componenten bouwen met de tokens van Sumi, waardoor ze automatisch meegaan in je thema en de donkere modus:

.badge {
padding: .1em .55em;
border: 1px solid var(--s-border);
border-radius: 999px;
background: var(--s-surface);
color: var(--s-muted);
font-size: .8rem;
}

Browserondersteuning

Huidige versies van Chrome, Edge, Firefox en Safari. Sumi maakt gebruik van :where(), :has() en color-mix(), die beschikbaar zijn vanaf Chrome en Edge 111, Firefox 121 en Safari 16.2. Oudere browsers tonen nog steeds leesbare pagina's, maar met simpelere hover- en focuskleuren.

Bestanden

BestandDoel
sumi.cssBronbestand met commentaren, voor ontwikkeling
sumi.min.cssGeminificeerde build, voor productie
docs.htmlOverzicht van alle componenten met HTML, een light/dark switch en een live token-editor
tutorial.htmlStap-voor-stap gids voor het bouwen van een pagina met Sumi

Om het geminificeerde bestand opnieuw te genereren na het bewerken van de bron: npx lightningcss-cli --minify sumi.css -o sumi.min.css

Licentie

MIT © 2026 Vladimir Carrer