Module Documentation
SantyCSS ships as 5 independent CSS modules. Use the full bundle, or load only what you need for optimal performance.
Installation
Install once, use everywhere. Zero dependencies, no build step required.
npm install santycss
📦
Package size
284 KB
compressed tarball
🗂️
Files included
15 files
CSS + JS tooling
⚡
Dependencies
Zero
no runtime deps
Package Structure
Everything ships inside the dist/ folder with the JS tooling at the root level.
santycss/ ├── dist/ │ ├── santy.css ← Full bundle (723KB) — all utilities + components + animations │ ├── santy.min.css ← Minified full bundle (615KB) │ ├── santy-core.css ← Utilities only (598KB) │ ├── santy-components.css ← Components only (52KB) │ ├── santy-animations.css ← 120+ animations (60KB) │ └── santy-email.css ← Email template CSS (13KB) ├── postcss/ │ └── index.js ← PostCSS plugin (tree-shaking) ├── lib/ │ ├── purge-core.js ← Purge API (tree-shaking engine) │ └── animations.js ← Animation definitions ├── index.js ← Main entry — CSS path helpers + purge API ├── santy-jit.js ← JIT runtime (generates classes on-the-fly) ├── vite-plugin-santycss.js ← Vite plugin └── purge.js ← CLI purge tool
| Export | Resolves to | Use when |
|---|---|---|
| santycss/css | dist/santy.css | You want everything in one file |
| santycss/min | dist/santy.min.css | Production, CDN, smallest file size |
| santycss/css/core | dist/santy-core.css | Only utilities, no components |
| santycss/css/components | dist/santy-components.css | Only UI components (.btn, .card…) |
| santycss/css/animations | dist/santy-animations.css | Only animation classes |
| santycss/css/email | dist/santy-email.css | HTML email templates |
| santycss/postcss | postcss/index.js | PostCSS tree-shaking plugin |
| santycss/vite | vite-plugin-santycss.js | Vite plugin |
Import Options
4 ways to use SantyCSS depending on your setup.
Option A
JS import (React / Vue / Vite)
// Full bundle import 'santycss/css'; // Modular — load only what you need import 'santycss/css/core'; import 'santycss/css/components'; import 'santycss/css/animations'; import 'santycss/css/email';
Option B
CSS / SCSS @import
/* In your main.css */ @import 'santycss/dist/santy.css'; /* Or individual modules */ @import 'santycss/dist/santy-core.css'; @import 'santycss/dist/santy-components.css'; @import 'santycss/dist/santy-email.css';
Option C
Next.js layout.js
// app/layout.js or pages/_app.js import 'santycss/css'; export default function RootLayout({ children }) { return ( <html> <body>{children}</body> </html> ); }
Option D
Path resolver (webpack / rollup)
// Get absolute paths for config files const santy = require('santycss'); santy.css // → /path/to/dist/santy.css santy.min // → /path/to/dist/santy.min.css santy.core // → /path/to/dist/santy-core.css santy.components // → /path/to/dist/santy-components.css santy.animations // → /path/to/dist/santy-animations.css santy.email // → /path/to/dist/santy-email.css
CDN Links
Once published on npm, jsDelivr and unpkg serve the files instantly — no setup needed.
<!-- Full minified bundle — recommended for production --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/santycss/dist/santy.min.css"> <!-- Version-pinned (best practice for production) --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/santycss@1.3.1/dist/santy.min.css"> <!-- Utilities only --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/santycss/dist/santy-core.css"> <!-- Components --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/santycss/dist/santy-components.css"> <!-- Animations --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/santycss/dist/santy-animations.css"> <!-- Email module --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/santycss/dist/santy-email.css"> <!-- unpkg alternative --> <link rel="stylesheet" href="https://unpkg.com/santycss/dist/santy.css">
What's included
✓
All 10,000+ utility classes (spacing, color, layout, typography…)
✓
20 color families × 10 shades each
✓
Responsive prefixes:
sm: md: lg: xl:✓
State variants:
on-hover: on-focus: dark:✓
15+ UI components: btn, card, modal, drawer, table…
✓
70+ animations with entrance/exit variants
✓
CSS design tokens (
--santy-primary etc.)✓
Dark mode, RTL, print, motion-reduce variants
<!-- HTML --> <link rel="stylesheet" href="santy.css"> <!-- or --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/santycss/dist/santy.min.css"> // JS import 'santycss/css';
Utility categories
| Category | Example classes | Count |
|---|---|---|
| Spacing | add-padding-{n}, add-margin-{n}, gap-{n}, space-x-{n} | ~2400 classes |
| Colors | color-blue-500, background-green-100, border-color-red-600 | ~1200 classes |
| Typography | set-text-{n}, text-bold, text-center, font-sans, line-height-relaxed | ~400 classes |
| Layout | make-flex, make-grid, grid-cols-{1-12}, flex-row, align-center | ~300 classes |
| Sizing | set-width-{n}, set-height-{n}, max-width-{n}, aspect-ratio-16-9 | ~800 classes |
| Position | position-relative, pin-top-0, z-10, z-50, inset-0 | ~200 classes |
| Overflow | overflow-hidden, overflow-x-auto, overflow-y-scroll | 12 classes |
| Borders | add-border-{n}, round-corners-{n}, make-circle, make-pill | ~300 classes |
| Effects | add-shadow-md, opacity-50, blur-md, backdrop-blur-lg, ring-2 | ~200 classes |
| Transforms | rotate-45, scale-110, flip-horizontal, skew-x-6 | ~80 classes |
| Gradients | gradient-to-right, from-blue-500, to-purple-600 | ~100 classes |
| Transitions | transition-fast, transition-colors, transition-transform | ~30 classes |
| State variants | on-hover:*, on-focus:*, dark:*, group-hover:*, peer-checked:* | ~3000 classes |
| Responsive | sm:*, md:*, lg:*, xl:*, on-mobile:*, on-tablet:* | ~3000 classes |
| Accessibility | sr-only, not-sr-only, outline-none, pointer-events-none | ~30 classes |
import 'santycss/css/core'; <!-- Example: build your own card using utilities --> <div class="background-white round-corners-16 add-padding-24 add-shadow-md on-hover:add-shadow-lg on-hover:scale-102 transition-normal"> <h3 class="set-text-18 text-semibold color-gray-900 add-margin-bottom-8">Title</h3> <p class="set-text-14 color-gray-500 line-height-relaxed">Body text.</p> </div>
All components
| Component | Key classes |
|---|---|
| .btn | .btn-primary .btn-success .btn-danger .btn-sm .btn-lg .btn-outline .btn-ghost |
| .card | .card-header .card-body .card-footer |
| .modal | .modal-overlay .modal-box .modal-header .modal-body .modal-footer .modal-close |
| .drawer | .drawer-overlay .drawer-panel .drawer-header .drawer-body |
| .navbar | .navbar-brand .navbar-menu .navbar-item .navbar-dark .navbar-glass |
| .dropdown | .dropdown-menu .dropdown-item .dropdown-divider .dropdown-header |
| .tabs | .tabs-item .tabs-item.active .tab-panel .tabs-pill |
| .accordion | .accordion-item .accordion-header .accordion-body .accordion-icon |
| Component | Key classes |
|---|---|
| .alert | .alert-info .alert-success .alert-warning .alert-danger |
| .badge / .chip | .badge .chip .chip-blue .chip-green .chip-red |
| .input / .select | .input .select .textarea .input-group .input-addon |
| .table | .table-hover .table-striped .table-responsive |
| .pagination | .page-item .page-link .page-item.active .page-item.disabled |
| .toggle | .toggle .toggle-slider .toggle-green .toggle-purple |
| .progress | .progress .progress-bar |
| .skeleton | .skeleton (animated loading placeholder) |
Dark mode: All components adapt automatically when you add
class="dark" to <html>. Use class="dark-auto" to follow the OS preference.
// Load utilities + components (most common setup) import 'santycss/css/core'; import 'santycss/css/components'; <!-- Button examples --> <button class="btn btn-primary">Save</button> <button class="btn btn-outline btn-sm">Cancel</button> <!-- CSS-only modal (no JS needed) --> <a href="#my-modal" class="btn btn-primary">Open</a> <div id="my-modal" class="modal-overlay"> <div class="modal-box"> <div class="modal-header"> <h4 class="modal-title">Confirm</h4> <a href="#" class="modal-close"></a> </div> <div class="modal-body">Are you sure?</div> </div> </div>
| Group | Classes |
|---|---|
| Looping | animate-spin, animate-ping, animate-pulse, animate-bounce |
| Fade | animate-fade-in, animate-fade-in-from-top/bottom/left/right, animate-fade-out |
| Slide | animate-slide-in-from-top/bottom/left/right, animate-slide-out-to-* |
| Zoom | animate-zoom-in, animate-zoom-in-from-*, animate-zoom-out-* |
| Bounce | animate-bounce-in, animate-bounce-in-from-top/bottom/left/right |
| Flip | animate-flip, animate-flip-in-x/y, animate-flip-out-x/y |
| Rotate | animate-rotate-in, animate-rotate-in-from-top-left/right/bottom-left/right |
| Back | animate-back-in-from-*, animate-back-out-to-* |
| Attention | animate-shake-x/y, animate-rubber-band, animate-tada, animate-wobble |
| Specials | animate-hinge, animate-jack-in-box, animate-roll-in, animate-roll-out |
| Speed | animation-speed-fastest (0.3s) → animation-speed-glacial (3s) |
| Delay | animation-delay-100 → animation-delay-3000 (ms) |
| Repeat | animation-loop-1/2/3/4/5, animation-loop-forever |
| Fill | animation-fill-none/forwards/backwards/both |
| Motion | motion-safe:animate-spin, motion-reduce:animate-none |
import 'santycss/css/animations'; <!-- Fade in on page load --> <div class="animate-fade-in">Appears smoothly</div> <!-- Staggered entrance --> <div class="animate-slide-in-from-left animation-delay-0">Item 1</div> <div class="animate-slide-in-from-left animation-delay-200">Item 2</div> <div class="animate-slide-in-from-left animation-delay-400">Item 3</div> <!-- Reduced motion accessibility --> <div class="motion-safe:animate-bounce motion-reduce:animate-none"> Bounces only if user hasn't requested reduce-motion </div>
✓ Gmail
✓ Outlook 2016+
✓ Apple Mail
✓ Yahoo Mail
✓ Thunderbird
✓ Hey
✓ Mobile responsive
✓ Dark mode
| Category | Key classes | Purpose |
|---|---|---|
| .email-wrapper / container | .email-wrapper, .email-container | Outer 600px max-width wrapper |
| Table layout | .email-table, .email-cell, .email-col-half, .email-col-third | Email-safe column layouts |
| Header / Footer | .email-header, .email-header-light, .email-footer, .email-footer-dark | Branding sections |
| Hero | .email-hero, .email-hero-light, .email-hero-gradient | Bold banner area |
| Body | .email-body-wrap, .email-body-wrap-gray, .email-section | Main content area |
| Typography | .email-h1/h2/h3, .email-p, .email-p-lead, .email-link, .email-muted | Email-safe fonts |
| Buttons | .email-btn, .email-btn-sm/lg/outline/dark/success/danger/warning | CTA buttons |
| Cards & Callouts | .email-card, .email-callout-success/warning/danger | Content blocks |
| Lists | .email-list, .email-check-list | Styled bulleted / checkmark lists |
| Badges | .email-badge-blue/green/red/yellow/purple/gray/new | Status labels |
| Images | .email-img, .email-img-rounded, .email-img-circle, .email-img-full | Responsive images |
| Avatars | .email-avatar-sm/md/lg | Profile pictures |
| Stats | .email-stat-value, .email-stat-label | Large number blocks |
| Code | .email-code, .email-code-inline | Developer emails |
| Spacers | .email-spacer-4 → .email-spacer-64 | Vertical spacing blocks |
| Social | .email-social-wrap, .email-social-link, .email-social-text-link | Social media links |
| Preheader | .email-preheader | Hidden preview text |
| Legal | .email-legal, .email-address, .email-unsubscribe | Footer compliance text |
How to include
Pick any one of these methods depending on your setup:
① CDN / Plain HTML email
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/santycss/dist/santy-email.css">
② npm (React / Vue / Next.js)
import 'santycss/css/email';
③ PostCSS / Sass @import
@import 'santycss/dist/santy-email.css';
④ Node.js path resolver
const santy = require('santycss'); // santy.email → absolute path fs.readFileSync(santy.email, 'utf8');
Component examples
Layout & Structure
<!-- Full outer wrapper → max 600px, centered --> <table class="email-wrapper" role="presentation"><tr><td> <table class="email-container" role="presentation"> <!-- Two-column layout --> <tr> <td class="email-col-half">Left column</td> <td class="email-col-half">Right column</td> </tr> <!-- Three-column layout --> <tr> <td class="email-col-third">Col 1</td> <td class="email-col-third">Col 2</td> <td class="email-col-third">Col 3</td> </tr> </table> </td></tr></table>
Header · Hero · Footer
<!-- Dark header with logo --> <tr><td class="email-header"> <img src="logo.png" class="email-logo" alt="Brand" width="140"> </td></tr> <!-- Light header variant --> <tr><td class="email-header-light"> ... </td></tr> <!-- Gradient hero banner --> <tr><td class="email-hero-gradient"> <h1 class="email-h1" style="color:#fff;">Welcome aboard! 🎉</h1> <p class="email-p-lead" style="color:rgba(255,255,255,.85);">Let's get started.</p> </td></tr> <!-- Footer with legal --> <tr><td class="email-footer"> <p class="email-legal">© 2026 Company Inc · 123 Street, City</p> <a href="{{unsubscribe_url}}" class="email-unsubscribe">Unsubscribe</a> </td></tr>
Typography
<tr><td class="email-body-wrap"> <h1 class="email-h1">Main heading</h1> <h2 class="email-h2">Section heading</h2> <h3 class="email-h3">Sub-heading</h3> <p class="email-p-lead">Large intro paragraph</p> <p class="email-p">Normal body text. <a href="#" class="email-link">Inline link</a></p> <p class="email-muted">Small muted helper text</p> <p class="email-small">Fine print / disclaimer</p> </td></tr>
Buttons (CTAs)
<!-- Primary button (blue) --> <div class="email-btn-center"> <a href="https://example.com" class="email-btn">Get Started</a> </div> <!-- Button variants --> <a href="#" class="email-btn email-btn-sm">Small button</a> <a href="#" class="email-btn email-btn-lg">Large button</a> <a href="#" class="email-btn email-btn-outline">Outline button</a> <a href="#" class="email-btn email-btn-dark">Dark button</a> <a href="#" class="email-btn email-btn-success">Confirm order ✓</a> <a href="#" class="email-btn email-btn-danger">Cancel subscription</a> <a href="#" class="email-btn email-btn-warning">Action required ⚠</a>
Cards & Callouts
<!-- White card with border --> <div class="email-card"> <h3 class="email-h3">Order Summary</h3> <p class="email-p">Item × 2 — $49.00</p> </div> <!-- Coloured callout banners --> <div class="email-callout-success">✓ Payment received — thank you!</div> <div class="email-callout-warning">⚠ Your subscription expires in 3 days.</div> <div class="email-callout-danger">✕ We couldn't process your payment.</div>
Lists
<!-- Bulleted list --> <ul class="email-list"> <li>Unlimited projects</li> <li>Priority support</li> </ul> <!-- Checkmark list (✓ prefix via CSS) --> <ul class="email-check-list"> <li>No credit card required</li> <li>Cancel any time</li> <li>Free 14-day trial</li> </ul>
Badges & Status labels
<span class="email-badge-blue">Info</span> <span class="email-badge-green">Active</span> <span class="email-badge-red">Expired</span> <span class="email-badge-yellow">Pending</span> <span class="email-badge-purple">Pro</span> <span class="email-badge-gray">Draft</span> <span class="email-badge-new">New</span>
Stats & Metrics
<table class="email-table"><tr> <td class="email-cell" style="text-align:center;"> <div class="email-stat-value">1,284</div> <div class="email-stat-label">Page views</div> </td> <td class="email-cell" style="text-align:center;"> <div class="email-stat-value">42%</div> <div class="email-stat-label">Open rate</div> </td> <td class="email-cell" style="text-align:center;"> <div class="email-stat-value">$3.2k</div> <div class="email-stat-label">Revenue</div> </td> </tr></table>
Spacers & Dividers
<!-- Horizontal rule --> <div class="email-divider"></div> <!-- Vertical spacing blocks (px values: 4 8 16 24 32 48 64) --> <div class="email-spacer-8"></div> <div class="email-spacer-24"></div> <div class="email-spacer-48"></div>
Code & Images
<!-- Code block (developer emails) --> <pre class="email-code">npm install santycss</pre> <!-- Inline code --> Use the <code class="email-code-inline">email-btn</code> class for buttons. <!-- Responsive images --> <img src="banner.jpg" class="email-img-full" alt="Banner"> <!-- full-width --> <img src="photo.jpg" class="email-img-rounded" alt="Photo"> <!-- 8px radius --> <img src="avatar.jpg" class="email-avatar-md" alt="Avatar"> <!-- 48px circle -->
Social links & Preheader
<!-- Hidden preview text (shows in inbox before open) --> <div class="email-preheader">Your invoice is ready — view it now</div> <!-- Social media row --> <div class="email-social-wrap"> <a href="https://twitter.com/yourco" class="email-social-link"> <img src="twitter-icon.png" width="24" alt="Twitter"> </a> <a href="https://linkedin.com/company/yourco" class="email-social-text-link">LinkedIn</a> </div>
Complete email template
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/santycss/dist/santy-email.css"> <table class="email-wrapper" role="presentation"> <tr><td> <!-- Preheader --> <div class="email-preheader">Your order has been confirmed ✓</div> <table class="email-container" role="presentation"> <!-- Header --> <tr><td class="email-header"> <img src="logo.png" class="email-logo" alt="Brand"> </td></tr> <!-- Hero --> <tr><td class="email-hero"> <h1 class="email-h1" style="color:#fff;">Order Confirmed! 🎉</h1> <p class="email-p" style="color:rgba(255,255,255,.8);">Order #12345</p> </td></tr> <!-- Body --> <tr><td class="email-body-wrap"> <p class="email-p">Hi Sarah, your order is on its way!</p> <!-- Success callout --> <div class="email-callout-success"> <strong>Estimated delivery: 2–3 business days</strong> </div> <div class="email-spacer-24"></div> <!-- CTA button --> <div class="email-btn-center"> <a href="#" class="email-btn">Track Your Order</a> </div> </td></tr> <!-- Footer --> <tr><td class="email-footer"> <p class="email-legal">© 2026 Brand Inc · 123 Main St</p> <a href="#" class="email-unsubscribe">Unsubscribe</a> </td></tr> </table> </td></tr> </table>
// postcss.config.js const santycss = require('santycss/postcss'); module.exports = { plugins: [ santycss({ content: [ './src/**/*.{html,js,jsx,ts,tsx,vue,svelte}', './pages/**/*.{js,jsx,ts,tsx}', ], safelist: ['animate-spin', 'make-hidden'], // never purge these }), ], };
// vite.config.js import { defineConfig } from 'vite'; import santycss from 'santycss/vite'; export default defineConfig({ plugins: [ santycss({ content: ['./src/**/*.{html,vue,jsx,tsx}'], }), ], });
Purge / Tree-shake API
Use the Node.js API directly for custom build pipelines, CI steps, or scripts.
const { purge, purgeFiles } = require('santycss'); // Purge from a string of HTML/JS const purgedCSS = purge(originalCSS, htmlContent, { safelist: ['animate-spin'], }); // Purge from file globs const purgedCSS = purgeFiles(originalCSS, [ './src/**/*.html', './src/**/*.jsx', ], { safelist: [] });
React / Next.js
// Install npm install santycss // app/layout.tsx (Next.js App Router) import 'santycss/css'; export default function RootLayout({ children }) { return <html><body>{children}</body></html>; } // Usage in any component export default function Card() { return ( <div className="background-white round-corners-16 add-padding-24 add-shadow-md"> <h2 className="set-text-20 text-bold color-gray-900">Hello</h2> <button className="btn btn-primary add-margin-top-16">Click</button> </div> ); }
Vue / Nuxt
// main.js import { createApp } from 'vue'; import 'santycss/css'; import App from './App.vue'; createApp(App).mount('#app'); // nuxt.config.ts export default defineNuxtConfig({ css: ['santycss/dist/santy.css'], }); <!-- MyComponent.vue --> <template> <div class="make-flex align-center gap-16"> <button class="btn btn-primary">Save</button> </div> </template>
Plain HTML
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- Option 1: CDN --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/santycss/dist/santy.min.css"> <!-- Option 2: Local file --> <link rel="stylesheet" href="santy.css"> </head> <body class="background-gray-50"> <div class="container add-padding-y-64"> <h1 class="set-text-40 text-bold color-gray-900">Hello, SantyCSS!</h1> <button class="btn btn-primary add-margin-top-24">Get Started</button> </div> </body> </html>