Customising Bootstrap 5 Breakpoints and Grid Gutters with Sass

Customising Bootstrap 5 Breakpoints and Grid Gutters with Sass

Key Takeaways

  • Bootstrap 5 stores every breakpoint and gutter value in Sass maps, making them overridable before compilation rather than overridable with CSS hacks after.
  • You must override the $grid-breakpoints and $container-max-widths maps together, or layout utilities and container widths will fall out of sync.
  • Gutter widths are controlled by the $gutters map and the $grid-gutter-width variable, both of which cascade into spacing utilities, not just the grid.
  • Adding a new breakpoint requires updating four Sass maps and regenerating all responsive utility classes automatically through Bootstrap’s loop system.
  • A pre-built template like the Canvas HTML Template ships with a Sass source tree, so custom breakpoints slot in without rewriting compiled output.

How Bootstrap 5 Stores Breakpoints Internally

Bootstrap 5 defines breakpoints in a single Sass map called $grid-breakpoints, located in scss/_variables.scss. The default values in Bootstrap 5.3 are:

$grid-breakpoints: (
  xs:  0,
  sm:  576px,
  md:  768px,
  lg:  992px,
  xl:  1200px,
  xxl: 1400px
);

Every responsive utility class (d-md-flex, col-lg-4, mt-xl-5) is generated by looping over this map. Change the map values and the entire utility layer regenerates. That is the core promise of the Sass approach: one change, consistent output.

A companion map, $container-max-widths, pins container widths to specific breakpoints. Widen a breakpoint without updating this map and containers will overflow or leave unexpected whitespace at certain viewport sizes. Always treat these two maps as a pair.

Customising Bootstrap 5 Breakpoints and Grid Gutters with Sass, abstract concept illustration

Overriding Breakpoints the Correct Way

Put overrides in a custom file that sits before the Bootstrap import in your Sass entry point. Never edit _variables.scss directly. When Bootstrap publishes a patch, any edits made there will be overwritten.

A minimal override file looks like this:

// _custom-variables.scss

// Widen the xl breakpoint and add a 1920px xxxl tier
$grid-breakpoints: (
  xs:   0,
  sm:   576px,
  md:   768px,
  lg:   992px,
  xl:   1280px,
  xxl:  1440px,
  xxxl: 1920px
);

// Keep container widths proportional
$container-max-widths: (
  sm:   540px,
  md:   720px,
  lg:   960px,
  xl:   1240px,
  xxl:  1400px,
  xxxl: 1860px
);

Your Sass entry point then reads:

// main.scss
@import "custom-variables";
@import "bootstrap/scss/bootstrap";

Bootstrap processes $grid-breakpoints with !default flags, so any variable you declare first wins. The framework never overwrites a value already in scope. This is covered in more depth in the guide to building a custom Bootstrap 5 bundle, which also explains how to trim unused components during the same compilation pass.

Adding a Genuinely New Breakpoint

Adding xxxl to the map is sufficient for most utility classes because Bootstrap’s mixin loops pick it up automatically. You still need a matching entry in $container-max-widths. Bootstrap validates at runtime that every key in $container-max-widths exists in $grid-breakpoints and will throw a Sass error if the maps are inconsistent.

One practical limit worth knowing: Bootstrap’s column classes top out at 12 columns regardless of how many breakpoints you add. A new breakpoint does not add column slots. What it does add is a complete set of responsive utility classes at that viewport size, which is usually exactly what a wide-screen design system needs.

If you want column count to scale on very large screens, you need to extend the grid system explicitly:

// Extend grid columns for the xxxl tier only
@include media-breakpoint-up(xxxl) {
  @for $i from 1 through 12 {
    .col-xxxl-#{$i} {
      width: percentage($i / 12);
      flex: 0 0 auto;
    }
  }
}

Keep this block in a separate partial so it does not clutter your variable overrides.

bootstrap grid gutters, abstract technical diagram

Customising Grid Gutters with Sass

Gutters in Bootstrap 5 are controlled by two variables. $grid-gutter-width sets the base horizontal gutter used in legacy-style grids. The more powerful lever is the $gutters map, which feeds the g-, gx-, and gy-* utility classes:

// Default Bootstrap 5.3 gutters map
$gutters: (
  0: 0,
  1: $spacer * .25,
  2: $spacer * .5,
  3: $spacer,
  4: $spacer * 1.5,
  5: $spacer * 3,
);

Because gutters are expressed as multiples of $spacer (default 1rem), shrinking the spacer compresses every gap in the layout at once. That is rarely what you want. More surgical control comes from replacing specific map entries directly:

// Tighter gutters for a data-dense dashboard
$gutters: (
  0: 0,
  1: 0.25rem,
  2: 0.5rem,
  3: 0.75rem,
  4: 1.25rem,
  5: 2rem
);

$grid-gutter-width: 1.5rem; // down from 1.875rem

Place these overrides in the same _custom-variables.scss partial before the Bootstrap import. The compiled output will reflect the new scale in every gutter utility class across the entire site, including nested grids and form rows.

