Theme Bulma with Sass Tokens, Not CSS Patches
Patching .button.is-primary after Bulma compiles creates order- and specificity-fragile CSS. Set Sass tokens like $primary before import instead, then verify the hex value propagated to buttons, links, and focus rings.
24 Mar 2026, 17:09 UTC

The override that quietly breaks
You need a brand color across Bulma buttons, links, and focus states. The quick fix is to append .button.is-primary { background-color: #6c5ce7; } to the compiled stylesheet. It works until the next upgrade, until a pagination item looks wrong, or until a media query reorders rules and your patch loses to the original.
Bulma ships as CSS plus Sass sources and no JavaScript, so theming is a build-time decision. The supported path is to inject design tokens before you import the framework, not to edit the distributed stylesheet afterward.
Why source order is not a theming strategy
Bulma's classes are intentionally flat and low-specificity. When you override .button.is-primary after import, you rely on source order and equal specificity. If Bulma later changes how that selector is generated, wraps it in a media query, or introduces a more specific helper, your patch silently breaks. You also duplicate rules: the original primary color still ships in the payload, and your override adds a second copy.
Changing the source variable updates buttons, links, focus states, pagination, and tables consistently because every component derives from the same token.
Set design tokens before you import Bulma
Bulma exposes Sass variables such as $primary, $primary-invert, $scheme-main, $radius, and $family-primary. Setting them before import means the framework derives components from your palette in one pass.
Because Bulma's Sass API has changed across major versions, confirm the exact entrypoint and variable names in your installed package before relying on this pattern. The 0.9 line and 1.x do not share an identical token list or module path.
Worked example
Create a single Sass entry point in your project root:
// src/theme.scss
// Verify these names against your installed Bulma version.
$primary: #6c5ce7;
$primary-invert: #ffffff;
$scheme-main: #ffffff;
$radius: 4px;
$family-primary: "Inter", sans-serif;
@import "bulma/bulma";
Compile it with Dart Sass from your project root. You need normal user write access to the output directory:
sass src/theme.scss dist/theme.css --no-source-map
Expected checks: grep -i "6c5ce7" dist/theme.css should return matches inside .button.is-primary background and focus-ring rules. If the variable name is wrong, Sass may warn or ignore it, and the compiled CSS will still contain Bulma's default blue.
Verify propagation in the browser
Render a primary button, a text link, and a focused input. Inspect computed styles: the button background should be your hex, and the input focus ring should derive from the same token rather than a separate hardcoded value. If you are on a release that exposes CSS variables in a --bulma-* namespace, toggle the theme scope and inspect the resolved values on the root element to confirm overrides apply where expected.
Sass tokens versus CSS custom properties
In Bulma 1.x, many theme values are exposed as CSS variables, enabling runtime or scoped theming without recompiling. For a fixed brand palette, however, Sass-time overrides usually emit smaller CSS because values are substituted directly rather than shipped as variables plus fallbacks. Choose CSS variables when you need dynamic themes; choose Sass tokens when the brand is static.
What tokens do not cover
Not every visual is tokenized. Some utilities and component internals are generated from fixed values or Sass functions, so overriding $primary may not affect every derived shade. If your version computes light or dark variants at compile time, setting only $primary can leave hover or invert colors inconsistent; set the derived tokens explicitly when they exist.
| Approach | Maintenance | CSS size | Upgrade risk |
|---|---|---|---|
| Sass token before import | Low: one source of truth | Smaller for fixed palette | Low: variables are the public API |
| Post-import class override | High: duplicate rules per component | Larger: original plus patch | High: depends on generated selectors |
Actionable checklist
- Pin the Bulma version in
package.json. - Create a minimal Sass entry that sets your tokens before import.
- Compile with Dart Sass and grep the output for your color value.
- Render a primary button, a text link, and a focused input; inspect computed styles.
- After any Bulma upgrade, diff the compiled CSS to catch renamed variables, changed entrypoints, or altered generated selectors.
Treat the compiled CSS as a build artifact. If you find yourself editing it directly, move that decision back into your Sass entry instead.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.