Zuri SASS Documentation
A minimal Sass component library inspired by Material Design 3. This is the complete reference — installation, customization, every component and utility.
Introduction
Zuri SASS is a zero-runtime CSS library authored in Sass. It ships a drop-in compiled stylesheet (dist/style.css) plus the Sass source (zuri/) so you can override variables and inherit the mixin toolkit.
The design language follows Material Design 3: token-driven color (light + dark maps), six elevation levels, a seven-step shape scale, and spec-compliant state layers.
- No JavaScript — pure CSS, works with any framework.
- Small — ~24 KB minified.
- Customizable — every color, radius and font is a Sass variable.
- MIT licensed.
Install
Via npm
npm install zurisass
<link rel="stylesheet" href="node_modules/zurisass/dist/style.css" />
Via Sass source
Use this path if you want to override variables before compile time.
// your-styles.scss
$primary-color: #0a7;
$base-border-radius: 8px;
@import "zurisass/zuri/index";
From the repository
git clone https://github.com/Njoxpy/ZuriSASS
cd ZuriSASS
npm install
npm run build:css # → dist/style.css + dist/style.min.css
npm run watch # rebuild on every save
Quick start
Drop class names on your elements.
<!doctype html>
<html>
<head><link rel="stylesheet" href="dist/style.css" /></head>
<body>
<button class="btn">Primary action</button>
<div class="text-field text-field--outlined">
<label class="text-field__label" for="email">Email</label>
<input class="text-field__input" id="email" type="email" />
</div>
<div class="elevation-2 shape-md p-4">Raised surface</div>
</body>
</html>
Project structure
zuri/
├── index.scss // entrypoint — imports everything below
├── variables/ // $primary-color, spacing, fonts, etc.
├── base/ // reset + safe-margin
├── theme/ // color maps, typography, elevation, shape, state-layer
├── components/ // btn, card, header, forms, text-field, tables
├── utilities/ // spacing, flex, display, text alignment
└── responsive/ // breakpoints + respond-to mixin
Theming — overview
Zuri exposes three layers of customization, from coarsest to finest:
- Variables — override common tokens like
$primary-color,$base-border-radius,$font-stackbefore importing. - Color maps — override
$light-themesand$dark-themesfor full M3 palette control. - Theme class — put
.light-themeor.dark-themeon a container to switch palettes at runtime.
Variables
Defined in zuri/variables/_variables.scss.
| Variable | Default | Purpose |
|---|---|---|
$primary-color | #6200ea | Brand color for .btn, .fab, focus rings. |
$secondary-color | #2ecc71 | Accent color. |
$error-color | #b00020 | Error states. |
$disabled-color | #BDBDBD | Disabled text & borders. |
$base-border-radius | 4px | Default corner radius. |
$base-padding | 0.75rem | Component padding unit. |
$btn-padding | 10px 20px | Button padding. |
$font-stack | sans-serif | Default font family for typography classes. |
Override any of these before @import "zurisass/zuri/index";.
Color maps
Two Sass maps drive the whole palette: $light-themes and $dark-themes. Each contains the Material 3 color tokens.
$light-themes: (
primary: #6200ea,
on-primary: #ffffff,
primary-container: #bb86fc,
on-primary-container: #3700b3,
secondary: #03dac6,
on-secondary: #000000,
...
surface: #ffffff,
on-surface: #000000,
error: #b00020,
...
);
For each key X, Zuri auto-generates:
.text-X— setscolor..bg-X— setsbackground-color..btn-X— a button variant usingXas the background.
So adding a new color token in the map automatically produces all three classes.
Dark mode
Put .dark-theme (or .light-theme) on any container — typically <body> — and the .bg-* / .text-* utilities automatically resolve against the matching color map.
<body class="dark-theme">
<section class="bg-primary text-on-primary">Hero</section>
</body>
<script>
// Toggle via JS if you need a user preference
document.body.classList.toggle("dark-theme");
</script>
Text fields
BEM structure: .text-field with nested __label, __input, __helper, plus modifier classes.
<div class="text-field text-field--outlined">
<label class="text-field__label" for="email">Email</label>
<input class="text-field__input" id="email" type="email" />
<span class="text-field__helper">We never share your email.</span>
</div>
| Modifier | Effect |
|---|---|
.text-field--outlined | Outlined variant (otherwise filled). |
.text-field--error | Error state — red label, border, helper. |
[disabled] on input | Disabled state. |
Forms
The base <form> element has theme-aware padding and label styling. Combine with .text-field components for full forms.
<form>
<label>Name</label>
<input type="text" />
<button class="btn">Submit</button>
</form>
Cards
<div class="card">
<div class="card-image"><img src="product.jpg" alt="" /></div>
<div class="card-content">
<div class="card-price"><h2>$50</h2><p>4.9</p></div>
<p>Product description…</p>
<div class="card-cta">
<button>Add to cart</button>
</div>
</div>
</div>
Tables
Add .table-content to any <table> for striped rows, header styling, and consistent spacing.
<table class="table-content">
<thead><tr><td>Name</td><td>Role</td></tr></thead>
<tbody>
<tr><td>Jane</td><td>Designer</td></tr>
</tbody>
</table>
Header & navigation
<header class="header">
<h2><a href="/" class="logo">Brand</a></h2>
<nav>
<ul>
<li><a href="#" class="nav-item">Home</a></li>
<li><a href="#" class="nav-item">About</a></li>
</ul>
</nav>
</header>
<!-- Fixed variant -->
<header class="header-fixed">...</header>
Typography
Material 3 type scale as classes. Apply to any element.
| Class | Size | Weight |
|---|---|---|
.headline-1 | 96px | light |
.headline-2 | 60px | lighter |
.headline-3 | 48px | normal |
.headline-4 | 34px | normal |
.headline-5 | 24px | normal |
.headline-6 | 20px | medium |
.subtitle-1 / .subtitle-2 | 16 / 14px | normal |
.body-1 / .body-2 | 16 / 14px | normal |
.caption | 18px | normal |
.overline | 10px | normal |
Elevation
Six Material 3 shadow levels. Use the class, or the mixin inside your own components.
<div class="elevation-3">Raised surface</div>
.my-card {
@include elevation(2);
}
Available levels: elevation-0 (none) through elevation-5 (highest).
Shape
Seven-step corner radius scale.
| Class | Radius |
|---|---|
.shape-none | 0 |
.shape-xs | 4px |
.shape-sm | 8px |
.shape-md | 12px |
.shape-lg | 16px |
.shape-xl | 28px |
.shape-full | 9999px (pill) |
.chip { @include shape(full); }
State layers
Material 3 applies translucent overlays at the spec opacities for hover, focus-visible and pressed states. Use the state-layer mixin on any interactive surface.
.my-button {
background: $primary-color;
color: white;
@include state-layer(#fff); // overlay color
}
Opacities: hover 8%, focus 12%, pressed 12%.
Spacing utilities
Spacing scale: 0, 1, 2, 3, 4, 5, 6, 8, 10 (where n = n × 0.25rem up to 4, then jumps).
| Prefix | Property |
|---|---|
p-* | padding (all sides) |
pt-* / pr-* / pb-* / pl-* | padding one side |
px-* / py-* | padding horizontal / vertical |
m-*, mt-* … | margin (same pattern) |
.mx-auto | horizontal centering |
gap-* | flex/grid gap |
Layout utilities
| Class | Effect |
|---|---|
.d-flex / .d-grid / .d-block / .d-none / .d-inline-flex | display values |
.flex-row / .flex-col | flex-direction |
.flex-wrap / .flex-nowrap | flex-wrap |
.flex-1 / .flex-auto | flex shorthand |
.justify-start / -center / -between / -around / -end | justify-content |
.items-start / -center / -stretch / -end | align-items |
.text-left / -center / -right | text-align |
.w-full / .w-auto / .h-full | width / height |
.visible / .invisible | visibility |
Color utilities
Generated from the theme color maps. For every key X:
.text-X— e.g..text-primary,.text-on-surface..bg-X— e.g..bg-secondary,.bg-error-container.
Breakpoints
| Name | Min width |
|---|---|
mobile | 480px |
tablet | 768px |
desktop | 1200px |
wide | 1440px |
Also available: .container class with responsive max-width.
Responsive mixins
.hero {
font-size: 1.5rem;
@include respond-to(tablet) { font-size: 2rem; }
@include respond-to(desktop) { font-size: 3rem; }
}
.mobile-menu {
@include respond-below(tablet) { display: block; }
}
respond-to($name)—min-widthquery.respond-below($name)—max-widthquery (exclusive).
Contributing
- Fork the repo.
- Create a branch:
git checkout -b feature/my-component. - Make changes in
zuri/. Runnpm run watchto rebuild on save. - Add a demo to
preview/components.html. - Open a pull request.
.block__element--modifier). Drive variant classes from the theme color map via @each, not hardcoded colors.
Roadmap
- Migrate
@import→@use/@forward(Sass 2.0 compatibility). - Components: checkbox, radio, switch, chip, dialog, snackbar, dropdown, progress, slider.
- Twelve-column grid system.
- Icon-button variant.
- CSS custom-properties build for zero-recompile theming.
Troubleshooting
"gulp: command not found"
Run npm install first. Use npm run build:css instead of calling gulp directly.
Sass deprecation warnings about @import
Expected — migration to @use/@forward is on the roadmap. The @import syntax still works in Sass 1.x.
Custom variables not applying
They must be declared before the library import:
// ✅ correct
$primary-color: #0a7;
@import "zurisass/zuri/index";
// ❌ wrong — library values are already locked in
@import "zurisass/zuri/index";
$primary-color: #0a7;
Changelog
v1.0.0
- Initial public release.
- Components: button, FAB, card, header, fixed-header, form, text-field (filled + outlined + error), table.
- Material 3 systems: elevation, shape, state layers.
- Utilities: spacing, flex, display, text alignment.
- Responsive:
respond-to/respond-belowmixins. - Light + dark theme maps with auto-generated color utilities.
- npm-publishable package —
dist/style.css,dist/style.min.css, full Sass source.