
Standalone · Lean · Agnostic · Structured · Hybrid · Edgeless · Deterministic
A buildless CSS framework for modern web design. BEM-first authoring, token-driven systems, cascade-layered architecture, zero dependencies. Write one <link> tag. No build step. No npm. No bundler.
Current version: 0.6.30.0 (pre-1.0 — API still evolving).
Essential (tokens + core — frozen source-of-truth surface):
<link rel="stylesheet" href="css/slashed-essential.css">
Full (essential + utilities + components + visual utilities + animations + breakpoint utilities):
<link rel="stylesheet" href="css/slashed-full.css">
CDN (for prototypes):
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/codeslash-dev/slashed@0.6.30.0/css/slashed-full.css">
Then author your markup in BEM:
<!-- Use framework tokens and utilities -->
<div class="sf-container">
<header class="site-header">
<nav class="site-nav">
<a href="/" class="site-nav__logo">Logo</a>
<ul class="site-nav__menu sf-flex sf-gap-m">
<li><a href="/about">About</a></li>
<li><a href="/contact">Contact</a></li>
</ul>
</nav>
</header>
<!-- Your own BEM blocks styled with framework tokens -->
<main class="site-main">
<section class="hero">
<h1 class="hero__title">Welcome</h1>
<p class="hero__subtitle">Build without the build step</p>
<button class="sf-btn--primary">Get started</button>
</section>
</main>
</div>
/* css/your-styles.css — your namespace, your rules */
.site-header {
padding: var(--sf-space-m);
border-bottom: 1px solid var(--sf-color-border);
}
.site-nav {
display: flex;
align-items: center;
justify-content: space-between;
}
.site-nav__logo {
font-weight: 700;
color: var(--sf-primary);
text-decoration: none;
}
.hero {
padding: var(--sf-space-3xl) var(--sf-space-m);
text-align: center;
}
.hero__title {
font-size: var(--sf-text-4xl);
margin-bottom: var(--sf-space-m);
}
.hero__subtitle {
font-size: var(--sf-text-l);
color: var(--sf-color-text-secondary);
margin-bottom: var(--sf-space-l);
}
That’s it. No setup, no configuration, no build step.
Standalone — Zero build step, zero npm, zero bundler. Lean — every class earns its place; visual utilities are optional. Agnostic — works unchanged on WordPress, Bricks, Astro, Next.js, plain HTML. Structured — cascade layers and BEM enforce specificity order. Hybrid — BEM blocks + layout primitives + utilities in explicit hierarchy. Edgeless — unlayered BEM always wins; no !important needed. Deterministic — tokens drive everything; magic numbers are bugs.
Three authoring layers:
.product-card, .site-header).sf-container, .sf-stack, .sf-grid — compose pagessf-flex, sf-gap-*, sf-text-* — one-off tweaks onlySee CLAUDE.md for the complete philosophy and critical gotchas. See docs/BEM.md for naming rules and CONTRIBUTING.md for architecture.
Open these HTML files in your browser to explore and build with SLASHED:
showcase.html — Visual gallery of all framework components in action.archive/cheatsheet.html — Reference all tokens, utilities, and components (to be rebuilt for v2).archive/configurator.html — Token configurator (to be rebuilt for v2).Design tokens · 400+ tokens for color, spacing, typography, shadows, radius, animations, and motion. Use light-dark() to define both light and dark mode in one declaration. Use clamp() for fluid scaling across viewports.
Layout primitives · .sf-container (max-width wrapper), .sf-stack (vertical spacing), .sf-cluster (horizontal spacing with alignment), .sf-grid (auto-layout grid). No flex/grid utility soup — composition does the work.
Typography system · --sf-text-* tokens use clamp() for continuous scaling. Paired with --sf-leading-* line-height tokens. Scale the entire system with --sf-text-scale without touching individual values.
Spacing scale · --sf-space-* tokens scale together with --sf-space-scale. Adjust one variable to globally scale spacing on every element using var(--sf-space-*).
Pre-baked components · .sf-btn--* (buttons), .sf-form-group (inputs with labels/hints/errors), .sf-modal, .sf-dropdown, .sf-tabs, .sf-card, and more. All authored in BEM, all customizable via tokens or instance overrides.
Pure CSS baseline · Core functionality uses native HTML (<dialog>, <details>, :has()) and works without JavaScript. Pre-baked interactive components (nav dropdowns, modals, tabs) in slashed-full.css also work without JavaScript. Reach for js/slashed-ui.js only for enhancements (aria-expanded sync, Escape to close, arrow-key navigation).
Accessibility · Native focus styles, sufficient color contrast, ARIA labels on interactive components, semantic HTML encouragement, print-safe design.
Dark mode · Automatic via light-dark() and prefers-color-scheme (no JS required). For manual control, use [data-theme="light"|"dark"] attribute (requires JavaScript to set).
Responsive · Mobile-first architecture. Fluid tokens via clamp() eliminate many breakpoint rules. Breakpoint utilities (sm:, md:, lg:, xl:) available in full bundle for discrete viewport-level switches (show/hide nav, flip flex direction, etc.).
<!-- For quick prototypes, use the pinned CDN version -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/codeslash-dev/slashed@0.6.30.0/css/slashed-full.css">
<!-- For production until 1.0, always pin to exact version (breaking changes can land in any bump pre-1.0) -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/codeslash-dev/slashed@0.6.30.0/css/slashed-essential.css">
css/ folder to your project<link rel="stylesheet" href="path/to/slashed/css/slashed-essential.css">
Place the slashed/ folder in your child theme’s root directory:
// functions.php
add_action('wp_enqueue_scripts', function() {
wp_enqueue_style('slashed', get_stylesheet_directory_uri() . '/slashed/css/slashed-essential.css');
});
In Bricks admin → Theme Styles → Typography, set HTML font size → 100% (overrides Bricks’ default 62.5%). Then enqueue in your child theme’s functions.php or via WPCodeBox.
// Astro: src/layouts/Layout.astro
import '../css/slashed-essential.css';
// Next.js: app/layout.js
// Option 1: Link tag in head (simpler)
// <link rel="stylesheet" href="/slashed/slashed-essential.css">
// (copy slashed/css/ to public/slashed/ in your build step)
// Option 2: Import as CSS (requires src/ structure)
// import 'src/styles/slashed-essential.css';
// Eleventy: .eleventy.js (copy slashed/css/ to output)
eleventyConfig.addPassthroughCopy({ "slashed/css": "_site/slashed" });
// In layouts: <link rel="stylesheet" href="/slashed/slashed-essential.css">
Override tokens by copying the starter template and loading it AFTER the framework:
cp css/tokens-user.example.css css/tokens-user.css
<link rel="stylesheet" href="css/slashed-essential.css">
<link rel="stylesheet" href="css/tokens-user.css"> <!-- your overrides -->
/* css/tokens-user.css */
:root {
--sf-primary: light-dark(#2563eb, #5b8def); /* brand color */
--sf-neutral: light-dark(#52525b, #a1a1aa); /* neutral palette */
--sf-radius-m: 0.375rem; /* cornerness */
--sf-space-scale: 1.1; /* scale all spacing up 10% */
}
The cascade does the work – tokens declared in tokens-user.css override those in tokens-default.css. See css/tokens-default.css for the full token reference.
Use BEM blocks with framework tokens. Avoid utility soup.
<!-- ❌ Wrong: utility soup obscures design intent and blocks reusability -->
<div class="flex gap-4 p-4 border rounded shadow hover:shadow-lg">
<img src="..." class="w-12 h-12 rounded-full">
<div class="flex-1">
<h4 class="font-bold">John Doe</h4>
<p class="text-sm text-gray-600">Designer</p>
</div>
</div>
<!-- ✅ Right: BEM block with framework tokens — scoped and reusable -->
<div class="user-card">
<img src="..." alt="John Doe" class="user-card__avatar">
<div class="user-card__content">
<h4 class="user-card__name">John Doe</h4>
<p class="user-card__role">Designer</p>
</div>
</div>
/* BEM + tokens: one block, clear intent, easy to reuse */
.user-card {
display: flex;
gap: var(--sf-space-m);
padding: var(--sf-space-m);
border: 1px solid var(--sf-color-border);
border-radius: var(--sf-radius-m);
box-shadow: var(--sf-shadow-s);
transition: box-shadow var(--sf-duration-normal);
}
.user-card:hover {
box-shadow: var(--sf-shadow-l);
}
.user-card__avatar {
width: 3rem;
height: 3rem;
border-radius: 50%;
object-fit: cover;
}
.user-card__name {
margin: 0;
font-size: var(--sf-text-m);
}
.user-card__role {
margin: 0;
font-size: var(--sf-text-s);
color: var(--sf-color-text-secondary);
}
/* ❌ Anti-patterns: avoid these */
/* Magic numbers break the token system */
.card { padding: 16px; /* instead use var(--sf-space-m) */ }
/* Element-in-element nesting breaks reusability */
.block__element__nested { } /* instead use .block__element */
README.md This file
CONTRIBUTING.md Maintainer notes: repo layout, build, versioning
CHANGELOG.md Append-only release history
ROADMAP.md Pending work and stability roadmap
CLAUDE.md Framework philosophy and critical gotchas
PHILOSOPHY.md Frozen project constitution — the seven pillars (immutable)
LICENSE MIT license
showcase.html Visual showcase of all framework components
css/
Canonical source files:
├── tokens-default.css Design tokens (frozen source of truth)
├── slashed-custom-tokens.css Consumer override canvas — all overridable tokens, commented out
├── slashed-core.css Reset + base + layout primitives + a11y + print
├── slashed-utilities.css Layout, functional, typographic utilities
├── slashed-components.css Pre-baked UI components (.sf-* prefixed)
├── slashed-utilities-viewport.css Viewport breakpoint utilities (sm:/md:/lg:/xl:)
├── slashed-utilities-visual.css Decorative utilities (bg, border, radius, shadow)
├── slashed-animations.css Animation and transition helpers
├── slashed-experimental.css Cross-browser features without full support
├── component-tokens.css Instance tokens scoped to component selectors (not :root)
├── tokens-legacy.css Fallbacks for Chrome 111-122, Firefox 113-119, Safari 16.2-17.4
└── tokens-user.example.css Starter template for your token overrides
js/
└── slashed-ui.js Optional: a11y enhancements + CSS polyfills
docs/
├── BEM.md Complete BEM naming rules and authoring methodology
└── VERSION-FREEZE.md Version ceiling policy and unlock conditions
archive/
├── cheatsheet.html Interactive reference (to be rebuilt)
└── configurator.html Token configurator (to be rebuilt)
SLASHED welcomes contributions. See CONTRIBUTING.md for:
New features must:
CHANGELOG.md in the same commitSee docs/BEM.md for the complete BEM naming convention (required reading before authoring new components).
Modern browsers: Chrome 123+, Firefox 120+, Safari 17.5+, Edge 123+.
Graceful fallbacks: Safari 16.2-17.4 (light-dark() resolves to light value; color-mix() has hardcoded backups). Pre-1.0 breaking changes may remove fallback support. See css/tokens-legacy.css for legacy browser support.
js/slashed-ui.js adds progressive enhancements:
aria-expanded sync, Escape to close, click-outside to close<dialog>)aria-selected wiring--_i index on .stagger children for staggered animations--_fill for CSS-driven track fill on <input type="range"><script src="js/slashed-ui.js" defer></script>
Core CSS is fully functional without this file. JavaScript is optional, never required.
MIT — see LICENSE.
Copyright (c) 2026 Jacek Granatowski (codeslash.net).