Theming with Sass: settings, partials and selective imports
Override Foundation's variables before the framework reads them, build a custom palette, change grid gutters, and import only the components you ship.
The settings file and import order
/* src/scss/_settings.scss — your own file, imported FIRST.
Never edit the copy inside node_modules. */
@import "util/util";
/* --- palette ------------------------------------------------------- */
$foundation-palette: (
primary: #6d28d9,
secondary: #64748b,
success: #15803d,
warning: #b45309,
alert: #b91c1c,
brand: #0f766e // adding a key creates .brand, .button.brand and friends
);
/* --- global ------------------------------------------------------- */
$global-font-size: 100%;
$global-width: rem-calc(1200);
$global-lineheight: 1.6;
$body-background: #fbfbfd;
$body-font-color: #1f2937;
$global-radius: 6px;
$global-margin: 1rem;
$global-padding: 1rem;
/* --- grid --------------------------------------------------------- */
$grid-column-count: 12;
$grid-column-gutter: (small: 16px, medium: 24px);
$grid-container-padding: (small: 16px, medium: 32px);
$grid-margin-gutters: (small: 12px, medium: 24px);
/* --- components --------------------------------------------------- */
$button-padding: (small: 0.5rem 1rem, medium: 0.75rem 1.5rem);
$button-radius: $global-radius;
$topbar-background: #ffffff;
$callout-background: #f1f5f9;/* src/scss/app.scss */
@import "settings"; // 1. your overrides
@import "foundation"; // 2. the framework, now reading your values
/* 3. anything that depends on Foundation's output goes last */
@import "components/site-header";
@import "components/data-table";- Sass resolves variables in order. An override declared after the import has no effect, because the media queries and classes were already generated.
$foundation-paletteis a map, so an extra key is enough to create a new colour everywhere the framework loops over the palette.- Because the palette is used inside
@eachloops, adding a colour increases the compiled CSS. Six variants is cheap; twenty is not. - Use
map-mergeto extend rather than replace:$foundation-palette: map-merge($foundation-palette, (brand: #0f766e));.
💡
Keep your settings file under version control and treat it as the design system's source of truth. It is much easier to review a palette change in a diff than to discover it in a compiled stylesheet.
Selective imports
/* Import the machinery, then include only the components in use.
foundation-global-styles and foundation-typography are almost always needed;
everything else is a decision you can justify. */
@import "settings";
@import "foundation";
@include foundation-global-styles;
@include foundation-grid;
@include foundation-flex-grid;
@include foundation-xy-grid-classes(
$base-grid: true,
$margin-grid: true,
$padding-grid: true,
$block-grid: true,
$collapse: true,
$offset: true,
$vertical-grid: false // skip vertical grids if you never use them
);
@include foundation-typography;
@include foundation-forms;
@include foundation-button;
@include foundation-button-group;
@include foundation-card;
@include foundation-callout;
@include foundation-label;
@include foundation-badge;
@include foundation-table;
@include foundation-menu;
@include foundation-dropdown;
@include foundation-dropdown-menu;
@include foundation-top-bar;
@include foundation-reveal;
@include foundation-accordion;
@include foundation-tabs;
@include foundation-off-canvas;
@include foundation-visibility-classes;
@include foundation-flex-classes;
@include foundation-prototype-classes; // optional: the .text-*, .float-* helpers| Include | Adds | Typical saving |
|---|---|---|
foundation-xy-grid-classes with features off | Fewer grid classes | 5-15% of the file |
| Dropping unused components | Only what you use | 30-50% |
Skipping foundation-prototype-classes | No utility classes | 3-8% |
| Omitting Motion UI | No keyframes | 2-5% |
$global-text-direction left at default | No RTL duplication | Avoids doubling the output |
/* Grid gutters are a map, so overriding them is a single declaration.
Foundation generates the breakpoint variants from these keys. */
$grid-margin-gutters: (small: 16px, medium: 24px, large: 32px);
$grid-container-max: rem-calc(1440);
/* Changing the column count regenerates every cell class. This is possible in
Sass precisely because the classes are generated, not hand-written. */
$grid-column-count: 16;Keeping the theme maintainable
- One settings file, owned by the team, with a comment for every value that is not a straight copy of a Foundation default.
- A single entry stylesheet whose import list is the manifest of what the site ships.
- Component partials that consume Foundation's variables rather than redefining colours.
- A build check that fails when the compiled CSS grows by more than an agreed percentage.
- A visual regression snapshot per template, because Sass changes fail silently at the layout level.
/* A component partial that stays compatible with the theme: it reads
Foundation's variables instead of inventing its own palette. */
.site-header {
background: $topbar-background;
border-bottom: 1px solid $light-gray;
.site-header__title {
font-size: rem-calc(18);
color: get-color(primary); // looks the value up in $foundation-palette
font-weight: $global-weight-bold;
}
}
/* Never do this — it breaks the moment the palette changes:
color: #6d28d9; */| Practice | Good | Bad |
|---|---|---|
| Colour | get-color(primary) | A hex literal copied from the design |
| Spacing | $global-margin | A magic 17px |
| Units | rem-calc(18) | A bare 18px that ignores user font size |
| Breakpoints | breakpoint(medium) | A hand-written min-width: 640px |
| Radius | $global-radius | Three different corner radii |
FAQ
Why did my variable override have no effect?
Import order. Your settings partial must be imported before
foundation; declaring the variable afterwards leaves the framework's defaults already compiled into the output.Can I theme Foundation with CSS custom properties instead?
Only partially. Foundation 6 emits mostly static values, so variables are resolved at build time. A few components expose custom properties, but a full re-theme without a build step is not a supported workflow.
Related
Project setup: Sass, Motion UI and the build pipeline Choosing Foundation
Last refreshed 2026-09-18.