SCSS variables, CSS custom properties, functions, and mixins for customizing colors, typography, spacing, and component appearance throughout the framework.
Override default variables before importing Bulma to customize the entire framework.
/**
* Core customization approach
*/
// Override variables BEFORE importing Bulma
$primary: #ff6b6b;
$info: #54a0ff;
$success: #5f27cd;
$warning: #ff9f43;
$danger: #ee5253;
// Typography
$family-sans-serif: "Inter", "Helvetica Neue", Arial, sans-serif;
$family-monospace: "JetBrains Mono", "Fira Code", monospace;
$size-1: 3.5rem;
$size-2: 2.75rem;
$size-3: 2.25rem;
// Spacing
$gap: 2rem;
$column-gap: 0.75rem;
$container-offset: 2rem;
// Border radius
$radius: 6px;
$radius-small: 3px;
$radius-large: 8px;
$radius-rounded: 9999px;
// Import Bulma after variable overrides
@import 'bulma/bulma.scss';Core Variable Categories:
/* Color Variables */
$white: hsl(0, 0%, 100%);
$black: hsl(0, 0%, 4%);
$light: hsl(0, 0%, 96%);
$dark: hsl(0, 0%, 21%);
/* Color Palette */
$primary: hsl(171, 100%, 41%);
$info: hsl(217, 71%, 53%);
$success: hsl(141, 53%, 53%);
$warning: hsl(48, 100%, 67%);
$danger: hsl(348, 86%, 61%);
/* Typography Variables */
$family-sans-serif: BlinkMacSystemFont, -apple-system, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", "Helvetica", "Arial", sans-serif;
$family-monospace: monospace;
$render-mode: optimizeLegibility;
$size-1: 3rem;
$size-2: 2.5rem;
$size-3: 2rem;
$size-4: 1.5rem;
$size-5: 1.25rem;
$size-6: 1rem;
$size-7: 0.75rem;
$weight-light: 300;
$weight-normal: 400;
$weight-medium: 500;
$weight-semibold: 600;
$weight-bold: 700;
/* Spacing Variables */
$block-spacing: 1.5rem;
$gap: 32px;
$tablet: 769px;
$desktop: 1024px;
$widescreen: 1216px;
$fullhd: 1408px;
/* Component Variables */
$navbar-height: 3.25rem;
$navbar-padding-vertical: 1rem;
$navbar-padding-horizontal: 2rem;
$footer-background-color: hsl(0, 0%, 98%);
$footer-color: hsl(0, 0%, 29%);
$footer-padding: 3rem 1.5rem 6rem;
$box-color: hsl(0, 0%, 29%);
$box-background-color: hsl(0, 0%, 100%);
$box-radius: 6px;
$box-shadow: 0 0.5em 1em -0.125em hsla(0, 0%, 0%, 0.1), 0 0px 0 1px hsla(0, 0%, 0%, 0.02);
$box-padding: 1.25rem;
/* Control Variables */
$control-border-width: 1px;
$control-height: 2.5em;
$control-line-height: 1.5;
$control-padding-vertical: calc(0.5em - 1px);
$control-padding-horizontal: calc(0.75em - 1px);Runtime theming using CSS custom properties that can be changed dynamically.
/**
* CSS Custom Properties for runtime theming
*/
@use 'bulma/sass/utilities/css-variables';/* Core CSS Variables available for runtime theming */
:root {
/* Color scheme variables */
--bulma-scheme-h: 221;
--bulma-scheme-s: 14%;
--bulma-light-l: 90%;
--bulma-dark-l: 20%;
/* Primary color variables */
--bulma-primary-h: 171;
--bulma-primary-s: 100%;
--bulma-primary-l: 41%;
/* Component variables */
--bulma-navbar-height: 3.25rem;
--bulma-control-height: 2.5em;
--bulma-control-radius: 4px;
/* Typography variables */
--bulma-family-primary: Inter, SF Pro, Segoe UI, Roboto, sans-serif;
--bulma-size-1: 3rem;
--bulma-size-2: 2.5rem;
--bulma-size-3: 2rem;
/* Spacing variables */
--bulma-block-spacing: 1.5rem;
--bulma-gap: 32px;
}
/* Dark theme override */
[data-theme="dark"] {
--bulma-scheme-brightness: dark;
--bulma-scheme-main-l: 4%;
--bulma-background-l: 14%;
--bulma-text-l: 71%;
}
/* Custom theme example */
[data-theme="purple"] {
--bulma-primary-h: 271;
--bulma-primary-s: 100%;
--bulma-primary-l: 71%;
--bulma-info-h: 217;
--bulma-success-h: 141;
}Runtime Theme Switching:
// JavaScript for theme switching
function setTheme(theme) {
document.documentElement.setAttribute('data-theme', theme);
// Or directly modify CSS variables
const root = document.documentElement;
if (theme === 'dark') {
root.style.setProperty('--bulma-scheme-brightness', 'dark');
root.style.setProperty('--bulma-background-l', '14%');
root.style.setProperty('--bulma-text-l', '71%');
}
}
// Toggle dark mode
function toggleDarkMode() {
const current = document.documentElement.getAttribute('data-theme');
setTheme(current === 'dark' ? 'light' : 'dark');
}Add custom colors to Bulma's color system using the color merging function.
/**
* Custom color palette integration
*/
// Import Bulma functions
@use 'bulma/sass/utilities/functions';
// Define custom colors
$custom-colors: (
"purple": (
hsl(271, 100%, 71%),
hsl(271, 100%, 71%),
),
"pink": (
hsl(336, 100%, 78%),
hsl(336, 100%, 78%),
),
"twitter": (
hsl(206, 82%, 63%),
hsl(206, 82%, 63%),
),
"linkedin": (
hsl(203, 89%, 53%),
hsl(203, 89%, 53%),
),
);
// Merge with Bulma colors
$merged-colors: functions.mergeColorMaps($bulma-colors, $custom-colors);
// Override the colors variable
$colors: $merged-colors;
// Import Bulma
@import 'bulma/bulma.scss';Generated Custom Color Classes:
<!-- Custom color usage -->
<button class="button is-purple">Purple Button</button>
<button class="button is-pink">Pink Button</button>
<div class="notification is-twitter">Twitter notification</div>
<div class="has-background-linkedin has-text-white">LinkedIn background</div>
<!-- Light/dark variants automatically generated -->
<div class="has-background-purple-light">Light purple background</div>
<div class="has-text-pink-dark">Dark pink text</div>Import only the components you need for smaller bundle sizes.
/**
* Selective import approach
*/
// Always import utilities first
@use 'bulma/sass/utilities';
// Import base styles
@use 'bulma/sass/base';
// Import only needed elements
@use 'bulma/sass/elements/button';
@use 'bulma/sass/elements/box';
@use 'bulma/sass/elements/title';
// Import only needed components
@use 'bulma/sass/components/navbar';
@use 'bulma/sass/components/card';
// Import only needed layout
@use 'bulma/sass/layout/container';
@use 'bulma/sass/layout/section';
// Import only needed grid
@use 'bulma/sass/grid/columns';
// Import only needed helpers
@use 'bulma/sass/helpers/spacing';
@use 'bulma/sass/helpers/typography';
@use 'bulma/sass/helpers/color';Utility functions and mixins for extending Bulma's functionality.
/**
* Available Sass functions
*/
// Color functions
@function mergeColorMaps($bulma-colors, $custom-colors);
@function powerNumber($number, $exp);
@function colorLuminance($color);
@function findColorInvert($color);
@function findLightColor($color);
@function findDarkColor($color);
// Responsive mixins
@mixin mobile { /* Mobile styles */ }
@mixin tablet { /* Tablet and up styles */ }
@mixin tablet-only { /* Tablet only styles */ }
@mixin touch { /* Mobile and tablet styles */ }
@mixin desktop { /* Desktop and up styles */ }
@mixin desktop-only { /* Desktop only styles */ }
@mixin widescreen { /* Widescreen and up styles */ }
@mixin widescreen-only { /* Widescreen only styles */ }
@mixin fullhd { /* Full HD and up styles */ }
// Utility mixins
@mixin arrow($color: currentColor);
@mixin block($spacing: $block-spacing);
@mixin delete;
@mixin loader;
@mixin overlay($offset: 0);
@mixin placeholder;
@mixin unselectable;Using Mixins:
// Custom component with Bulma mixins
.my-component {
@include block; // Add consistent spacing
@include unselectable; // Make text unselectable
@include mobile {
font-size: 0.875rem;
}
@include desktop {
font-size: 1rem;
}
&::before {
@include arrow(#3273dc);
}
&.is-loading::after {
@include loader;
}
}
// Custom responsive behavior
.my-grid {
display: grid;
gap: 1rem;
@include mobile {
grid-template-columns: 1fr;
}
@include tablet {
grid-template-columns: repeat(2, 1fr);
}
@include desktop {
grid-template-columns: repeat(3, 1fr);
}
@include widescreen {
grid-template-columns: repeat(4, 1fr);
}
}Customize individual components by overriding their specific variables.
/**
* Component-specific customization
*/
// Button customization
$button-color: hsl(0, 0%, 29%);
$button-background-color: hsl(0, 0%, 100%);
$button-border-color: hsl(0, 0%, 86%);
$button-border-width: 1px;
$button-padding-vertical: calc(0.5em - 1px);
$button-padding-horizontal: 1em;
$button-focus-border-color: hsl(217, 71%, 53%);
$button-focus-box-shadow-size: 0 0 0 0.125em;
$button-focus-box-shadow-color: hsla(217, 71%, 53%, 0.25);
// Navbar customization
$navbar-background-color: hsl(0, 0%, 100%);
$navbar-box-shadow-size: 0 2px 0 0;
$navbar-box-shadow-color: hsl(0, 0%, 96%);
$navbar-height: 3.25rem;
$navbar-padding-vertical: 1rem;
$navbar-padding-horizontal: 2rem;
$navbar-z: 30;
$navbar-fixed-z: 30;
// Card customization
$card-color: hsl(0, 0%, 29%);
$card-background-color: hsl(0, 0%, 100%);
$card-shadow: 0 0.5em 1em -0.125em hsla(0, 0%, 0%, 0.1), 0 0px 0 1px hsla(0, 0%, 0%, 0.02);
$card-header-background-color: transparent;
$card-header-color: hsl(0, 0%, 29%);
$card-header-padding: 0.75rem 1rem;
$card-header-shadow: 0 0.125em 0.25em hsla(0, 0%, 0%, 0.1);
$card-header-weight: 700;
$card-content-background-color: transparent;
$card-content-padding: 1.5rem;
$card-footer-background-color: transparent;
$card-footer-border-top: 1px solid hsl(0, 0%, 93%);
$card-footer-padding: 0.75rem;
// Import after customization
@import 'bulma/bulma.scss';Use pre-built Bulma variants for specific use cases.
/**
* Available Bulma variants
*/
// No dark mode support (smaller file size)
@import 'bulma/versions/bulma-no-dark-mode.scss';
// No utility helpers (smaller file size)
@import 'bulma/versions/bulma-no-helpers.scss';
// All classes prefixed with 'bulma-'
@import 'bulma/versions/bulma-prefixed.scss';
// No helpers + prefixed classes
@import 'bulma/versions/bulma-no-helpers-prefixed.scss';Prefixed Version Usage:
<!-- Using prefixed version -->
<div class="bulma-container">
<h1 class="bulma-title">Prefixed Title</h1>
<button class="bulma-button bulma-is-primary">Prefixed Button</button>
<div class="bulma-columns">
<div class="bulma-column">Prefixed Column</div>
<div class="bulma-column">Another Column</div>
</div>
</div>Configure Sass compilation for optimal builds.
/**
* Production build configuration
*/
// Optimize for production
$production: true;
// Disable source maps in production
$include-source-maps: false;
// Minimize color palette (remove unused colors)
$colors: (
"primary": ($primary, $primary-invert),
"info": ($info, $info-invert),
"success": ($success, $success-invert),
"warning": ($warning, $warning-invert),
"danger": ($danger, $danger-invert),
);
// Remove unused size variants
$sizes: (
$size-1,
$size-3,
$size-5,
);
@import 'bulma/bulma.scss';// Complete customization example
$primary: #6366f1;
$success: #10b981;
$warning: #f59e0b;
$danger: #ef4444;
$family-sans-serif: "Inter", system-ui, sans-serif;
$radius: 8px;
$navbar-height: 4rem;
// Custom component
.my-hero {
@extend .hero;
@extend .is-primary;
background: linear-gradient(135deg, #{$primary} 0%, #{lighten($primary, 10%)} 100%);
.hero-body {
padding: 6rem 1.5rem;
@include tablet {
padding: 8rem 1.5rem;
}
}
}
@import 'bulma/bulma.scss';<!-- Using customized Bulma -->
<section class="my-hero">
<div class="hero-body">
<div class="container">
<h1 class="title has-text-white">Custom Hero</h1>
<h2 class="subtitle has-text-white-ter">With gradient background</h2>
<button class="button is-white is-outlined is-large">Get Started</button>
</div>
</div>
</section>