A lightweight, atomic-first CSS framework for building fast, accessible, and maintainable web interfaces. Created in 2019 and now open source, Foundation CSS provides utility classes for rapid prototyping and consistent design systems.
- Lightweight: Only 19.8KB gzipped (156KB minified)
- Mobile-first: Responsive by default with consistent breakpoints
- Accessible: Built with accessibility in mind
- Customizable: Easy to customize with SCSS variables
- Modular: Import only what you need
- Fast: Optimized for performance and developer experience
npm install @enodo/foundation-css
<!-- Latest version -->
<link rel="stylesheet" href="https://unpkg.com/@enodo/foundation-css@latest/dist/index.min.css">
<!-- Specific version -->
<link rel="stylesheet" href="https://unpkg.com/@enodo/foundation-css@1.0.0/dist/index.min.css">
<!-- jsDelivr alternative -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@enodo/foundation-css@latest/dist/index.min.css">
// Import everything
@use "@enodo/foundation-css";
// Or import specific modules (short aliases)
@use "@enodo/foundation-css/typographies";
@use "@enodo/foundation-css/spacing-units";
@use "@enodo/foundation-css/colors";
// Variables and functions
@use "@enodo/foundation-css/variables/colors";
@use "@enodo/foundation-css/functions";
src/
├── atomic/ # Atomic utility classes
│ ├── _backgrounds.scss
│ ├── _borders.scss
│ ├── _colors.scss
│ ├── _displays.scss
│ ├── _spacing-units.scss
│ └── ...
├── variables/ # Customizable variables
│ ├── _breakpoints.scss
│ ├── _colors.scss
│ └── ...
├── functions/ # SCSS utility functions
│ ├── _forge.scss
│ ├── _px2rem.scss
│ └── ...
└── index.scss # Main entry point
Foundation CSS provides utility classes for:
- Colors :
.fc-*
,.bg-*
,.bc-*
- Display :
.d-flex
,.d-grid
,.d-none
, ... - Spacing :
.p*
,.m*
,.g*
- Typography : Classes for sizes, weights, alignment optimized for reading on all devices
- Positions :
.ps-*
,.t*
,.l*
, ... - Visibility :
.visibility-*
,.opacity-*
- And much more...
Foundation CSS implements a systematic approach to sizing through Spacing Units and Typography Scale, inspired by BBC GEL guidelines.
- 16 Spacing Units (1 SU to 16 SU) for consistent margins, padding, and gaps
- 15 Typography Sizes (atlas, elephant, canon, body-copy, etc.) with semantic naming
- Responsive by default with automatic scaling across breakpoints
- Accessibility-focused using rem units for browser text resizing compatibility
For detailed explanations and usage guidelines, see our Sizing Concepts documentation.
$breakpoints: (
sm: 600px,
md: 1008px,
lg: 1280px,
);
px2rem()
: Convert px to remresponsify()
: Built-in responsive support
# Build everything (CSS + docs)
npm run build
# Build only CSS
npm run build:css
# Build documentation
npm run build:docs
# Development with watch
npm run dev
# Check bundle size
npm run size
# Linting
npm run lint
npm run lint:fix
# Formatting
npm run format
npm run format:check
# Serve documentation
npm run serve
Complete documentation is available locally:
npm run serve
Then visit http://localhost:8080
to browse all components and examples.
<div class="d-flex fd-column g4 p4">
<header class="bg-light-900 fc-light p4">Header</header>
<main class="d-flex fl1 fd-column p4">Main content</main>
<footer class="bg-green p4">Footer</footer>
</div>
<!-- Responsive grid: 1 column on mobile, 2 on tablet, 3 on desktop -->
<div class="d-grid grid__1 sm:grid__2 md:grid__3 g4">
<div class="bg-light p4">Card 1</div>
<div class="bg-light p4">Card 2</div>
<div class="bg-light p4">Card 3</div>
</div>
<h1 class="fs-canon fw-bold mb4">Main title</h1>
<p class="fs-paragon fc-light-700">Paragraph with good line spacing.</p>
<!-- Responsive classes -->
<div class="d-block sm:d-flex md:d-grid">
<!-- Block on mobile, flex on tablet, grid on desktop -->
</div>
<!-- Hover effects -->
<button class="bg-blue fc-white h:bg-green h:fc-dark t">
Hover me
</button>
<!-- Focus states -->
<input class="bc-light f:bc-blue f:bs-sm" type="text">
Customize the framework by redefining variables:
@use "@enodo/foundation-css" with (
// Breakpoints for responsive design
$breakpoints: (
sm: 768px,
md: 1024px,
lg: 1440px,
),
// Color palette with variations
$colors: (
primary: (
main: #your-color, /* generate var(--primary) */
100: #your-color, /* generate var(--primary-100) color variation */
),
secondary: (
main: #your-color, /* generate var(--secondary) */
),
),
// Spacing units for consistent spacing (margin, padding, gap, positioning, ...)
$spacing-units: (
1: 4px,
2: 8px,
3: 12px,
4: 16px,
5: 20px,
6: 24px,
7: 32px,
8: 40px,
9: 48px,
10: 56px,
11: 64px,
12: 72px,
13: 80px,
14: 120px,
15: 160px,
16: 200px,
),
// Border radius values
$borders: (
xs: 3px,
sm: 5px,
md: 8px,
lg: 16px,
xl: 24px,
),
// Box shadow definitions
$box-shadows: (
none: none,
sm: (0 1px 2px hsla(0deg, 0%, 0%, 0.05)),
md: (0 1px 3px hsla(0deg, 0%, 0%, 0.06)),
lg: (0 1px 4px hsla(0deg, 0%, 0%, 0.09)),
xl: (0 10px 24px hsla(0deg, 0%, 0%, 0.05)),
),
// Generated background properties
$backgrounds: (
size: (auto, cover, contain),
repeat: (repeat, no-repeat, repeat-x, repeat-y),
position: (center, top, bottom, left, right),
),
// Generated cursor types
$cursors: auto, default, pointer, wait, move, not-allowed, help, text, grab, grabbing,
// Generated display values
$displays: block, grid, inline-grid, inline, inline-block, flex, inline-flex, none, table, table-cell, table-row, unset,
// Generated interactivity properties
$pointer-events: auto, none,
$user-selects: auto, none,
$user-drags: auto, none,
// Generated list styling
$list-styles: disc, decimal, inherit,
$list-positions: inside, outside,
// Generated object fit values
$object-fit: contain, cover, fill, none,
// Generated opacity values
$opacities: (0, 5, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100),
$opacities-hover: (0, 5, 50, 80, 100),
$opacities-focus: (100),
// Generated position values
$positions: absolute, fixed, relative, static, sticky, unset,
// Generated typography settings
$font-families: (
brand: "My funky font family",
sans: (system-ui, -apple-system, "Segoe UI", "Roboto", "Helvetica Neue", "Arial", sans-serif),
serif: ("Times New Roman", "Times", "Georgia", serif),
mono: ("SFMono-Regular", "Consolas", "Liberation Mono", "Menlo", monospace),
),
// Generated font sizes
// Visit https://github.com/enodo-io/foundation-css/blob/main/src/variables/_typographies.scss
// for complete definition of corresponding font-size and line-height
$font-sizes: (
atlas,
elephant,
imperial,
royal,
foolscap,
canon,
trafalgar,
paragon,
double-pica,
great-primer,
body-copy,
pica,
long-primer,
brevier,
minion,
),
// Generated font weight values
$font-weights: (100, 200, 300, 400, 500, 600, 700, 800, 900),
// Vertical alignment
$vertical-aligns: baseline, bottom, middle, sub, super, text-bottom, text-top, top, unset,
// Z-index scale
$z-indexes: (
hide: -1,
base: 0,
selected: 25,
active: 50,
dropdown: 1000,
popover: 2000,
tooltip: 3000,
banner: 4000,
nav: 5000,
nav-fixed: 5050,
modal-bg: 9000,
modal: 9050,
)
);
Import only the modules you need:
@use "@enodo/foundation-css/backgrounds";
@use "@enodo/foundation-css/spacing-units";
@use "@enodo/foundation-css/typographies";
Foundation CSS exposes reusable variables as CSS custom properties that can be overridden at runtime:
/* Available CSS variables */
:root {
/* Spacing units (in rem for accessibility) */
--su1: 0.25rem; /* 4px */
--su2: 0.5rem; /* 8px */
--su3: 0.75rem; /* 12px */
--su4: 1rem; /* 16px */
--su5: 1.25rem; /* 20px */
--su6: 1.5rem; /* 24px */
--su7: 2rem; /* 32px */
--su8: 2.5rem; /* 40px */
/* ... up to --su16: 12.5rem (200px) */
--su-full: 63rem; /* 1008px */
--su-step: 5.25rem; /* 84px */
/* Border radius */
--br-xs: 0.1875rem; /* 3px */
--br-sm: 0.3125rem; /* 5px */
--br-md: 0.5rem; /* 8px */
--br-lg: 1rem; /* 16px */
--br-xl: 1.5rem; /* 24px */
/* Box shadows */
--bs-none: none;
--bs-sm: 0 1px 2px hsla(0deg, 0%, 0%, 0.05), ...;
--bs-md: 0 1px 3px hsla(0deg, 0%, 0%, 0.06), ...;
--bs-lg: 0 1px 4px hsla(0deg, 0%, 0%, 0.09), ...;
--bs-xl: 0 10px 24px hsla(0deg, 0%, 0%, 0.05), ...;
/* Colors (see palette documentation) */
--light: #fff;
--light-100: #e1e3e8;
--green: #4bdc9f;
--green-100: #e8f8f2;
/* ... all color stops */
}
/* Use in your custom components */
.my-button {
padding: var(--su3) var(--su5); /* 12px 20px */
border-radius: var(--br-md); /* 8px */
box-shadow: var(--bs-sm);
background-color: var(--green);
color: var(--light);
}
.my-card {
padding: var(--su4);
gap: var(--su3);
border-radius: var(--br-lg);
box-shadow: var(--bs-md);
}
/* Media queries need hardcoded values (CSS vars don't work) */
@media (min-width: map.get($breakpoints, md)) {
.my-component {
padding: var(--su6);
}
}
/* Dynamic theming with JavaScript */
document.documentElement.style.setProperty('--green', '#your-brand-color');
Create custom components using CSS custom properties:
@use "sass:map";
/* Recommended: Use CSS variables for easier maintenance */
.button {
display: inline-flex;
align-items: center;
justify-content: center;
border: none;
border-radius: var(--br-sm);
cursor: pointer;
transition: all 0.2s ease;
padding: var(--su3) var(--su5); /* 12px 20px */
}
.button--small {
padding: var(--su2) var(--su3); /* 8px 12px */
font-size: 0.875rem;
}
.button--large {
padding: var(--su4) var(--su7); /* 16px 32px */
font-size: 1.125rem;
}
.button--primary {
background-color: var(--green);
color: var(--light);
}
.button--primary:hover {
background-color: var(--green-600);
}
.button--secondary {
background-color: var(--light-500);
color: var(--light);
}
.button--secondary:hover {
opacity: 0.8;
}
.my-card {
display: flex;
flex-direction: column;
gap: var(--su3);
padding: var(--su4);
background-color: var(--light-100);
border-radius: var(--br-md);
box-shadow: var(--bs-sm);
}
@media (min-width: map.get($breakpoints, md)) {
.my-card {
padding: var(--su6);
}
}
This approach ensures consistency with Foundation CSS design tokens while creating custom components.
Foundation CSS follows Atomic CSS principles:
- Atomicity : Each class has a single responsibility
- Composability : Classes combine to create complex layouts
- Performance : Optimized size and automatic CSS purging
- Maintainability : Modular and well-structured SCSS code
- Fork the project
- Create your feature branch (
git checkout -b feature/AmazingFeature
) - Commit your changes (
git commit -m 'Add some AmazingFeature'
) - Push to the branch (
git push origin feature/AmazingFeature
) - Open a Pull Request
- Complete examples in the documentation
- Add conditional classes for print media
- Refactor documentation generation to use loops and variables instead of hardcoded HTML (reduce code duplication in the repo)
- Improve documentation
- Create a better design or UI for the documentation using only Foundation CSS tools
- Make a better default color palette
- Check color palette contrast WCAG compatibility in documentation
- Facilitate dark mode creation
This project is licensed under the MIT License.
Special thanks to:
-
The BBC UX&D team for their pioneering work on the BBC GEL (Global Experience Language) guidelines. The spacing unit and typography concepts in Foundation CSS are directly inspired by their systematic, accessibility-focused approach to design systems.
-
The Stack Overflow team for their excellent Stacks design system. Foundation CSS's atomic naming conventions and conditional class system draw inspiration from their thoughtful, developer-friendly approach to utility-first CSS.