Modern frontend frameworks treat components as JavaScript objects, classes, or functions.
But what if you could build components using only HTML, CSS, and attributes — no JS logic, no virtual DOM, no build step?
That’s exactly what State.js enables.
State.js exposes HTML attributes as reactive CSS variables, letting you build fully reactive UI components using nothing but CSS.
In this article, you’ll learn how to build your first CSS‑reactive component using State.js.
What Is a “Component” in State.js?
In React, a component is a function.
In Vue, it’s an object.
In Svelte, it’s a compiled file.
In State.js, a component is simply:
An HTML element whose behavior is driven by CSS variables and State.js attributes.
No JavaScript logic.
No rendering engine.
No framework runtime.
Just HTML + CSS + State.js.
Example: A <ui-health-bar> Component
Let’s build a reusable health bar component.
HTML
<ui-health-bar
data-state
data-hp="75"
data-max="100">
</ui-health-bar>
State.js automatically exposes:
--state-hp--state-max--state-hp-normalized--state-hp-percent
These variables update reactively whenever the attributes change.
CSS
ui-health-bar {
display: block;
width: 200px;
height: 20px;
background: #333;
border-radius: 4px;
overflow: hidden;
position: relative;
}
ui-health-bar::after {
content: "";
position: absolute;
inset: 0;
width: var(--state-hp-percent);
background: linear-gradient(to right, #4caf50, #8bc34a);
transition: width 0.3s ease;
}
This is the magic:
- CSS reads the reactive variables
- CSS handles the animation
- CSS renders the component
- State.js updates the variables
No JavaScript logic required.
Updating the Component
Add a button that reduces HP:
<button
data-state
data-state-bind="hp"
data-state-decrement="10">
Take Damage
</button>
When clicked:
-
data-hpdecreases - State.js updates
--state-hp - CSS recalculates
--state-hp-percent - The bar animates automatically
This is reactivity without JavaScript logic.
Why This Works
State.js turns HTML attributes into live CSS variables.
CSS handles:
- layout
- animation
- transitions
- interpolation
- gradients
- transforms
State.js handles:
- state changes
- variable updates
- triggers
- binding
- reactivity
Together, they form a CSS‑reactive component system.
Why This Is a Big Deal
This approach gives you:
✔ Zero JavaScript logic
Your component logic lives in CSS.
✔ Zero framework runtime
No virtual DOM.
No hydration.
No re-renders.
✔ Zero build step
Works in plain HTML files.
✔ Fully portable components
A <ui-health-bar> works anywhere HTML works.
✔ Native browser performance
CSS is GPU‑accelerated and instant.
Component API Design (Optional)
You can define your own component API:
<ui-health-bar
data-hp="50"
data-max="200">
</ui-health-bar>
Or add more attributes:
<ui-health-bar
data-hp="50"
data-max="200"
data-color="green"
data-low="red">
</ui-health-bar>
State.js exposes them all as CSS variables.
Conclusion
State.js lets you build components using:
- HTML for structure
- CSS for behavior
- State.js for reactivity
This creates a new category of UI architecture:
CSS‑Reactive Components
Components powered by CSS variables instead of JavaScript logic.
If you want to build lightweight, portable, framework‑free UI — this pattern is a game changer.
Top comments (0)