If your project also uses fluid typography, be aware that tighter gutters and a fluid type scale interact directly because column padding affects readable line length. The post on fluid typography in Bootstrap 5 with clamp() and CSS variables walks through how to balance those two concerns.

Responsive Gutters Per Breakpoint

A fixed gutter is often too wide on mobile and too narrow on desktop. Bootstrap 5 does not ship responsive gutter variables out of the box, but the pattern is straightforward to implement with the media-breakpoint-up mixin:

// Responsive gutter override
:root {
  --bs-gutter-x: 1rem; // mobile default
}

@include media-breakpoint-up(md) {
  :root {
    --bs-gutter-x: 1.5rem;
  }
}

@include media-breakpoint-up(xl) {
  :root {
    --bs-gutter-x: 2rem;
  }
}

Bootstrap 5 exposes --bs-gutter-x and --bs-gutter-y as CSS custom properties on .row and .container. Overriding them at the :root level cascades down to every row on the page. This approach does not require recompilation when you want to change a gutter at runtime, making it a good fit for theme-switching scenarios. Canvas uses a similar pattern through its --cnvs-themecolor variable system, so the two approaches compose cleanly.

Common Mistakes to Avoid

  • Editing node_modules directly. Any npm update or npm ci run will wipe your changes. Always override through a custom partial.
  • Forgetting to update $container-max-widths. A new breakpoint in $grid-breakpoints without a matching container width causes containers to fill 100% of the viewport at that tier, which is usually not what you intended.
  • Using only the CSS variable approach without Sass. CSS variable overrides adjust values at runtime but do not regenerate utility classes. You will have --bs-gutter-x at the right value but gx-3 will still compile to the default pixel value in the stylesheet.
  • Mixing breakpoint overrides with a CDN-hosted Bootstrap build. Loading Bootstrap from a CDN means loading compiled CSS with hardcoded breakpoints. Sass overrides have no effect. You must compile Bootstrap yourself. The post on building websites with Bootstrap 5 in 2026 covers setting up a local build pipeline from scratch.
  • Omitting the xs: 0 entry. Bootstrap’s breakpoint loop requires xs to remain at 0. Removing it breaks the col-* (no breakpoint prefix) classes entirely.

Using Canvas as a Sass Foundation

Implementing these overrides from scratch requires configuring a Sass compiler, managing import order, and testing output across the breakpoint range. The Canvas HTML Template ships with the complete Bootstrap 5 Sass source tree already integrated, so the _custom-variables.scss pattern described in this article works out of the box. Canvas adds its own variable layer on top, exposing things like --cnvs-themecolor and column gap tokens that sit above the Bootstrap defaults and below component styles. That layering means you can override Bootstrap breakpoints in one file, Canvas layout tokens in another, and component overrides in a third, keeping separation of concerns clean across a large project.

Across its 50-plus live demos, Canvas ships layouts that already span the full breakpoint range. Stress-testing a new xxxl tier is as simple as opening an existing demo at 1920 pixels and checking whether the container constraint holds.

Frequently Asked Questions

No, not in a way that generates utility classes. CSS custom property overrides adjust values at runtime, but responsive classes like d-xxxl-flex or col-xxxl-6 only exist if Bootstrap’s Sass loop ran with your breakpoint in $grid-breakpoints. You must compile Bootstrap from its Sass source to add genuine new breakpoints.

$grid-gutter-width is a scalar variable used as the default horizontal spacing between columns in the legacy row/column system. The $gutters map defines the scale of values available to the g-, gx-, and gy-* utility classes. In modern Bootstrap 5 projects, the $gutters map is the primary lever because it covers both axes and integrates with the spacing utility scale.

Yes, every variable in scss/_variables.scss is declared with !default. This means Sass will use your value if one is already in scope and ignore the Bootstrap default. That is why your custom partial must be imported before bootstrap/scss/bootstrap: the variable needs to be defined before Bootstrap attempts to set its default.

Changing breakpoint names will break any class that references that name (for example, renaming md to tablet breaks d-md-flex). Changing breakpoint values while keeping the same names is safe: all classes regenerate with the new pixel values. Always keep xs, sm, md, lg, xl, and xxl in the map if you want to retain compatibility with all default component classes.

Inspect the compiled CSS and search for the pixel value of your new breakpoint in a @media rule. For a xxxl tier at 1920px, you should find @media (min-width: 1920px) wrapping the utility classes for that tier. You can also use browser DevTools to simulate viewports at the exact breakpoint boundary and verify that responsive classes toggle correctly.

Looking for a production-ready Bootstrap 5 HTML template? Browse Canvas Template demos and find the perfect starting point for your next project.

If you’re building with the Canvas HTML Template and want to ship production-ready Bootstrap 5 layouts faster, try Canvas Builder free — the visual builder that exports clean Canvas-ready markup in minutes.

Skip the setup and build it free

Spin up a complete Bootstrap 5 site, blog included, with Canvas Builder. No coding, no cost.

Share:
Canvas Team
Canvas Team

Tutorials and tips for building beautiful Bootstrap 5 websites with the Canvas HTML Template and Canvas Builder.

More from the Canvas Blog