CSS, written where your markup lives

Style with a single attribute.

NibCSS turns nib="p=16px; hover:bgc=#4F52D9" into a real, deterministic stylesheet — in HTML, React, Vue, Angular, Svelte and every server framework.

Start building
Read the documentation →
01 · The attribute

One attribute on the element.

<button nib="p=12px 20px; bdrd=12px; bgc=#4F52D9">
02 · The stylesheet

Becomes real, deduplicated CSS.

.nib-10zgc5x { padding: 12px 20px } .nib-1ysywln { border-radius: 12px } .nib-1lr8rj1 { background-color: #4F52D9 }
03 · Step inside

Now watch it style a real element.

Inside the browser

One rule at a time. Real CSS every time.

localhost:5173 — Card.tsx
export function Card() {
return (
<article nib="
">
…
</article>
);
}
Launch week
Styled by 0 nib rules

Every rule you add on the left becomes a class and a line of CSS below.

/* add a rule → */
How it works

From attribute to stylesheet in five steps.

The same engine runs in your bundler, in a CLI and in the browser — so the output is identical everywhere.

01

Parse

Split the attribute on ; into rules.

p=16px · hover:bgc=#4F52D9
02

Resolve

Expand recipes, fill $tokens, map shorthands.

bgc → background-color
03

Hash

Name every rule deterministically.

p=16px → .nib-jbmcpl
04

Emit

Write each distinct rule exactly once.

.nib-jbmcpl { padding: 16px }
05

Apply

At build time — or live in the browser.

class="nib-jbmcpl …"
Why NibCSS

Everything CSS can do. Nothing to invent.

⚡

Zero runtime, if you want it

The build plugin extracts static attributes into a real .css file — or rewrites them straight into class names.

◎

Deterministic output

p=16px is .nib-jbmcpl in every file, build and machine. SSR hydrates cleanly and caches stay warm.

✦

Any CSS value

clamp(), gradients, var(), container units — if CSS accepts it, so does nib. No scale to memorise.

◐

States, breakpoints, dark mode

md:dark:hover:bgc=#111 — modifiers chain in any order and compile to real selectors and media queries.

⬡

Tokens and recipes

Name colours and spacing once, compose buttons and cards from recipes, override per element.

✓

Errors that help

“Unknown utility trf — did you mean tf?” with the file, the line and values that would have worked.

Works everywhere

One syntax. Every framework.

The same attribute works in plain HTML, React, Next.js, Vue, Nuxt, Angular, Svelte, Astro — and in Rails, Django or Laravel templates through the CLI. Learn it once, take it anywhere.

ReactNext.jsVueNuxtAngularSvelteAstroSolidQwikRemixRailsDjangoLaravelHTML
React<div nib="p=16px" />
Vue<p v-nib="'mt=8px'">
Angular<b [nib]="'cl=red'">
Svelte<a use:nib={'…'}>
Next.jswithNib(config)
HTML<script src="…@1">
bgc→background-colorp→paddingd→displayjsc→justify-contentali→align-itemsgtc→grid-template-columnsbdrd→border-radiusbxsh→box-shadowfts→font-sizeftw→font-weightbgc→background-colorp→paddingd→displayjsc→justify-contentali→align-itemsgtc→grid-template-columnsbdrd→border-radiusbxsh→box-shadowfts→font-sizeftw→font-weight
tf→transformts→transitionopc→opacitymxw→max-widthpos→positionins→insetbdf→backdrop-filterasp→aspect-ratiolts→letter-spacingovf→overflowtf→transformts→transitionopc→opacitymxw→max-widthpos→positionins→insetbdf→backdrop-filterasp→aspect-ratiolts→letter-spacingovf→overflow

293 shorthands — and any real CSS property as it is.

Try it — right here

Type an attribute. Watch it render.

This is the real NibCSS engine running in your browser. Break it on purpose — the diagnostics tell you exactly what went wrong.

Every rule is valid.
Hello, NibCSS
Hover me — then edit the attribute.
.nib-12c2hzo { padding: 28px }
.nib-j8kuhi { border-radius: 24px }
.nib-9gc5ax { background-color: rgba(255,255,255,.08) }
.nib-15eqg9u { border: 1px solid rgba(255,255,255,.18) }
.nib-bbb42x { backdrop-filter: blur(12px) }
.nib-11tlxeg { color: #fff }
.nib-12ce1g9 { box-shadow: 0 30px 60px rgba(0,0,0,.35) }
0
built-in shorthands
0
packages, one engine
0
languages for diagnostics
0 kB
JavaScript with rewrite: true

Write less. Style more.

Add one script tag or one plugin, and every element in your app can be styled right where it lives.