SLASHED

SLASHED LOGO

SLASHED

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).


Quick start

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.


Philosophy

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:

  1. BEM blocks — your namespace (.product-card, .site-header)
  2. Layout primitives.sf-container, .sf-stack, .sf-grid — compose pages
  3. Utilitiessf-flex, sf-gap-*, sf-text-* — one-off tweaks only

See CLAUDE.md for the complete philosophy and critical gotchas. See docs/BEM.md for naming rules and CONTRIBUTING.md for architecture.


Interactive tools

Open these HTML files in your browser to explore and build with SLASHED:


Features

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.).


Installation

Static sites & CDN

<!-- 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">

Download

  1. Download the latest release
  2. Extract the archive
  3. Copy the css/ folder to your project
  4. Link in your HTML:
<link rel="stylesheet" href="path/to/slashed/css/slashed-essential.css">

WordPress

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');
});

Bricks Builder

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, Next.js, Eleventy

// 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">

Token customization

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.


Authoring example

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 */

File reference

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)

Contributing

SLASHED welcomes contributions. See CONTRIBUTING.md for:

New features must:

  1. Earn their place (no decoration bloat)
  2. Follow BEM naming and cascade layers
  3. Use design tokens (no magic numbers)
  4. Update CHANGELOG.md in the same commit
  5. Pass linting and pre-commit checks

See docs/BEM.md for the complete BEM naming convention (required reading before authoring new components).


Browser support

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.


Optional JavaScript enhancements

js/slashed-ui.js adds progressive enhancements:

<script src="js/slashed-ui.js" defer></script>

Core CSS is fully functional without this file. JavaScript is optional, never required.


License

MIT — see LICENSE.

Copyright (c) 2026 Jacek Granatowski (codeslash.net).