Sass Customization
Sass customization allows you to configure Bulma's design tokens at build time by setting Sass variables. This approach was the primary customization method in Bulma v0.9.4 and earlier, and remains useful for creating consistent, compiled themes.
While Sass customization is still supported and useful, consider using CSS Variables for runtime flexibility and dynamic theming capabilities introduced in Bulma v1.
Overview
Sass variables control the fundamental values that Bulma uses to generate its CSS. When you customize Sass variables, these values are compiled into the final CSS at build time, affecting the default appearance and the values of CSS variables.
Dependencies
To customize Bulma with Sass variables, you need:
npm install sass
npm install bulma
Build Configuration
Webpack
For Webpack-based projects (Create React App, custom Webpack):
package.json scripts:
{
"scripts": {
"build-bulma": "sass --load-path=node_modules src/styles/bulma-custom.scss src/styles/bulma-custom.css",
"watch-bulma": "npm run build-bulma -- --watch"
}
}
Custom Sass file (src/styles/bulma-custom.scss):
// Set your brand colors
$purple: #8a4d76;
$pink: #fa7c91;
$brown: #757763;
$beige-light: #d0d1cd;
$beige-lighter: #eff0eb;
// Customize Bulma variables
@use 'bulma/sass' with (
$family-primary: '"Nunito", sans-serif',
$grey-dark: $brown,
$grey-light: $beige-light,
$primary: $purple,
$link: $pink,
$control-border-width: 2px,
$input-shadow: none
);
// Import custom fonts
@import url('https://fonts.googleapis.com/css?family=Nunito:400,700');
Import in your React app:
// src/index.tsx or src/App.tsx
import './styles/bulma-custom.css';
import { Button, Box, Title } from '@allxsmith/bestax-bulma';
function App() {
return (
<Box p="4">
<Title>Custom Sass Theme</Title>
<Button color="primary">Custom Primary Button</Button>
</Box>
);
}
Vite
For Vite projects, you can directly import and process Sass:
vite.config.js:
import { defineConfig } from 'vite';
export default defineConfig({
css: {
preprocessorOptions: {
scss: {
includePaths: ['node_modules'],
},
},
},
});
Custom Sass file (src/styles/bulma-custom.scss):
@use 'bulma/sass' with (
$primary: #e91e63,
$family-primary: '"Roboto", sans-serif',
$radius-large: 12px,
$control-height: 3rem
);
Import directly in React:
// src/main.tsx or src/App.tsx
import './styles/bulma-custom.scss';
import { Button, Container } from '@allxsmith/bestax-bulma';
function App() {
return (
<Container>
<Button color="primary">Vite + Sass Button</Button>
</Container>
);
}
Next.js
Next.js has built-in Sass support:
Install Sass:
npm install sass
Custom Sass file (styles/bulma-custom.scss):
@use 'bulma/sass' with (
$primary: #0070f3,
$family-primary: '"Inter", sans-serif',
$navbar-height: 4rem,
$footer-padding: 3rem 1.5rem
);
Import in _app.tsx:
// pages/_app.tsx
import '../styles/bulma-custom.scss';
import type { AppProps } from 'next/app';
export default function App({ Component, pageProps }: AppProps) {
return <Component {...pageProps} />;
}
Use in pages:
// pages/index.tsx
import { Hero, Container, Title, Button } from '@allxsmith/bestax-bulma';
export default function Home() {
return (
<Hero size="medium">
<Hero.Body>
<Container>
<Title>Next.js + Sass Customization</Title>
<Button color="primary" size="large">
Get Started
</Button>
</Container>
</Hero.Body>
</Hero>
);
}
Common Sass Variables
Color Variables
@use 'bulma/sass' with (
// Primary colors
$primary: #3273dc,
$link: #3273dc,
$info: #3298dc,
$success: #48c774,
$warning: #ffdd57,
$danger: #f14668,
// Neutral colors
$white: #ffffff,
$black: #0a0a0a,
$light: #f5f5f5,
$dark: #363636,
// Grey shades
$grey-darker: #121212,
$grey-dark: #363636,
$grey: #4a4a4a,
$grey-light: #b5b5b5,
$grey-lighter: #dbdbdb
);
Typography Variables
@use 'bulma/sass' with (
// Font families
$family-sans-serif: '"Inter", "SF Pro Display", sans-serif',
$family-monospace: '"Fira Code", "SF Mono", monospace',
$family-primary: $family-sans-serif,
$family-secondary: $family-sans-serif,
$family-code: $family-monospace,
// Font sizes
$size-1: 3rem,
$size-2: 2.5rem,
$size-3: 2rem,
$size-4: 1.5rem,
$size-5: 1.25rem,
$size-6: 1rem,
$size-7: 0.875rem,
// Font weights
$weight-light: 300,
$weight-normal: 400,
$weight-medium: 500,
$weight-semibold: 600,
$weight-bold: 700
);
Layout Variables
@use 'bulma/sass' with (
// Spacing
$block-spacing: 1.5rem,
$column-gap: 0.75rem,
// Border radius
$radius-small: 2px,
$radius: 4px,
$radius-medium: 6px,
$radius-large: 8px,
$radius-rounded: 9999px,
// Control elements
$control-height: 2.5em,
$control-line-height: 1.5,
$control-padding-vertical: calc(0.5em - 1px),
$control-padding-horizontal: calc(0.75em - 1px)
);
Component Variables
@use 'bulma/sass' with (
// Button
$button-padding-vertical: 0.5rem,
$button-padding-horizontal: 1rem,
$button-border-radius: $radius,
// Input
$input-shadow: inset 0 0.0625em 0.125em rgba(10, 10, 10, 0.05),
$input-hover-border-color: $grey-dark,
$input-focus-border-color: $link,
// Card
$card-shadow: 0 0.5em 1em -0.125em rgba(10, 10, 10, 0.1),
$card-radius: $radius-large,
// Navbar
$navbar-height: 3.25rem,
$navbar-padding-vertical: 1rem,
$navbar-padding-horizontal: 2rem
);
Legacy vs Modern Approach
Bulma v0.9.4 and Earlier
In older versions of Bulma, Sass customization was the only way to customize the framework:
// Old approach (still works)
$primary: #ff6b35;
$family-primary: 'Helvetica Neue', sans-serif;
@import 'bulma/bulma.sass';
Bulma v1 with CSS Variables
Modern Bulma generates CSS variables from Sass variables:
// Sass variables affect the CSS variable defaults
@use 'bulma/sass' with (
$primary: #ff6b35,
// Sets --bulma-primary-* variables
$family-primary: 'Helvetica Neue',
sans-serif
);
The generated CSS includes variables that can be overridden at runtime:
:root {
--bulma-primary-h: 18deg;
--bulma-primary-s: 100%;
--bulma-primary-l: 60%;
--bulma-family-primary: 'Helvetica Neue', sans-serif;
}
Integration with React Components
Build-time Theme
// styles/corporate-theme.scss
@use 'bulma/sass' with (
$primary: #1e3a8a,
// Corporate blue
$success: #059669,
// Corporate green
$family-primary: '"Open Sans", sans-serif',
$radius: 2px,
// Sharp corners
$control-height: 3rem // Larger controls
);
// App.tsx
import './styles/corporate-theme.css';
import { Button, Card, Container, Title } from '@allxsmith/bestax-bulma';
function CorporateApp() {
return (
<Container>
<Card>
<Card.Content>
<Title>Corporate Design System</Title>
<Button color="primary">Corporate Button</Button>
<Button color="success" ml="2">
Action Button
</Button>
</Card.Content>
</Card>
</Container>
);
}
Combining with CSS Variables
You can use both approaches together - Sass for base configuration and CSS variables for runtime theming:
// Base theme with Sass
@use 'bulma/sass' with (
$family-primary: '"Inter", sans-serif',
$radius: 6px,
$control-height: 2.75rem
);
// Runtime theming with CSS variables
import { Theme } from '@allxsmith/bestax-bulma';
function App() {
return (
<Theme primaryH="270" primaryS="100%" primaryL="50%" isRoot>
<CorporateApp />
</Theme>
);
}
Best Practices
1. Establish Design Tokens
Define your design system values clearly:
// design-tokens.scss
$brand-blue: #1e40af;
$brand-green: #059669;
$brand-orange: #ea580c;
$font-primary: '"Inter", sans-serif';
$font-mono: '"JetBrains Mono", monospace';
$spacing-unit: 0.25rem;
$border-radius-base: 6px;
@use 'bulma/sass' with (
$primary: $brand-blue,
$success: $brand-green,
$warning: $brand-orange,
$family-primary: $font-primary,
$family-code: $font-mono,
$radius: $border-radius-base
);
2. Modular Sass Files
Organize your customizations by feature:
// styles/main.scss
@use './variables' as vars;
@use './typography';
@use './components';
@use 'bulma/sass' with (
$primary: vars.$brand-primary,
$family-primary: vars.$font-family-base
);
3. Environment-specific Builds
Create different themes for different environments:
// themes/development.scss
@use 'bulma/sass' with (
$primary: #ef4444,
// Red for development
$warning: #f59e0b
);
// themes/production.scss
@use 'bulma/sass' with (
$primary: #3b82f6,
// Blue for production
$warning: #f59e0b
);
Migration from Sass to CSS Variables
When migrating from pure Sass customization to CSS variables:
// Before: Sass only
$primary: #8b5cf6;
$border-radius: 8px;
// After: Sass for defaults, CSS variables for runtime
@use 'bulma/sass' with (
$primary: #8b5cf6,
// Default value
$radius: 8px // Default value
);
// Runtime customization with Theme component
<Theme
primaryH="258"
primaryS="90%"
primaryL="64%"
bulmaVars={{ '--bulma-radius': '12px' }}
>
<App />
</Theme>
This approach provides the best of both worlds: consistent build-time defaults with runtime flexibility.
For more information about modern theming approaches, see CSS Variables and Theme component documentation.