SnapCSS — A Runtime CSS Engine
SnapCSS — A Runtime CSS Engine
A utility-first CSS engine that works entirely at runtime.
No build step. No compilation. No tooling required.
Why I Built SnapCSS
Modern frontend styling systems are powerful, but they often depend on an entire build pipeline before you can write a single class.
For quick prototypes, experiments, browser-based projects, or lightweight applications, that setup can feel unnecessarily heavy.
I wanted something simpler:
Write utility classes directly in HTML
Load one script
Start styling instantly
No compilation step required
That idea became SnapCSS.
What Is SnapCSS?
SnapCSS is a runtime CSS engine.
Instead of generating stylesheets ahead of time, SnapCSS scans your DOM at runtime, resolves utility class names into style objects, and applies those styles directly in the browser.
Depending on the feature, styles are applied using:
Inline styles
Dynamically injected CSS rules
The result is a lightweight utility-first styling system that works entirely in the browser.
Usage
CDN — Zero Tooling
<script src="https://unpkg.com/@visshnnu-tejaa/snapcss/dist/snapcss.min.js"></script>
<div class="p-8 bg-cyan-500 text-white rounded-xl shadow-lg hover:bg-violet-500">
Works instantly. No build step.
</div>
npm — Framework Support
npm install @visshnnu-tejaa/snapcss
import { init, setDarkMode } from '@visshnnu-tejaa/snapcss';
init();
Feature Walkthrough
1. Utility Classes
SnapCSS supports a wide range of utility classes including:
Spacing
Layout
Typography
Colors
Flexbox
Grid
Borders
Shadows
Opacity
Overflow
Transforms
Transitions
Positioning
Z-index
<div class="flex items-center gap-4 p-6 bg-white rounded-2xl shadow-md">
<span class="text-lg font-bold text-gray-800">
SnapCSS
</span>
</div>
2. Responsive Breakpoints
SnapCSS uses a ResizeObserver to monitor viewport changes in real time.
When a breakpoint threshold is crossed, matching responsive utilities are automatically applied or removed.
Supported Breakpoints
| Prefix | Width |
|---|---|
sm: |
640px |
md: |
768px |
lg: |
1024px |
xl: |
1280px |
2xl: |
1536px |
<div class="p-4 sm:p-6 md:p-8 lg:p-12 bg-white md:bg-blue-500 lg:bg-green-500">
Responsive padding and color
</div>
3. Dark Mode
SnapCSS injects CSS rules for every unique dark: utility into a shared <style> tag.
Dark mode can then be toggled globally using:
import { setDarkMode } from '@visshnnu-tejaa/snapcss';
setDarkMode(true); // Enable dark mode
setDarkMode(false); // Disable dark mode
setDarkMode(null); // Follow OS preference
<div class="bg-white dark:bg-gray-900 text-black dark:text-white p-6">
Adapts to dark mode
</div>
4. State Variants
Interactive state modifiers are powered using native DOM event listeners.
Supported variants include:
hover:focus:focus-visible:active:
SnapCSS dynamically applies and removes styles based on user interaction.
<button class="bg-blue-500 hover:bg-blue-700 active:scale-95 text-white px-4 py-2 rounded-lg">
Click me
</button>
5. Group Hover
SnapCSS supports parent-triggered child styling using:
groupgroup-hover:
<div class="group p-4 bg-gray-100 rounded-xl">
<p class="text-gray-500 group-hover:text-violet-600 transition-colors">
I change when the parent is hovered
</p>
</div>
6. Structural Modifiers
Style elements based on DOM position using:
first:last:odd:even:
<ul>
<li class="p-2 first:font-bold last:text-gray-400 odd:bg-gray-50">
Item
</li>
<li class="p-2 first:font-bold last:text-gray-400 odd:bg-gray-50">
Item
</li>
<li class="p-2 first:font-bold last:text-gray-400 odd:bg-gray-50">
Item
</li>
</ul>
7. Space Utilities
Utilities like space-x-* and space-y-* automatically apply spacing between sibling elements.
<div class="flex space-x-4">
<div class="w-10 h-10 bg-red-400 rounded"></div>
<div class="w-10 h-10 bg-green-400 rounded"></div>
<div class="w-10 h-10 bg-blue-400 rounded"></div>
</div>
8. Dynamic DOM Support
SnapCSS automatically watches for new DOM nodes using a MutationObserver.
This allows dynamically rendered UI components to work immediately without rescanning or re-initialization.
function Card({ title }) {
return (
<div class="p-6 bg-white rounded-xl shadow-md hover:shadow-lg transition-shadow">
{title}
</div>
);
}
9. Custom Themes
SnapCSS supports theme extension during initialization.
import { init } from '@visshnnu-tejaa/snapcss';
init({
theme: {
colors: {
brand: {
500: '#7C6CF2',
600: '#6B5CE7',
},
},
},
});
You can then use custom utilities anywhere:
<div class="bg-brand-500 text-white">
Custom themed color
</div>
How SnapCSS Works Internally
The engine is divided into focused modules:
| Module | Responsibility |
|---|---|
parser |
Parses utility class names |
resolver |
Resolves utilities into style objects |
applier |
Applies styles to DOM elements |
scanner |
Performs the initial DOM scan |
observer |
Watches for dynamically added elements |
darkmode |
Handles dark mode rule injection |
responsive |
Handles responsive breakpoints |
states |
Manages interaction states |
group |
Implements group-hover behavior |
structural |
Handles first/last/odd/even logic |
cache |
Memoizes resolved utilities |
The Parsing System
One of the most interesting parts of SnapCSS is the parser.
A class like:
sm:hover:bg-violet-500
is tokenized left-to-right.
The engine extracts modifier chains:
sm→ responsive modifierhover→ interaction modifier
The remaining tokens:
bg violet 500
are resolved into a final style object:
{
backgroundColor: '#8b5cf6'
}
Architecture Decisions
Why Inline Styles?
Inline styles apply immediately and avoid stylesheet generation overhead.
They also simplify runtime style application because styles can be written directly to the target element.
Why Inject CSS for Dark Mode?
Dark mode requires global toggling behavior.
Injecting CSS rules once and toggling a single html.dark class is significantly more efficient than recalculating every dark-mode element individually.
Why Use ResizeObserver?
Responsive utilities in SnapCSS are controlled through JavaScript.
A ResizeObserver provides real-time viewport updates that the runtime engine can react to instantly.
Why Use MutationObserver?
Modern applications frequently create and destroy DOM nodes dynamically.
The observer ensures new elements are styled automatically without requiring manual rescans.
Try SnapCSS
Install via npm
npm install @visshnnu-tejaa/snapcss
CDN
<script src="https://unpkg.com/@visshnnu-tejaa/snapcss/dist/snapcss.min.js"></script>
Links
GitHub: LINK
Docs: snapcss.in
Final Notes
SnapCSS is actively maintained and continuously evolving.
Built with:
TypeScript
tsup
Published on:
- npm
Licensed under MIT.