Semantic HTML
Style elements, not components. Your markup stays meaningful.
[µ*]A classless, cascade-first CSS layer. Style semantic HTML directly — minimal selectors [µ*], no utility-class soup, a small and reusable footprint. No build. Just minify
Because to get a real micro DOM you need a micro CSS too.
Style elements, not components. Your markup stays meaningful.
Reach for a class only when the cascade genuinely can't.
No endless utility classes cluttering your markup.
One calm, neutral baseline you carry between projects.
11.6 KB minified, 3.1 KB gzip — and it earns every rule it ships.
The design baseline for the content web — typography, layout and components that semantic HTML already deserves.
This very page is built with Mode CSS. The layout, header, navigation, cards, forms and footer you are looking at come straight from the base stylesheet — semantic HTML plus a few µ-attributes. Only the colors and a few decorative touches live in a separate theme file.
The CDN is for prototyping; npm is for shipping.
page.html
<link rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/@microdom/mode.css@1/dist/mode.min.css">
terminal
npm install @microdom/mode.css
app.js
import "@microdom/mode.css"; // flat, readable build
import "@microdom/mode.css/min"; // minified build
page.html
<link rel="stylesheet" href="mode.css"> <!-- base layout + defaults -->
<link rel="stylesheet" href="custom.css"> <!-- your theme -->
Write plain, semantic markup. The cascade does the styling — no class on every element.
page.html
<main>
<section µ-grid="3-col">
<article>
<h3>Readable by default</h3>
<p>Just semantic HTML — no classes.</p>
</article>
<!-- ... More Articles -->
</section>
</main>
Layout that the cascade can't express alone is opted into with an exact set of µ-attributes — no class soup, just intent.
| Attribute | What it does |
|---|---|
µ-grid | Auto-responsive grid (auto-fit, min 280px). |
µ-grid="2-col … 6-col" | Explicit column counts at each breakpoint. |
µ-grid="sidebar-left" | Asymmetric sidebar + content layout. |
µ-grid > article | Becomes a native card automatically. |
µ-pricing µ-grid="3-col blog" | Themed section variant defined in your theme file. |
The base ships a small set of design tokens — typography scale, spacing rhythm, a neutral palette and the master layout widths. Re-skinning the whole site is mostly a matter of overriding them in custom.css.
custom.css
:root {
--color-bg: #0b0d12; /* dark steel */
--color-text: #d8dee8;
--color-accent: #ff7a18; /* molten ember */
--radius: 12px;
--max-width: 1080px;
}
Mode.js + Mode CSS = intent-aligned. Micro DOM behavior, micro visual semantics — one standard, two layers.
Classes are state, not decoration. Static design lives in the cascade — zero classes.
State lives first in native attributes (disabled, aria-*, :checked). A class is the
marker of last resort: a circumstance no native tag can express — a price turning neg,
a row going stale. That's why Mode markup stays clean: every class you do see means
something is happening right now.
live-table.html
<td>$41,203</td> <!-- steady: no class -->
<td class="neg">$40,981</td> <!-- dropped: the one class that means something -->
Semantic, classless HTML ships fewer bytes; fewer bytes render faster and read cleaner. A document expressed in native elements and native state is more accessible to assistive technology, clearer to search engines, and easier for the AI readers of the web to parse — the meaning is in the tags, not in a decoration layer they have to decode.