Sass Customization

Once TrailMap needs a brand color that isn't Bootstrap's default blue, most people reach for a CSS override sheet loaded after Bootstrap's own stylesheet, sprinkled with !important to make sure it wins. It works for about a week, and then it doesn't: a component you haven't touched yet still renders in the old blue, a Bootstrap update changes selector specificity, and now you're playing whack-a-mole across a dozen files. Bootstrap 5 ships its entire source as Sass, and the officially recommended fix is to override its variables before that source ever gets compiled — so every component that reads $primary picks up TrailMap's trail-green automatically, with zero overrides to maintain.

The Problem with !important Overrides

Say TrailMap's stylesheet, loaded after the Bootstrap CDN link, tries to recolor every primary button:

/* trailmap-overrides.css — loaded AFTER bootstrap.min.css */
.btn-primary {
  background-color: #2c7a4b !important;
  border-color: #2c7a4b !important;
}

This "works," but only for .btn-primary. TrailMap's .text-primary headings, .border-primary cards, .bg-primary badges, active nav links, focus rings, and form validation states are all generated from the same $primary Sass value — and none of them get the memo. You'd need a matching !important override for every single one, forever fighting a framework that already has a mechanism built in for exactly this.

Note: !important overrides aren't "wrong" for a one-off exception. The problem is using them as your primary customization strategy — that's a sign you're fighting Bootstrap instead of configuring it.

The Right Way: Override Variables Before Importing

Bootstrap 5's compiled CSS is just the end result of compiling its own .scss source files. Every color, spacing value, and border-radius in that source is a Sass variable with a !default flag, which means: "use this value, unless something already set it earlier." So instead of importing the compiled CSS, TrailMap installs Bootstrap's source and writes its own entry file that sets variables first:

// trailmap-custom.scss

// 1. Your variable overrides go FIRST
$primary: #2c7a4b;

// 2. THEN import Bootstrap's actual source
@import "bootstrap/scss/bootstrap";

Order matters completely here. Because Bootstrap's own $primary: #0d6efd !default; line only assigns a value if nothing already claimed the variable, TrailMap's line — compiled first — wins, and Bootstrap's own default is silently skipped. Flip the two lines and this stops working entirely, since by the time your override runs, $primary is already locked in.

Worked Example: Recoloring TrailMap to Trail-Green

With $primary overridden, every component that derives from it changes at once — no per-component CSS required:

// trailmap-custom.scss
$primary: #2c7a4b;
$link-color: $primary;

@import "bootstrap/scss/bootstrap";
# compile it (via the sass CLI, or your bundler's sass loader)
npx sass trailmap-custom.scss trailmap-custom.css
<link href="trailmap-custom.css" rel="stylesheet">

<button class="btn btn-primary">Save Trail</button>
<a class="link-primary" href="#">View all trails</a>

The button, the link, the navbar's active state, form focus rings, badges using bg-primary-subtle — every one of them now renders in trail-green, compiled straight from a single line change. No selector ever had to be found and overridden by hand.

A Few Variables Worth Knowing

VariableControls
$primaryThe main brand color used across buttons, links, active states, focus rings
$body-bg / $body-colorDefault page background and text color
$font-family-baseThe default font stack for the whole page
$border-radiusDefault corner rounding for buttons, cards, inputs, alerts
$enable-shadowsTurns on subtle box-shadows across components (off by default)

Why This Beats the CDN Build

The CDN link you used in the Setup: CDN vs npm lesson points to a file that has already been compiled — its variables were resolved once, at Bootstrap's own build time, and baked into plain CSS. There is no way to hand a compiled CSS file a new value for $primary; by the time you can see it, the Sass step has already happened. Sass-variable overrides only work if you have Bootstrap's .scss source available and control the compile step yourself — which means npm (or another package manager) plus a Sass compiler, not a CDN link. It's the direct tradeoff for the customization power: a build step now, in exchange for never writing an override sheet again.

Next: Variables recolor and reshape existing components. The Utility API covers the sibling system that lets you add or remove entire utility classes like .mt-3.