How I built a context-aware styling engine that eliminates CSS classes entirely
The Problem with Modern CSS
People have been building web interfaces for years, and one grows tired of the same false choice: elegant but static classless frameworks (Pico, Water.css) versus powerful but verbose utility-first systems (Tailwind).
Classless frameworks are beautiful. Drop in a CSS file and your semantic HTML looks great. But they don’t adapt. A blog post and a data dashboard get the same treatment, even though they need radically different spacing, typography, and reading ergonomics.
Utility-first frameworks adapt, but at what cost? Your HTML becomes unreadable:
<div class="flex flex-col md:flex-row justify-between items-center p-4 md:p-6 lg:p-8 bg-white dark:bg-gray-900 rounded-lg shadow-md hover:shadow-lg transition-all duration-200">
That’s not HTML. That’s CSS wearing an HTML costume.
What If Your CSS Could Think?
I built Wisp to solve this. It’s a 5KB engine that analyzes your HTML structure and automatically generates optimized CSS. No classes. No configuration. No build step.
Here’s how it works:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@rotsl/wisp@latest/dist/wisp.min.css">
</head>
<body>
<main>
<h1>My Blog Post</h1>
<p>Some content here...</p>
<p>More paragraphs...</p>
</main>
<script src="https://cdn.jsdelivr.net/npm/@rotsl/wisp@latest/dist/wisp.min.js"></script>
</body>
</html>
Wisp scans the DOM, detects this is narrative content (mostly paragraphs), and injects CSS optimized for reading:
- Line height: 1.7 (comfortable reading)
- Max width: 65ch (optimal line length)
- Font size: 1.125rem (slightly larger for readability)
- Spacing: Generous margins between paragraphs
Change the HTML to a dashboard:
<main>
<article>Metric 1</article>
<article>Metric 2</article>
<article>Metric 3</article>
<article>Metric 4</article>
<table>...</table>
</main>
Wisp detects dashboard context and switches to:
- Compact spacing (0.5rem units)
- Full-width layout
- Smaller font (0.875rem)
- Tighter line height (1.4)
Same HTML structure, entirely different presentation. No classes changed. No configuration files.
The Algorithm
Wisp uses three metrics to classify content:
Density (ρ): Text-to-element ratio
ρ = min((text_length / element_count) / 500, 1.0)
Pattern (π): Element type distribution
- Prose (paragraph-heavy)
- Structured (list-heavy)
- Technical (code-heavy)
- Navigational (heading-heavy)
Depth (δ): Maximum DOM nesting level
These combine into four contexts:
The entire analysis runs in <1ms for typical pages.
Real-World Results
I tested Wisp on Wikipedia’s “Wiki” article. The engine:
- Detected narrative context (prose density: 0.25)
- Generated reading-optimized CSS (1.7 line-height, 65ch width)
- Added accessibility enhancements (skip link for deep nesting)
- Reduced specificity conflicts by 40% vs. Wikipedia’s default stylesheet
The result is live at rotsl.github.io/wisp — an interactive dashboard showing real-time analysis, benchmarks, and framework comparisons.
Architecture
Wisp is implemented in dual languages:
Python core (src/core/scanner.py) powers the CLI for static generation and batch processing:
./wisp-fetch https://en.wikipedia.org/wiki/Wiki --open
JavaScript runtime (src/core/wisp.js, 2KB) handles browser-side enhancement with zero dependencies.
Both use the same algorithm, ensuring consistency between build-time and runtime.
Installation & Usage
npm :
npm install @rotsl/wisp
import Wisp from '@rotsl/wisp';
import '@rotsl/wisp/dist/wisp.min.css';
CDN :
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@rotsl/wisp@latest/dist/wisp.min.css">
<script src="https://cdn.jsdelivr.net/npm/@rotsl/wisp@latest/dist/wisp.min.js"></script>
Python CLI :
git clone https://github.com/rotsl/wisp.git
cd wisp
python3 -m venv venv && source venv/bin/activate
pip install -r requirements.txt
./wisp-fetch https://example.com --open
Framework Integration
React :
import { useEffect } from 'react';
import Wisp from '@rotsl/wisp';
import '@rotsl/wisp/dist/wisp.min.css';
function App() {
useEffect(() => { Wisp.scan(); }, []);
return <main>...</main>;
}
Vue :
<script setup>
import { onMounted } from 'vue';
import Wisp from '@rotsl/wisp';
import '@rotsl/wisp/dist/wisp.min.css';
onMounted(() => Wisp.scan());
</script>
The Philosophy
Wisp embodies progressive enhancement:
- Base CSS works without JavaScript — functional styling for all
- Runtime enhances when available — context detection, accessibility features
- Respects user preferences — prefers-reduced-motion, prefers-color-scheme
- Semantic HTML first — if it’s structured correctly, it looks good
This aligns with the original vision of the web: documents that adapt to their content, not frameworks that demand specific markup patterns.
Benchmarks
*Tailwind requires build step; purged CSS varies
Research & Publications
Wisp is documented in a formal research paper: Wisp: A Context-Aware, Zero-Dependency Semantic Styling Engine for the Modern Web (ResearchGate).
The paper covers the algorithm design, comparative analysis against existing frameworks, and performance benchmarks.
Links & Resources
- GitHub Repository github.com/rotsl/wisp
- npm Package npmjs.com/package/@rotsl/wisp
- Live Dashboard rotsl.github.io/wisp
- GitLab Mirror gitlab.com/rotsl/wisp
- Research Paper ResearchGate
Paste this into a HTML file:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@rotsl/wisp@latest/dist/wisp.min.css">
</head>
<body>
<main>
<h1>Hello, Wisp!</h1>
<p>This paragraph is automatically styled based on content analysis.</p>
<p>Add more paragraphs, a table, or form elements — watch the styling adapt.</p>
</main>
<script src="https://cdn.jsdelivr.net/npm/@rotsl/wisp@latest/dist/wisp.min.js"></script>
</body>
</html>
Open it. Inspect the CSS variables. Change the HTML structure. Watch Wisp respond.
What’s Next
- Browser extension for one-click optimization of any webpage
- Additional contexts (e-commerce, documentation wikis, wizard interfaces)
- React/Vue wrapper components for component-level context detection
- CSS-only fallback mode for zero-JavaScript environments
Acknowledgments
Wisp builds on ideas from Context-Oriented Programming, semantic HTML principles, and the classless CSS movement. It stands on the shoulders of Pico CSS, Tailwind, and the W3C’s HTML5 specification.
The goal isn’t to replace these tools, but to offer a third path: intelligent simplicity.
Built with 💙 by Rohan R.



Top comments (0)