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-palette is 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 @each loops, adding a colour increases the compiled CSS. Six variants is cheap; twenty is not.
  • Use map-merge to 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
IncludeAddsTypical saving
foundation-xy-grid-classes with features offFewer grid classes5-15% of the file
Dropping unused componentsOnly what you use30-50%
Skipping foundation-prototype-classesNo utility classes3-8%
Omitting Motion UINo keyframes2-5%
$global-text-direction left at defaultNo RTL duplicationAvoids 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

  1. One settings file, owned by the team, with a comment for every value that is not a straight copy of a Foundation default.
  2. A single entry stylesheet whose import list is the manifest of what the site ships.
  3. Component partials that consume Foundation's variables rather than redefining colours.
  4. A build check that fails when the compiled CSS grows by more than an agreed percentage.
  5. 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; */
PracticeGoodBad
Colourget-color(primary)A hex literal copied from the design
Spacing$global-marginA magic 17px
Unitsrem-calc(18)A bare 18px that ignores user font size
Breakpointsbreakpoint(medium)A hand-written min-width: 640px
Radius$global-radiusThree 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.

Project setup: Sass, Motion UI and the build pipeline Choosing Foundation

Last refreshed 2026-09-18.