Principles

Vanilla Breeze is built on a philosophy of progressive enhancement, simplicity, and respect for the web platform. Understanding these principles helps you get the most out of the library.

The Three-Layer Architecture

Vanilla Breeze organizes web development into three distinct, optional layers. Each layer builds on the previous without requiring it.

Layer 1: HTML

Semantic markup that works everywhere. Content is accessible, indexable, and functional with no styling at all.

Required: Always

Layer 2: CSS

Design tokens, native element styling, and CSS-only custom elements. Full visual polish without any JavaScript.

Required: Optional

Layer 3: JavaScript

Web components for complex interactivity: animations, keyboard navigation, ARIA management, and dynamic behavior.

Required: Optional

How the Layers Work Together

Consider an accordion component:

Layer What You Get Code
HTML only Functional expand/collapse with native <details> <details><summary>Title</summary>Content</details>
HTML + CSS Styled with proper spacing, typography, and visual hierarchy Same HTML, Vanilla Breeze CSS loaded
HTML + CSS + JS Smooth animations, keyboard navigation, exclusive mode <accordion-wc> wrapper added

Each layer is an enhancement, not a requirement. Your content works at every level.

Why HTML-First Matters

Many frameworks treat HTML as an afterthought or a compile target. Vanilla Breeze treats it as the foundation.

Benefits of HTML-First

Resilience

When JavaScript fails (and it will), your content remains accessible. Forms still submit. Links still navigate. Information is still readable.

Performance

HTML renders immediately. Users see content before CSS and JavaScript finish loading. No blank screens, no loading spinners for basic content.

SEO and Discoverability

Search engines can index all your content without executing JavaScript. Social media previews work correctly. Screen readers work out of the box.

Simplicity

HTML is the simplest programming language. Anyone can learn it. There's no build step, no transpilation, no framework-specific syntax to master.

Longevity

HTML from 1995 still works today. Frameworks come and go; semantic HTML persists. Your investment in learning HTML pays dividends forever.

The Web Platform is Powerful

Modern HTML provides more than many developers realize:

Vanilla Breeze enhances these native capabilities rather than replacing them.

Progressive Enhancement

Progressive enhancement means starting with a baseline experience that works for everyone, then adding capabilities for browsers and users that support them.

How Vanilla Breeze Implements This

CSS Custom Elements Without JavaScript

Layout elements like <layout-stack> and <layout-grid> work purely with CSS. No JavaScript registration is needed because they use CSS attribute selectors:

/* This selector works whether or not the element is registered */ layout-stack { display: flex; flex-direction: column; } layout-stack[data-layout-gap="m"] { gap: var(--size-m); }

Web Components That Enhance Native Elements

JavaScript web components wrap native HTML patterns. The native pattern always works; the web component adds polish:

<!-- This works without JS, styled by CSS --> <details> <summary>Click to expand</summary> <p>Content is always accessible</p> </details> <!-- This adds animations and keyboard features --> <accordion-wc> <details> <summary>Click to expand</summary> <p>Content with smooth animation</p> </details> </accordion-wc>

Graceful Degradation Patterns

Components use the :defined pseudo-class to style differently before and after JavaScript runs:

/* Before JS registers the component */ tabs-wc:not(:defined) { /* Show all panels stacked */ } /* After JS registers the component */ tabs-wc:defined { /* Show tab navigation */ }

Zero Dependencies

Vanilla Breeze has no runtime dependencies. The CSS and JavaScript are self-contained.

Why This Matters

How We Achieve This

Vanilla Breeze uses only:

Development dependencies exist for building and testing, but they never ship to users.

Semantic Naming

Names should describe what something is, not how it looks.

Custom Elements

Custom elements use descriptive, hyphenated names that are self-documenting:

<!-- Layout describes what it does --> <layout-stack> <!-- Stacks children vertically --> <layout-cluster> <!-- Clusters items horizontally with wrapping --> <layout-sidebar> <!-- Creates a sidebar layout --> <layout-grid> <!-- Responsive grid layout --> <!-- Web components describe their purpose --> <accordion-wc> <!-- Accordion behavior --> <tabs-wc> <!-- Tab interface --> <toast-wc> <!-- Toast notifications -->

CSS Classes

Classes describe variants or purposes, not visual properties:

<!-- Good: describes purpose --> <button class="secondary">Cancel</button> <button class="ghost">Learn More</button> <nav class="horizontal pills">...</nav> <!-- Avoid: describes appearance --> <button class="gray">Cancel</button> <button class="no-background">Learn More</button>

Design Tokens

Tokens use semantic names that adapt to context:

/* Good: semantic purpose */ color: var(--color-text); /* Adapts to light/dark */ color: var(--color-text-muted); /* Secondary text */ background: var(--color-surface); /* Main background */ background: var(--color-interactive); /* Interactive elements */ /* Avoid: literal values */ color: var(--gray-700); background: var(--white);

Data Attributes for Configuration

Vanilla Breeze uses data-* attributes rather than classes for component configuration and state. This creates a clear separation of concerns.

Why Data Attributes?

Aspect Classes Data Attributes
Purpose Styling hooks Configuration and state
Values Boolean only (present/absent) Any string value
JavaScript access classList.contains() dataset.property
Collision risk High (common names) Low (namespaced)

Convention

<!-- Configuration with values --> <layout-stack data-layout-gap="m" data-layout-align="center"> <layout-grid data-layout-min="200px" data-layout-gap="l"> <tabs-wc data-orientation="vertical"> <!-- State (boolean or value) --> <accordion-wc data-exclusive> <button data-state="loading"> <input data-valid="true"> <!-- Classes for variant styling only --> <button class="secondary"> <nav class="horizontal pills">

Key Design Decisions

Some decisions in Vanilla Breeze may seem unusual. Here's the reasoning behind them.

Why custom elements instead of utility classes?

<layout-stack data-layout-gap="m"> is more readable than <div class="flex flex-col gap-4">. Custom elements are self-documenting in the DOM inspector, clearly show nesting relationships, and don't pollute the global class namespace.

The trade-off is slight unfamiliarity for developers used to utility-class frameworks. We believe the readability and maintainability benefits outweigh this learning curve.

Why OKLCH colors?

OKLCH is perceptually uniform, meaning equal numeric changes produce equal visual changes. This makes it easier to create consistent color scales and accessible contrast ratios. It also supports the full P3 color gamut for modern displays.

All modern browsers support OKLCH. For older browsers, you can provide fallbacks, though Vanilla Breeze targets evergreen browsers.

Why CSS logical properties?

Logical properties (inline-size, block-start) adapt automatically to different writing modes and text directions. A component using logical properties works correctly in English (LTR), Arabic (RTL), and Japanese (vertical) without any changes.

This is important for internationalization and ensures Vanilla Breeze components work globally.

Why CSS @layer?

CSS layers provide predictable cascade control. Vanilla Breeze styles live in a layer that's easy to override without specificity battles. Your custom styles naturally take precedence.

@layer base, tokens, elements, components, utilities;
Why no CSS reset?

Vanilla Breeze uses selective normalization rather than a heavy reset. Browser defaults are often sensible; we only adjust what needs adjusting. This results in smaller CSS and respects user preferences.

Why MIT license?

MIT is maximally permissive. Students can use it in coursework. Companies can use it without licensing concerns. Contributors don't need legal review. This removes friction from adoption and encourages learning.

Next Steps

Now that you understand the philosophy, put it into practice:

Quick Start

Get up and running in minutes.

Tutorial

Build a complete page step by step.

Accessibility

Learn how Vanilla Breeze supports accessibility.

Elements

Explore all available components.