Bulma is a modern, CSS-only framework based on Flexbox and CSS Grid. You drop one stylesheet into your page, then build interfaces by adding classes to your HTML — no build step required, and no JavaScript of any kind is included. This guide shows you how to install Bulma and use every component, element, layout tool, and helper it ships, using the exact class names and values found in Bulma v1.0.4.
Note
Bulma styles your markup; it never adds behavior. Interactive widgets such as the navbar burger menu, modals, dropdowns, and the "delete" buttons rely on you toggling a class (usually
is-active) with your own JavaScript. This is by design — Bulma is "environment agnostic," a pure style layer you can pair with any framework (React, Vue, Svelte, Astro, plain HTML, etc.).
1. Quick Start
The fastest way to try Bulma is to link the prebuilt CSS from a CDN and start adding classes.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Bulma Quick Start</title>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/bulma@1.0.4/css/bulma.min.css"
/>
</head>
<body>
<section class="section">
<div class="container">
<h1 class="title">Hello, Bulma</h1>
<p class="subtitle">My first website with <strong>Bulma</strong>!</p>
<button class="button is-primary">Get started</button>
</div>
</section>
</body>
</html>
Open the file in a browser and you will see a styled heading, subtitle, and a turquoise primary button.
Tip
The
<meta name="viewport">tag is required for Bulma's responsive features (breakpoints, mobile columns, the navbar burger) to behave correctly on phones and tablets.
The three ideas you just used are the whole mental model of Bulma:
- Layout containers (
section,container) give your page structure and spacing. - Elements and components (
title,subtitle,button) are reusable building blocks. - Modifiers (
is-primary) change the appearance of a block. Modifiers almost always start withis-orhas-.
2. Installation
Bulma's only output is a single CSS file. Choose whichever delivery method fits your project.
CDN (no install)
Link the minified stylesheet directly. Best for prototypes and demos.
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/bulma@1.0.4/css/bulma.min.css"
/>
npm
npm install bulma
Then import the compiled CSS in your bundler entry point:
import "bulma/css/bulma.min.css";
Yarn
yarn add bulma
Download
Download a release and reference the file locally:
<link rel="stylesheet" href="css/bulma.min.css" />
The published npm package exposes these entry points (from package.json):
| Field | Value | Use it for |
|---|---|---|
main |
bulma.scss |
Sass @use/import of the source |
style |
css/bulma.min.css |
The minified compiled stylesheet |
unpkg |
css/bulma.css |
The expanded compiled stylesheet via unpkg |
Note
A
bower install bulmacommand also exists historically, but Bower is deprecated as a package manager. Prefer npm, Yarn, or the CDN.
Using the Sass source
If you want to customize Bulma (change the primary color, fonts, spacing, etc.) you install it via npm/Yarn and import the Sass source instead of the compiled CSS. Bulma uses the modern Dart Sass module system:
// Import all of Bulma
@use "bulma/sass";
Important
Bulma 1.0 requires Dart Sass (the
sassnpm package). The legacy Ruby Sass and Node Sass engines are not supported. Compile with a current Dart Sass version (Bulma is built and tested againstsass^1.97).
Customizing variables at build time is covered in the Customization section below and, in depth, in the Admin Guide.
3. How Modifiers Work
Bulma is built around two prefixes you will type constantly:
is-*— a state or variant of the block it sits on. Examples:is-primary,is-large,is-active,is-rounded,is-fullwidth.has-*— describes something the block has (usually a child arrangement or a typographic property). Examples:has-text-centered,has-addons,has-icons-left,has-background-light.
Modifiers stack. A single button can carry several at once:
<button class="button is-primary is-large is-rounded is-fullwidth">
Big rounded full-width primary button
</button>
The seven semantic colors appear everywhere as is-<color> modifiers:
| Color | Default hue | Typical meaning |
|---|---|---|
is-primary |
turquoise | Your brand / main action |
is-link |
blue | Links and secondary actions |
is-info |
cyan | Informational notices |
is-success |
green | Positive outcomes |
is-warning |
yellow | Caution |
is-danger |
red | Errors and destructive actions |
is-light / is-dark |
greys | Neutral light/dark tones |
Tip
Almost every component (button, tag, notification, message, navbar, hero, panel, progress, table, input) accepts these same color modifiers. Learn them once and reuse them everywhere.
4. Layout
Layout classes give your page its overall skeleton.
Container
.container centers your content and caps its width at each breakpoint. It is the wrapper you put inside full-width bands like section, hero, or navbar.
<div class="container">
<!-- Centered, width-limited content -->
</div>
| Modifier | Effect |
|---|---|
is-fluid |
Full width with a small (32px) gutter on each side; never capped |
is-widescreen |
Stays full width until the widescreen breakpoint, then caps |
is-fullhd |
Stays full width until the fullhd breakpoint, then caps |
is-max-tablet |
Caps at the tablet width |
is-max-desktop |
Caps at the desktop width |
is-max-widescreen |
Caps at the widescreen width |
Section
.section is a full-width band with generous vertical padding — the standard way to space major page regions.
<section class="section">
<div class="container">…</div>
</section>
Modifiers: is-medium and is-large add progressively more padding (on desktop and up). is-fullheight makes the section at least 100vh tall.
Hero
A .hero is an imposing full-width banner. It can carry a color, a size, and optional header/footer slots.
<section class="hero is-primary is-bold">
<div class="hero-body">
<p class="title">Primary hero</p>
<p class="subtitle">A bold gradient banner</p>
</div>
</section>
Hero anatomy and modifiers:
| Class / modifier | Purpose |
|---|---|
hero-head |
Top slot (often a navbar) — does not stretch |
hero-body |
Main content — stretches to fill |
hero-foot |
Bottom slot (often tabs) — does not stretch |
is-<color> |
Colors the banner (any of the seven colors) |
is-bold |
Adds a diagonal gradient based on the color |
is-small / is-medium / is-large |
Increases body padding |
is-halfheight |
At least 50vh tall, body vertically centered |
is-fullheight |
At least 100vh tall, body vertically centered |
is-fullheight-with-navbar |
100vh minus the navbar height |
hero-video |
Full-bleed background video layer (is-transparent dims it) |
hero-buttons |
Spaced button row inside the hero |
Level
.level lays items out horizontally with equal vertical centering — ideal for toolbars and stat bars. Use level-left and level-right to pin items to each edge, and level-item for each cell.
<nav class="level">
<div class="level-left">
<div class="level-item"><p class="subtitle is-5"><strong>123</strong> posts</p></div>
<div class="level-item">
<div class="field has-addons">
<p class="control"><input class="input" type="text" placeholder="Find a post" /></p>
<p class="control"><button class="button">Search</button></p>
</div>
</div>
</div>
<div class="level-right">
<p class="level-item"><strong>All</strong></p>
<p class="level-item"><a>Published</a></p>
<p class="level-item"><a class="button is-success">New</a></p>
</div>
</nav>
The level stacks vertically on mobile by default. Add is-mobile to keep it horizontal on small screens.
Media object
.media is the classic avatar-beside-content pattern (comments, tweets, notifications). It nests for threaded replies.
<article class="media">
<figure class="media-left">
<p class="image is-64x64"><img src="avatar.png" alt="" /></p>
</figure>
<div class="media-content">
<div class="content"><p><strong>Jane Doe</strong> <small>@jane</small><br />Great post!</p></div>
</div>
<div class="media-right"><button class="delete"></button></div>
</article>
Footer
.footer is a padded band with a subtle background, meant for the bottom of the page.
<footer class="footer">
<div class="content has-text-centered">
<p>Built with <strong>Bulma</strong>.</p>
</div>
</footer>
5. Columns
Bulma's original responsive grid is a Flexbox system: a .columns wrapper with one or more .column children. By default every column shares the available width equally.
<div class="columns">
<div class="column">First</div>
<div class="column">Second</div>
<div class="column">Third</div>
</div>
Sizing a column
Add a sizing modifier to any .column to fix its width. The grid is 12 units wide.
| Fraction modifiers | Numeric modifiers |
|---|---|
is-full, is-half, is-one-third, is-two-thirds |
is-1 … is-12 |
is-one-quarter, is-three-quarters |
(each = N/12 of the row) |
is-one-fifth, is-two-fifths, is-three-fifths, is-four-fifths |
|
is-narrow (only as wide as its content) |
<div class="columns">
<div class="column is-half">Half width</div>
<div class="column">Fills the rest</div>
</div>
Offsetting
is-offset-* pushes a column to the right by the matching amount, e.g. is-offset-one-quarter, is-offset-4.
<div class="columns">
<div class="column is-half is-offset-one-quarter">Centered half-width column</div>
</div>
Caution
In
v1.0.4theis-offset-one-thirdmodifier (and its responsive variants-mobile,-tablet,-touch,-desktop,-widescreen) applies an offset of0.3333%instead of the intended33.3333%. This is a known bug (GitHub issue #4044). Theis-offset-one-third-fullhdvariant is correct. As a workaround, useis-offset-4(which equals one third of the 12-unit grid) until it is fixed upstream.
Responsive columns
Append a breakpoint suffix to apply a size only at that breakpoint and up: -mobile, -tablet, -touch, -desktop, -widescreen, -fullhd. By default columns are only side-by-side from tablet upward and stack on mobile.
<div class="columns is-mobile">
<div class="column is-half-mobile is-one-quarter-desktop">Responsive</div>
<div class="column">…</div>
</div>
.columns modifiers
| Modifier | Effect |
|---|---|
is-mobile |
Keep columns side-by-side even on mobile |
is-desktop |
Only become side-by-side from desktop up |
is-centered |
Center the columns horizontally |
is-vcentered |
Vertically center columns of unequal height |
is-multiline |
Allow columns to wrap onto multiple lines |
is-gapless |
Remove the gutter between columns |
is-0 … is-8 |
Set the gutter size (each step ≈ 0.25rem); also responsive (e.g. is-2-desktop) |
6. Smart Grid
New in Bulma 1.0, the Smart Grid is a CSS Grid layout that places as many equal cells per row as will fit, with no column-counting required.
<div class="grid">
<div class="cell">Cell 1</div>
<div class="cell">Cell 2</div>
<div class="cell">Cell 3</div>
<!-- as many cells as you like -->
</div>
By default each cell is at least 9rem wide and the grid fits as many columns as possible. Tune the minimum cell width with is-col-min-1 … is-col-min-32 (each step = 1.5rem):
<div class="grid is-col-min-12">…</div>
Fixed grid
Wrap a .grid in a .fixed-grid to pin an exact number of columns, and make that count responsive.
<div class="fixed-grid has-4-cols">
<div class="grid">
<div class="cell">1</div>
<div class="cell">2</div>
<div class="cell">3</div>
<div class="cell">4</div>
</div>
</div>
Modifier (on .fixed-grid) |
Effect |
|---|---|
has-1-cols … has-12-cols |
Fix the column count |
has-<n>-cols-mobile, -tablet, -desktop, -widescreen, -fullhd |
Set the count per breakpoint |
has-auto-count |
Auto-scale the count: 2 (mobile) → 4 → 8 → 12 → 16 (fullhd) |
Spanning cells
Apply these to any .cell to make it occupy more than one track:
| Modifier | Effect |
|---|---|
is-col-span-<n> |
Span N columns |
is-row-span-<n> |
Span N rows |
is-col-start-<n> / is-col-from-end-<n> / is-col-start-end |
Pin the starting column |
is-row-start-<n> / is-row-from-end-<n> / is-row-start-end |
Pin the starting row |
All span/start modifiers also accept breakpoint suffixes (e.g. is-col-span-2-desktop).
7. Elements
Elements are the single-purpose building blocks of Bulma.
Button
<button class="button">Default</button>
<button class="button is-primary">Primary</button>
<a class="button is-link is-light">Light link</a>
Buttons support a rich modifier set:
| Category | Modifiers |
|---|---|
| Colors | is-white, is-black, is-light, is-dark, is-primary, is-link, is-info, is-success, is-warning, is-danger |
| Color shades | is-light, is-dark, is-soft, is-bold (combine with a color, e.g. is-primary is-soft) |
| Styles | is-outlined, is-inverted, is-text, is-ghost |
| Sizes | is-small, is-normal, is-medium, is-large |
| Responsive size | is-responsive (font scales with the viewport) |
| States | is-hovered, is-focused, is-active, is-loading, is-static, [disabled] |
| Layout | is-fullwidth, is-rounded |
<button class="button is-success is-loading">Saving…</button>
<button class="button is-danger is-outlined">Delete</button>
Group buttons with the .buttons container. Add has-addons to join them seamlessly, or are-small / are-medium / are-large to size all children at once:
<div class="buttons has-addons">
<button class="button is-success is-selected">Yes</button>
<button class="button">Maybe</button>
<button class="button">No</button>
</div>
Tag
Small labels for counts, categories, and statuses.
<span class="tag is-primary">New</span>
<span class="tag is-danger is-light">3 errors</span>
Modifiers: any color (+ is-light), sizes is-normal / is-medium / is-large, is-rounded, and is-delete (renders a tiny ✕ button). Group with .tags, which also supports has-addons, are-medium, are-large, is-centered, and is-right.
<div class="tags has-addons">
<span class="tag is-dark">npm</span>
<span class="tag is-info">1.0.4</span>
</div>
Title and subtitle
Bold headings independent of the HTML heading level.
<h1 class="title">Page title</h1>
<h2 class="subtitle">A supporting subtitle</h2>
Use is-1 (largest, 3rem) through is-6 for titles and subtitles. When a title is immediately followed by a subtitle, the gap between them is automatically tightened; add is-spaced to keep the full margin.
Box
A simple white container with rounded corners and a shadow.
<div class="box">
<p>Anything can go in a box.</p>
</div>
Notification
A colored block of text, often with a dismiss button.
<div class="notification is-warning">
<button class="delete"></button>
Your trial expires in 3 days.
</div>
Accepts any color plus is-light / is-dark.
Content
.content styles a region of raw HTML (headings, paragraphs, lists, blockquotes, tables, code) so you do not have to add a class to every tag — perfect for rendered Markdown or CMS output.
<div class="content">
<h2>A heading</h2>
<p>Paragraph text with a <a href="#">link</a>.</p>
<ul><li>First</li><li>Second</li></ul>
</div>
Ordered-list style modifiers: is-lower-alpha, is-lower-roman, is-upper-alpha, is-upper-roman. Sizes: is-small … is-large.
Image
A responsive image wrapper that can enforce a fixed dimension or aspect ratio.
<figure class="image is-128x128">
<img src="photo.png" alt="" />
</figure>
| Modifier | Effect |
|---|---|
is-16x16 … is-128x128 |
Fixed square dimensions (16, 24, 32, 48, 64, 96, 128) |
is-square, is-1by1, is-4by3, is-16by9, is-3by2, is-2by1, … |
Fixed aspect ratio (15 ratios available) |
is-fullwidth |
Stretch to the container width |
(on the <img>) is-rounded |
Circular image |
Icon and icon-text
Bulma reserves space for an icon font (e.g. Font Awesome); it does not ship icons.
<span class="icon"><i class="fas fa-home"></i></span>
<span class="icon-text">
<span class="icon"><i class="fas fa-train"></i></span>
<span>Departing now</span>
</span>
Icon sizes: is-small, is-medium, is-large.
Table
<table class="table is-striped is-hoverable is-fullwidth">
<thead><tr><th>Name</th><th>Role</th></tr></thead>
<tbody>
<tr><td>Ada</td><td>Engineer</td></tr>
<tr class="is-selected"><td>Grace</td><td>Admiral</td></tr>
</tbody>
</table>
Modifiers: is-bordered, is-striped, is-hoverable, is-fullwidth, is-narrow. Cells and rows accept color modifiers and is-selected. Wrap a wide table in .table-container to make it scroll horizontally on small screens.
Progress
<progress class="progress is-success" value="60" max="100">60%</progress>
<progress class="progress is-small is-info" max="100">Loading</progress>
Omit the value attribute to get an animated indeterminate bar. Colors and sizes (is-small … is-large) are supported.
Delete and loader
.delete— a standalone circular ✕ button (is-small,is-medium,is-large)..loader— a spinning circle you can drop anywhere.
Skeletons
Loading placeholders. Add is-skeleton to an element to show a pulsing block while data loads, use .skeleton-block for a solid block, or .skeleton-lines (with child <div>s) for faked text lines.
<div class="skeleton-lines">
<div></div><div></div><div></div>
</div>
8. Components
Components are larger, multi-part patterns.
Navbar
A responsive navigation bar. On small screens it collapses behind a "burger" toggle.
<nav class="navbar" role="navigation" aria-label="main navigation">
<div class="navbar-brand">
<a class="navbar-item" href="/">Logo</a>
<a role="button" class="navbar-burger" aria-label="menu" aria-expanded="false" data-target="mainNav">
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
</a>
</div>
<div id="mainNav" class="navbar-menu">
<div class="navbar-start">
<a class="navbar-item">Home</a>
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link">More</a>
<div class="navbar-dropdown">
<a class="navbar-item">About</a>
<hr class="navbar-divider" />
<a class="navbar-item">Contact</a>
</div>
</div>
</div>
<div class="navbar-end">
<div class="navbar-item">
<div class="buttons">
<a class="button is-primary"><strong>Sign up</strong></a>
<a class="button is-light">Log in</a>
</div>
</div>
</div>
</div>
</nav>
Important
Opening the burger menu requires JavaScript: toggle the
is-activeclass on both the.navbar-burgerand the target.navbar-menu. Bulma styles both states but does not wire up the click.
Navbar modifiers and parts:
| Class / modifier | Purpose |
|---|---|
navbar-brand, navbar-menu, navbar-start, navbar-end |
Structural slots |
navbar-item, navbar-link, navbar-dropdown, navbar-divider |
Items and dropdowns |
is-<color> |
Color the whole bar |
has-shadow |
Bottom shadow |
is-transparent |
Remove item hover/active backgrounds |
is-spaced |
Extra padding (pairs well with boxed dropdowns) |
is-fixed-top, is-fixed-bottom |
Pin the bar (add has-navbar-fixed-top/-bottom to <html>) |
is-hoverable (on a dropdown item) |
Open the dropdown on hover |
has-dropdown-up, is-right, is-boxed (on dropdowns) |
Direction and style |
Card
<div class="card">
<div class="card-image">
<figure class="image is-4by3"><img src="cover.png" alt="" /></figure>
</div>
<div class="card-content">
<p class="title is-4">Card title</p>
<p class="subtitle is-6">Subtitle</p>
<div class="content">Body text.</div>
</div>
<footer class="card-footer">
<a class="card-footer-item">Save</a>
<a class="card-footer-item">Share</a>
</footer>
</div>
Parts: card-header, card-header-title, card-header-icon, card-image, card-content, card-footer, card-footer-item.
Modal
<div class="modal is-active">
<div class="modal-background"></div>
<div class="modal-content">
<div class="box">Hello from a modal.</div>
</div>
<button class="modal-close is-large" aria-label="close"></button>
</div>
Add or remove is-active to show or hide it (with your own JavaScript). For a structured dialog use the card variant:
<div class="modal is-active">
<div class="modal-background"></div>
<div class="modal-card">
<header class="modal-card-head">
<p class="modal-card-title">Confirm</p>
<button class="delete" aria-label="close"></button>
</header>
<section class="modal-card-body">Are you sure?</section>
<footer class="modal-card-foot">
<button class="button is-success">Save</button>
<button class="button">Cancel</button>
</footer>
</div>
</div>
Dropdown
<div class="dropdown is-active">
<div class="dropdown-trigger">
<button class="button" aria-haspopup="true" aria-controls="menu">
<span>Menu</span>
<span class="icon is-small"><i class="fas fa-angle-down"></i></span>
</button>
</div>
<div class="dropdown-menu" id="menu" role="menu">
<div class="dropdown-content">
<a class="dropdown-item">Item</a>
<a class="dropdown-item is-active">Selected item</a>
<hr class="dropdown-divider" />
<a class="dropdown-item">Other item</a>
</div>
</div>
</div>
Modifiers: is-active (show), is-hoverable (open on hover, no JS), is-right (align right), is-up (open upward).
Menu
A vertical menu, ideal for sidebars.
<aside class="menu">
<p class="menu-label">General</p>
<ul class="menu-list">
<li><a class="is-active">Dashboard</a></li>
<li><a>Customers</a></li>
</ul>
<p class="menu-label">Administration</p>
<ul class="menu-list">
<li><a>Settings</a></li>
</ul>
</aside>
Message
A colored block with an optional header.
<article class="message is-info">
<div class="message-header">
<p>Heads up</p>
<button class="delete" aria-label="delete"></button>
</div>
<div class="message-body">Here is some helpful information.</div>
</article>
Accepts any color and sizes is-small … is-large.
Pagination
<nav class="pagination is-centered" role="navigation" aria-label="pagination">
<a class="pagination-previous">Previous</a>
<a class="pagination-next">Next</a>
<ul class="pagination-list">
<li><a class="pagination-link">1</a></li>
<li><span class="pagination-ellipsis">…</span></li>
<li><a class="pagination-link is-current" aria-current="page">3</a></li>
<li><a class="pagination-link">4</a></li>
</ul>
</nav>
Modifiers: is-centered, is-right, is-rounded, and sizes is-small … is-large.
Panel
A composite box with a heading, optional filter tabs, and clickable blocks.
<nav class="panel">
<p class="panel-heading">Repositories</p>
<p class="panel-tabs"><a class="is-active">All</a><a>Public</a><a>Private</a></p>
<a class="panel-block is-active">
<span class="panel-icon"><i class="fas fa-book"></i></span>
bulma
</a>
<a class="panel-block">
<span class="panel-icon"><i class="fas fa-book"></i></span>
marksheet
</a>
</nav>
The panel heading takes any color (is-primary, etc.).
Tabs
<div class="tabs is-boxed is-centered">
<ul>
<li class="is-active"><a>Overview</a></li>
<li><a>Details</a></li>
<li><a>Reviews</a></li>
</ul>
</div>
Style modifiers: is-boxed, is-toggle, is-toggle-rounded, is-fullwidth. Alignment: is-centered, is-right. Sizes: is-small … is-large.
Breadcrumb
<nav class="breadcrumb has-arrow-separator" aria-label="breadcrumbs">
<ul>
<li><a href="#">Home</a></li>
<li><a href="#">Docs</a></li>
<li class="is-active"><a aria-current="page">Components</a></li>
</ul>
</nav>
Separators: has-arrow-separator, has-bullet-separator, has-dot-separator, has-succeeds-separator. Alignment: is-centered, is-right. Sizes available too.
9. Form Controls
Bulma styles form fields through a small set of classes. Each input lives inside a .control, which lives inside a .field.
<div class="field">
<label class="label">Email</label>
<div class="control has-icons-left">
<input class="input" type="email" placeholder="[email removed]" />
<span class="icon is-small is-left"><i class="fas fa-envelope"></i></span>
</div>
<p class="help">We never share your email.</p>
</div>
Inputs and textareas
<input class="input is-primary" type="text" placeholder="Primary" />
<input class="input is-rounded" type="text" placeholder="Rounded" />
<textarea class="textarea has-fixed-size" placeholder="Fixed size"></textarea>
Modifiers: any color, sizes is-small … is-large, states is-hovered/is-focused/is-active, is-rounded (inputs), is-static (read-only display), has-fixed-size (textarea).
Select
<div class="select is-multiple">
<select multiple size="3">
<option>One</option>
<option>Two</option>
</select>
</div>
Modifiers: colors, sizes, is-rounded, is-loading, is-multiple, is-fullwidth.
Checkbox and radio
<label class="checkbox"><input type="checkbox" /> I agree</label>
<label class="radio"><input type="radio" name="x" /> Yes</label>
<label class="radio"><input type="radio" name="x" /> No</label>
Wrap several in .checkboxes or .radios to space them in a flex row.
File upload
<div class="file has-name is-boxed is-primary">
<label class="file-label">
<input class="file-input" type="file" name="resume" />
<span class="file-cta">
<span class="file-icon"><i class="fas fa-upload"></i></span>
<span class="file-label">Choose a file…</span>
</span>
<span class="file-name">No file selected</span>
</label>
</div>
Modifiers: colors, sizes, has-name, is-boxed, is-right, is-centered, is-fullwidth.
Field grouping
| Class / modifier | Effect |
|---|---|
field has-addons |
Attach controls together (input + button) |
has-addons-centered, has-addons-right, has-addons-fullwidth |
Align/stretch the addon group |
field is-grouped |
Space controls in a row |
is-grouped-centered, is-grouped-right, is-grouped-multiline |
Align/wrap the group |
field is-horizontal (+ field-label, field-body) |
Label beside the inputs (from tablet) |
control is-expanded |
Make a control fill remaining space |
control has-icons-left / has-icons-right |
Reserve space for icons |
control is-loading |
Show a spinner inside the control |
10. Helpers
Helpers are single-property utility classes (most use !important) for quick, one-off tweaks.
Color helpers
<p class="has-text-primary">Primary text</p>
<div class="has-background-light">Light background</div>
- Text:
has-text-<color>for every color and shade name. - Background:
has-background-<color>. - Variants per color:
-invert,-light,-dark,-soft,-bold,-on-scheme, and numeric shades-00through-100in steps of 5 (e.g.has-text-primary-25). has-text-current,has-text-inherit,has-background-current,has-background-inherit.
Spacing helpers
The most-used helpers. The pattern is {property}{direction}-{size}:
- Property:
m= margin,p= padding. - Direction:
ttop,rright,bbottom,lleft,xleft+right,ytop+bottom, or omit for all sides. - Size:
0,1(0.25rem),2(0.5rem),3(0.75rem),4(1rem),5(1.5rem),6(3rem), orauto.
<div class="mt-4 px-2 mb-0">Margin-top 1rem, padding-x 0.5rem, no margin-bottom</div>
Typography helpers
| Group | Classes |
|---|---|
| Size | is-size-1 … is-size-7 (plus per-breakpoint, e.g. is-size-3-desktop) |
| Alignment | has-text-centered, has-text-justified, has-text-left, has-text-right (+ per-breakpoint) |
| Transform | is-capitalized, is-lowercase, is-uppercase, is-italic, is-underlined |
| Weight | has-text-weight-light / -normal / -medium / -semibold / -bold / -extrabold |
| Family | is-family-primary / -secondary / -sans-serif / -monospace / -code |
Visibility helpers
<div class="is-hidden-mobile">Hidden on phones</div>
<div class="is-flex is-justify-content-center">Centered flex row</div>
- Display:
is-block,is-flex,is-inline,is-inline-block,is-inline-flex,is-grid(+ per-breakpoint). - Hide:
is-hidden(+ per-breakpoint, e.g.is-hidden-tablet). - Other:
is-invisible,is-sr-only(visible only to screen readers).
Flexbox helpers
When an element is is-flex, control its layout directly: is-flex-direction-*, is-flex-wrap-*, is-justify-content-*, is-align-items-*, is-align-content-*, is-align-self-*, and is-flex-grow-0…5 / is-flex-shrink-0…5.
Other helpers
is-clearfix, is-pulled-left, is-pulled-right, is-clipped, is-overlay, is-clickable, is-relative, is-marginless, is-paddingless, is-radiusless, is-shadowless, is-unselectable, has-radius-small/-normal/-large/-rounded, the gap helpers is-gap-0…8 (and is-column-gap-*, is-row-gap-*), is-gapless, position helpers (is-position-absolute, etc.), overflow helpers (is-overflow-hidden, etc.), and aspect-ratio helpers (is-aspect-ratio-16by9, etc.).
11. Colors, Themes & Dark Mode
Light and dark themes
Bulma ships a light theme (default) and a dark theme. It respects the operating system preference automatically via prefers-color-scheme. You can also force a theme by adding an attribute or class to any container (most often <html>):
<html data-theme="dark">…</html>
<!-- or -->
<div class="theme-dark">…this subtree is dark…</div>
The accepted values are data-theme="light" / data-theme="dark" and the classes theme-light / theme-dark.
Tip
Because theming is driven by CSS custom properties, you can flip themes at runtime with one line of JavaScript:
document.documentElement.dataset.theme = "dark". No stylesheet reload is needed.
Runtime customization with CSS variables
Every Bulma value is exposed as a CSS custom property prefixed with --bulma-. To restyle Bulma without recompiling Sass, override the variable in your own stylesheet:
:root {
--bulma-primary-h: 270deg; /* shift the primary hue to purple */
--bulma-link-h: 210deg;
--bulma-radius: 1rem; /* rounder corners everywhere */
}
Scoped overrides work too — set variables on any selector and they cascade to that subtree only.
Build-time customization with Sass
For deeper changes, compile from source and pass overrides through the module system:
@use "bulma/sass" with (
$primary: #6c5ce7,
$family-primary: '"Nunito", sans-serif',
$radius: 0.5rem
);
The full list of overridable Sass variables and CSS custom properties is in the Admin Guide.
12. Responsiveness
Bulma is mobile-first. These are the breakpoints (all driven by the $gap value of 32px):
| Name | Range |
|---|---|
mobile |
up to 768px |
tablet |
769px and up |
tablet-only |
769px – 1023px |
touch |
up to 1023px (mobile + tablet) |
desktop |
1024px and up |
desktop-only |
1024px – 1215px |
widescreen |
1216px and up |
widescreen-only |
1216px – 1407px |
fullhd |
1408px and up |
Most responsive features (columns, typography sizes, text alignment, visibility, the navbar) use these names as class suffixes, e.g. is-hidden-touch, has-text-centered-mobile, column is-half-desktop.
13. How It Works (Concepts)
You do not need this section to use Bulma, but it explains why things behave the way they do.
- CSS only. Bulma compiles to a single stylesheet. There is no JavaScript, no runtime, and no dependencies in the published package. Interactivity is yours to add.
- CSS custom properties everywhere. Bulma 1.0 registers hundreds of
--bulma-*variables and builds its rules from them. That is what makes runtime theming, dark mode, and per-subtree overrides possible without recompiling. - HSL color math. Colors are stored as separate hue/saturation/lightness variables (e.g.
--bulma-primary-h,--bulma-primary-s,--bulma-primary-l). Bulma derives an entire accessible palette — light, dark, soft, bold, inverted, and 20 numbered shades — from each base color, choosing readable text/background pairings automatically. - Flexbox and CSS Grid. The
columnssystem is Flexbox; thegrid/cellSmart Grid is CSS Grid. Both are responsive by default. - Logical properties. Bulma uses
margin-inline,inset-inline, and similar logical properties, which gives it partial right-to-left language support.
14. Troubleshooting
Error: --bulma-block-spacing is undefined
Cause: Some components read --bulma-block-spacing, but it is not registered globally in every context (GitHub issue #4037), so spacing between blocks can collapse.
Solution: Define it yourself: :root { --bulma-block-spacing: 1.5rem; }.
Prevention: When you override spacing variables, set them on :root so every component can read them.
Problem: My navbar burger / modal / dropdown does nothing when clicked
Cause: Bulma ships no JavaScript. The collapsed/open states are styled but not toggled.
Solution: Add a click handler that toggles is-active (on the burger and its target menu for the navbar; on the .modal; on the .dropdown).
Prevention: Treat every "open/close" interaction as something you wire up. Alternatively, use is-hoverable on dropdowns and navbar items for a CSS-only open-on-hover.
Problem: is-offset-one-third barely moves my column
Cause: A bug in v1.0.4 where this modifier offsets by 0.3333% instead of 33.3333% (GitHub issue #4044).
Solution: Use is-offset-4 instead (4/12 of the grid = one third).
Prevention: Prefer numeric offsets (is-offset-4, is-offset-8) which are computed and reliable.
Problem: Columns are stacked when I expected them side by side
Cause: By default .columns only becomes horizontal from the tablet breakpoint up; on mobile the columns stack.
Solution: Add is-mobile to the .columns element to keep them side-by-side on phones.
Prevention: Decide per layout whether columns should ever stack; reach for is-mobile or the per-breakpoint size modifiers (is-half-mobile).
Problem: My Sass build fails with @use / module errors
Cause: You are compiling with the legacy Ruby Sass or Node Sass engine, which Bulma 1.0 does not support.
Solution: Install and use Dart Sass (npm install sass) and compile with it.
Prevention: Pin sass (Dart Sass) in your project and avoid node-sass.
Problem: The CSS file feels very large
Cause: Bulma 1.0 emits a comprehensive set of CSS custom properties and helper classes, so even minified the file is sizable (GitHub issue #3761).
Solution: Import only the modules you use from the Sass source, or use the prebuilt bulma-no-helpers variant; then minify and let your server gzip/brotli the output (compresses extremely well).
Prevention: Build from Sass and @forward only the parts of sass/ you need.
Problem: Icons do not appear inside .icon
Cause: Bulma reserves space for an icon but ships no icon font.
Solution: Include an icon library (e.g. Font Awesome) and place its markup inside the .icon element.
Prevention: Add your icon font's stylesheet alongside Bulma.
Problem: A .tile layout from an old tutorial does nothing
Cause: The tile component was removed in Bulma 1.0.
Solution: Rebuild the layout with the Smart Grid (fixed-grid + grid + cell) or with columns.
Prevention: Follow v1.0.x documentation; older guides reference removed features.
15. FAQ
Q: Does Bulma include any JavaScript? No. Bulma is purely CSS. Any interactive behavior (menus, modals, dropdowns, dismissing notifications) is something you implement, or you pull in a third-party Bulma-JS helper library.
Q: Which browsers are supported? Recent versions of Chrome, Edge, Firefox, Opera, and Safari. Internet Explorer 10+ is only partially supported. Bulma relies on Flexbox and CSS Grid.
Q: Do I have to use Sass?
No. The compiled css/bulma.css (or .min.css) works as-is. Sass is only needed for build-time customization; runtime customization is possible purely through CSS variables.
Q: How do I change the primary color?
Quickest: override --bulma-primary-h/s/l in your own CSS. For a full rebuild: @use "bulma/sass" with ($primary: #yourcolor).
Q: How do I enable dark mode?
It follows the OS setting automatically. To force it, set data-theme="dark" (or class theme-dark) on a container such as <html>.
Q: Can I prefix every Bulma class to avoid collisions?
Yes. Compile with @use "bulma/sass" with ($class-prefix: "bulma-"), which turns .button into .bulma-button. A prebuilt bulma-prefixed stylesheet ships with the package.
Q: What is the difference between columns and the new grid?
columns is a 12-unit Flexbox grid where you size each column explicitly. The Smart grid is CSS Grid that auto-fits as many equal cells as fit; use fixed-grid when you want an exact, responsive column count.
Q: How do I make a button full width?
Add is-fullwidth: <button class="button is-primary is-fullwidth">.
Q: How do I center content horizontally?
Wrap it in a .container, or use helpers like has-text-centered, is-flex is-justify-content-center, or columns is-centered.
Q: My colors look washed out / wrong in dark mode. Why?
Bulma recomputes accessible text/background pairings per theme. If you hard-code a hex color instead of using a Bulma color class, it will not adapt. Prefer has-text-* / has-background-* or the --bulma-* variables.
Q: Where do I set fonts?
Override --bulma-family-primary in CSS, or $family-primary in Sass. The defaults are an Inter-led sans-serif stack and an Inconsolata-led monospace stack.
Q: Is right-to-left (RTL) supported?
Partially. Bulma uses logical CSS properties throughout, and the Sass source has an $rtl flag. Full RTL is not a turnkey feature in v1.0.4.
Q: How big is the compiled stylesheet?
In v1.0.4 the expanded bulma.css is about 785 KB and the minified bulma.min.css about 678 KB; both compress dramatically with gzip/brotli. Trim further by building only the modules you use.
Q: How do I add custom colors?
Pass a $custom-colors map when you @use "bulma/sass". Each entry becomes a full is-<name> palette across components and helpers.
16. Class Reference
A quick index of the most common classes by area.
| Area | Key classes |
|---|---|
| Layout | container, section, hero (+hero-body), level, media, footer |
| Columns | columns, column, is-half, is-1…is-12, is-offset-*, is-mobile |
| Smart grid | fixed-grid, grid, cell, has-<n>-cols, is-col-span-* |
| Buttons | button, buttons, is-primary, is-outlined, is-loading, is-rounded |
| Text blocks | title, subtitle, content, box, notification, tag, tags |
| Media | image, is-128x128, is-16by9, icon, icon-text, table, progress |
| Components | navbar, card, modal, dropdown, menu, message, pagination, panel, tabs, breadcrumb |
| Forms | field, control, input, textarea, select, checkbox, radio, file, label, help |
| Color helpers | has-text-<color>, has-background-<color> (+ -light/-dark/-soft/-bold/-invert/-00…-100) |
| Spacing helpers | m*-{0..6,auto}, p*-{0..6,auto} (directions t r b l x y) |
| Typography helpers | is-size-1…7, has-text-centered, has-text-weight-bold, is-uppercase |
| Visibility helpers | is-hidden, is-block, is-flex, is-invisible, is-sr-only (+ per-breakpoint) |
| Theming | data-theme="dark", theme-dark, --bulma-* CSS variables |