Chai-CSS-package

☕ chai-css

A lightweight utility-first CSS engine in vanilla JavaScript.

Write chai-* class names on any HTML element — the engine scans the DOM, converts them to inline styles, and removes the classes. No build step, no framework, no dependencies.

<div class="chai-p-4 chai-bg-blue chai-text-white chai-rounded-lg">
  Hello, Chai!
</div>

Installation

npm install chai-css

Or via CDN (no install needed):

<script src="https://unpkg.com/chai-css/dist/chai.umd.js"></script>

Usage

Script tag (browser, zero setup)

<script src="https://unpkg.com/chai-css/dist/chai.umd.js"></script>

<div class="chai-flex chai-gap-4 chai-p-8">
  <div class="chai-bg-blue chai-text-white chai-p-4 chai-rounded-lg">Card</div>
</div>

The engine runs automatically on DOMContentLoaded. No extra code needed.

ES Module

import chai from 'chai-css';

// Run manually (useful after inserting elements dynamically)
chai.run();

// Or run on a specific subtree
chai.run(document.getElementById('my-container'));

// Parse a single class name (returns a style object or null)
chai.parse('chai-px-4');  // → { paddingLeft: '16px', paddingRight: '16px' }

CommonJS (Node / older bundlers)

const chai = require('chai-css');

chai.run();

Supported utilities

Spacing

| Class | CSS output | |——-|———–| | chai-p-{n} | padding: {n*4}px | | chai-px-{n} | padding-left/right: {n*4}px | | chai-py-{n} | padding-top/bottom: {n*4}px | | chai-pt/pr/pb/pl-{n} | individual sides | | chai-m-{n} | margin: {n*4}px (same variants) |

Colors

| Class | CSS output | |——-|———–| | chai-bg-{color} | background-color | | chai-text-{color} | color | | chai-border-{color} | border-color |

Colors: red, blue, green, purple, pink, teal, amber, orange, yellow, gray, slate, white, black — plus shade variants like blue-500, red-100.

Typography

| Class | CSS output | |——-|———–| | chai-text-{xs\|sm\|base\|lg\|xl\|2xl\|3xl\|4xl} | font-size | | chai-font-{thin\|light\|normal\|medium\|semibold\|bold\|extrabold} | font-weight | | chai-font-{sans\|serif\|mono} | font-family | | chai-italic | font-style: italic | | chai-uppercase\|lowercase\|capitalize | text-transform | | chai-underline\|line-through | text-decoration | | chai-text-{left\|center\|right\|justify} | text-align | | chai-leading-{none\|tight\|normal\|relaxed\|loose} | line-height | | chai-tracking-{tight\|normal\|wide\|wider\|widest} | letter-spacing |

Layout

| Class | CSS output | |——-|———–| | chai-flex | display: flex | | chai-grid | display: grid | | chai-block\|inline-block\|hidden | display | | chai-flex-col\|flex-row | flex-direction | | chai-flex-wrap\|flex-nowrap | flex-wrap | | chai-justify-{start\|end\|center\|between\|around} | justify-content | | chai-items-{start\|end\|center\|stretch} | align-items | | chai-gap-{n} | gap: {n*4}px | | chai-grid-cols-{n} | grid-template-columns: repeat(n, ...) |

Sizing

| Class | CSS output | |——-|———–| | chai-w-{n}\|full\|screen\|auto\|fit | width | | chai-h-{n}\|full\|screen\|auto | height | | chai-max-w-{xs\|sm\|md\|lg\|xl\|...\|full} | max-width |

Borders

| Class | CSS output | |——-|———–| | chai-border | border: 1px solid currentColor | | chai-border-{2\|4\|8} | border-width | | chai-border-{solid\|dashed\|dotted} | border-style | | chai-rounded\|rounded-{sm\|md\|lg\|xl\|2xl\|full} | border-radius |

Misc

| Class | CSS output | |——-|———–| | chai-shadow\|shadow-{sm\|md\|lg\|xl\|2xl} | box-shadow | | chai-opacity-{0\|25\|50\|75\|100} | opacity | | chai-absolute\|relative\|fixed\|sticky | position | | chai-top/right/bottom/left-{n} | inset values | | chai-z-{10\|20\|30\|40\|50} | z-index | | chai-overflow-{hidden\|auto\|scroll} | overflow | | chai-cursor-pointer\|default\|... | cursor |


Dynamic usage

If you add elements after page load, call chai.run() to process them:

import chai from 'chai-css';

const card = document.createElement('div');
card.className = 'chai-bg-purple chai-text-white chai-p-6 chai-rounded-xl';
document.body.appendChild(card);

chai.run();  // processes the new card

Or pass a root element to only scan a subtree:

const container = document.getElementById('dynamic-area');
container.innerHTML = `<p class="chai-text-blue chai-font-bold">Hi!</p>`;
chai.run(container);

Adding custom utilities

The parser is a single function — extend it by importing and wrapping:

import { parseClass as baseParser } from 'chai-css/src/index.js';

function myParser(cls) {
  // Your custom utilities
  if (cls === 'chai-glass') {
    return { backdropFilter: 'blur(8px)', background: 'rgba(255,255,255,0.1)' };
  }
  // Fall back to built-in parser
  return baseParser(cls);
}

API

chai.run(root?: Element | Document): void
// Scan root (default: document) for chai-* classes and apply them.

chai.parse(className: string): object | null
// Convert one class name to a style object. Returns null if unrecognised.

chai.applyStyles(el: Element): void
// Process a single element directly.

License

MIT © Harshit