Introduction: What is Bulma and Why Use It?
Bulma is a free, open-source CSS framework based on Flexbox that provides ready-to-use frontend components. Created by Jeremy Thomas in 2016, Bulma offers a modern, responsive design system without any JavaScript dependencies. Its lightweight nature (only ~200KB minified), modular structure, and intuitive class naming make it an excellent choice for rapid development of responsive websites and applications.
Key advantages:
- 100% responsive and mobile-first
- Modular architecture (import only what you need)
- Pure CSS (no JavaScript dependencies)
- Readable, human-friendly naming conventions
- Active community and regular updates
- Modern Flexbox-based grid system
Core Concepts & Structure
Installation Options
Method | Command/Link | Notes |
---|---|---|
NPM | npm install bulma | Recommended for most projects |
CDN | <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.4/css/bulma.min.css"> | Quick setup without installation |
Download | bulma.io/download | For offline development |
Starter Templates | bulma.io/templates | Pre-built templates to jumpstart projects |
Modular Import Structure
For optimized builds, import only the components you need:
// Import specific Bulma components
@import "bulma/sass/utilities/_all.sass";
@import "bulma/sass/base/_all.sass";
@import "bulma/sass/elements/button.sass";
@import "bulma/sass/components/navbar.sass";
// etc.
Bulma’s File Structure
bulma/
├── css/
│ ├── bulma.css
│ └── bulma.min.css
└── sass/
├── base/
├── components/
├── elements/
├── form/
├── grid/
├── helpers/
├── layout/
└── utilities/
Responsive Design System
Viewport Breakpoints
Breakpoint Name | Width | Class Prefix | Usage |
---|---|---|---|
Mobile | < 768px | is-* (default) | Base styling |
Tablet | ≥ 769px | is-*-tablet | Tablet-specific styles |
Desktop | ≥ 1024px | is-*-desktop | Desktop-specific styles |
Widescreen | ≥ 1216px | is-*-widescreen | Widescreen-specific styles |
Fullhd | ≥ 1408px | is-*-fullhd | Full HD-specific styles |
Example: is-half-mobile is-one-third-tablet is-one-quarter-desktop
Visibility Helpers
Class | Effect |
---|---|
is-hidden-mobile | Hidden on mobile only |
is-hidden-tablet-only | Hidden on tablet only |
is-hidden-desktop-only | Hidden on desktop only |
is-hidden-widescreen-only | Hidden on widescreen only |
is-hidden-touch | Hidden on mobile and tablet |
is-hidden-desktop | Hidden on desktop, widescreen, and fullhd |
Grid System
Columns
Basic structure:
<div class="columns">
<div class="column">First column</div>
<div class="column">Second column</div>
<div class="column">Third column</div>
</div>
Column Sizes
Class | Width |
---|---|
is-full | 100% |
is-four-fifths | 80% |
is-three-quarters | 75% |
is-two-thirds | 66.6666% |
is-three-fifths | 60% |
is-half | 50% |
is-two-fifths | 40% |
is-one-third | 33.3333% |
is-one-quarter | 25% |
is-one-fifth | 20% |
is-1 through is-12 | 8.3333% to 100% (12-column system) |
Column Modifiers
Class | Effect |
---|---|
is-narrow | Column takes only the space it needs |
is-offset-* | Shifts column to the right (e.g., is-offset-3 ) |
is-mobile | Mobile-first columns (stacked on mobile) |
is-multiline | Allows columns to wrap |
is-centered | Centers columns horizontally |
is-vcentered | Centers columns vertically |
is-gapless | Removes gaps between columns |
is-variable | Variable gap widths (is-0 through is-8 ) |
Typography
Text Size Classes
Class | Size |
---|---|
is-size-1 | 3rem |
is-size-2 | 2.5rem |
is-size-3 | 2rem |
is-size-4 | 1.5rem |
is-size-5 | 1.25rem |
is-size-6 | 1rem (default) |
is-size-7 | 0.75rem |
Responsive variants: is-size-1-mobile
, is-size-1-tablet
, etc.
Text Alignment
Class | Effect |
---|---|
has-text-centered | Center-aligned text |
has-text-justified | Justified text |
has-text-left | Left-aligned text |
has-text-right | Right-aligned text |
Responsive variants: has-text-centered-mobile
, has-text-left-desktop
, etc.
Text Transformation
Class | Effect |
---|---|
is-capitalized | Transforms first letter of each word to uppercase |
is-lowercase | Transforms all letters to lowercase |
is-uppercase | Transforms all letters to uppercase |
is-italic | Italicizes text |
has-text-weight-light | Sets font weight to light |
has-text-weight-normal | Sets font weight to normal |
has-text-weight-medium | Sets font weight to medium |
has-text-weight-semibold | Sets font weight to semibold |
has-text-weight-bold | Sets font weight to bold |
Color System
Context Colors
Class Prefix | Purpose |
---|---|
is-primary | Primary brand color |
is-link | Secondary brand color |
is-info | Informational elements |
is-success | Success elements |
is-warning | Warning elements |
is-danger | Error/danger elements |
is-light | Light elements |
is-dark | Dark elements |
is-black | Black elements |
is-white | White elements |
Color Modifiers
Modifier | Effect |
---|---|
is-light | Lighter shade (e.g., is-primary is-light ) |
has-text-* | Text color (e.g., has-text-primary ) |
has-background-* | Background color (e.g., has-background-info ) |
Common UI Components
Buttons
Basic usage:
<button class="button is-primary">Primary Button</button>
Button Styles
Class | Effect |
---|---|
is-outlined | Outlined button |
is-inverted | Inverted colors |
is-rounded | Rounded corners |
is-loading | Loading state |
is-static | Static button (looks inactive) |
is-ghost | Ghost button (transparent background) |
Button Sizes
Class | Size |
---|---|
is-small | Small button |
is-normal | Normal button (default) |
is-medium | Medium button |
is-large | Large button |
Navbar
Basic structure:
<nav class="navbar" role="navigation" aria-label="main navigation">
<div class="navbar-brand">
<a class="navbar-item" href="#">
<img src="logo.png" alt="Logo">
</a>
<a role="button" class="navbar-burger" aria-label="menu" aria-expanded="false">
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
</a>
</div>
<div 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">Dropdown</a>
<div class="navbar-dropdown">
<a class="navbar-item">Item 1</a>
<a class="navbar-item">Item 2</a>
</div>
</div>
</div>
<div class="navbar-end">
<div class="navbar-item">
<div class="buttons">
<a class="button is-primary">Sign up</a>
<a class="button is-light">Log in</a>
</div>
</div>
</div>
</div>
</nav>
Navbar Modifiers
Class | Effect |
---|---|
is-fixed-top | Fixes navbar to top |
is-fixed-bottom | Fixes navbar to bottom |
is-spaced | Adds vertical padding |
has-shadow | Adds shadow |
is-transparent | Makes background transparent |
Cards
Basic structure:
<div class="card">
<div class="card-image">
<figure class="image is-4by3">
<img src="image.jpg" alt="Card image">
</figure>
</div>
<div class="card-content">
<div class="media">
<div class="media-content">
<p class="title is-4">Card title</p>
<p class="subtitle is-6">Subtitle</p>
</div>
</div>
<div class="content">
Card content goes here.
</div>
</div>
<footer class="card-footer">
<a href="#" class="card-footer-item">Footer item</a>
</footer>
</div>
Forms
Basic form elements:
<div class="field">
<label class="label">Label</label>
<div class="control">
<input class="input" type="text" placeholder="Text input">
</div>
<p class="help">Help text</p>
</div>
<div class="field">
<div class="control">
<div class="select">
<select>
<option>Select dropdown</option>
</select>
</div>
</div>
</div>
<div class="field">
<div class="control">
<label class="checkbox">
<input type="checkbox">
Checkbox
</label>
</div>
</div>
<div class="field">
<div class="control">
<label class="radio">
<input type="radio" name="answer">
Radio option
</label>
</div>
</div>
Form Control Modifiers
Class | Effect |
---|---|
is-focused | Focused state |
is-active | Active state |
is-loading | Loading state |
has-icons-left | Left icon |
has-icons-right | Right icon |
is-expanded | Expanded width |
Layout Components
Hero Sections
<section class="hero is-primary">
<div class="hero-body">
<p class="title">Hero title</p>
<p class="subtitle">Hero subtitle</p>
</div>
</section>
Hero Modifiers
Class | Effect |
---|---|
is-small | Small hero |
is-medium | Medium hero |
is-large | Large hero |
is-fullheight | Full height hero |
is-fullheight-with-navbar | Full height minus navbar height |
is-bold | Bold gradient effect |
Containers
<div class="container">
<!-- Content inside a centered container -->
</div>
Class | Effect |
---|---|
is-fluid | Full width on all devices, with margins |
is-widescreen | Maximum 1152px width |
is-fullhd | Maximum 1344px width |
is-max-desktop | Maximum 1344px width |
is-max-widescreen | Maximum 1152px width |
Section
<section class="section">
<!-- Content inside a section with padding -->
</section>
Class | Effect |
---|---|
is-medium | Medium padding |
is-large | Large padding |
Helper Classes
Spacing Helpers
Class Pattern | Function |
---|---|
m-* | Margin on all sides (0-6) |
mt-* | Margin top (0-6) |
mr-* | Margin right (0-6) |
mb-* | Margin bottom (0-6) |
ml-* | Margin left (0-6) |
mx-* | Horizontal margin (0-6) |
my-* | Vertical margin (0-6) |
p-* | Padding on all sides (0-6) |
pt-* | Padding top (0-6) |
pr-* | Padding right (0-6) |
pb-* | Padding bottom (0-6) |
pl-* | Padding left (0-6) |
px-* | Horizontal padding (0-6) |
py-* | Vertical padding (0-6) |
Display Helpers
Class | Effect |
---|---|
is-block | display: block |
is-flex | display: flex |
is-inline | display: inline |
is-inline-block | display: inline-block |
is-inline-flex | display: inline-flex |
is-hidden | display: none |
Flexbox Helpers
Class | Effect |
---|---|
is-flex-direction-row | flex-direction: row |
is-flex-direction-column | flex-direction: column |
is-justify-content-start | justify-content: flex-start |
is-justify-content-end | justify-content: flex-end |
is-justify-content-center | justify-content: center |
is-justify-content-space-between | justify-content: space-between |
is-justify-content-space-around | justify-content: space-around |
is-align-items-start | align-items: flex-start |
is-align-items-end | align-items: flex-end |
is-align-items-center | align-items: center |
is-align-items-baseline | align-items: baseline |
is-align-items-stretch | align-items: stretch |
Common Challenges & Solutions
Challenge 1: Making Navbar Responsive
Problem: The navbar burger doesn’t automatically open on mobile.
Solution: Add JavaScript to toggle the .is-active
class:
document.addEventListener('DOMContentLoaded', () => {
// Get all "navbar-burger" elements
const $navbarBurgers = Array.prototype.slice.call(document.querySelectorAll('.navbar-burger'), 0);
// Add a click event on each of them
$navbarBurgers.forEach(el => {
el.addEventListener('click', () => {
// Get the target from the "data-target" attribute
const target = el.dataset.target;
const $target = document.getElementById(target);
// Toggle the "is-active" class on both the "navbar-burger" and the "navbar-menu"
el.classList.toggle('is-active');
$target.classList.toggle('is-active');
});
});
});
Challenge 2: Customizing Bulma’s Default Colors
Problem: Need to customize the default color scheme.
Solution: Create your own Sass variables file:
// Custom variables
$primary: #8A4D76;
$info: #FA7C91;
$success: #23D160;
$warning: #FFDD57;
$danger: #FF3860;
// Import Bulma after defining variables
@import "bulma/bulma.sass";
Challenge 3: Fixed Table Headers
Problem: Large tables need fixed headers for scrolling.
Solution: Combine Bulma with custom CSS:
<div class="table-container" style="max-height: 400px; overflow-y: auto;">
<table class="table is-bordered is-striped is-narrow is-hoverable is-fullwidth">
<thead style="position: sticky; top: 0; background-color: white; z-index: 1;">
<tr>
<th>Header 1</th>
<th>Header 2</th>
</tr>
</thead>
<tbody>
<!-- Table content -->
</tbody>
</table>
</div>
Best Practices & Tips
1. Modular Import for Performance
Only import the Bulma components you need:
// Import only what you need
@import "bulma/sass/utilities/_all.sass";
@import "bulma/sass/elements/button.sass";
// etc.
2. Mobile-First Approach
- Start with mobile designs, then enhance for larger screens
- Use responsive helpers like
is-hidden-mobile
strategically - Test on actual devices or device simulators
3. Extend Rather Than Override
Create your own classes that extend Bulma’s:
.special-button {
@extend .button;
@extend .is-primary;
border-radius: 0;
}
4. Use Sass Functions for Custom Colors
// Create a custom color using Bulma's functions
@import "bulma/sass/utilities/functions";
$custom-color: findLightColor(findColorInvert($primary));
5. Avoid Overusing Columns
- Don’t nest more than 3 levels of columns
- Use
container
with appropriate size modifiers - Consider tiles for complex grid layouts
6. Leverage Built-In Color Functions
// Create lighter/darker shades using Bulma's functions
$primary-light: findLightColor($primary);
$primary-dark: findDarkColor($primary);
7. Optimize Loading Time
- Consider using Purgecss to remove unused CSS
- Use asynchronous CSS loading for non-critical styles
- Combine with modern loading techniques like preload/prefetch
Resources for Further Learning
Official Documentation
Community Extensions
Learning Resources
- Bulma CSS Framework Tutorial (Scrimba)
- Learn Bulma CSS for Free (Scrimba)
- Bulma Crash Course (YouTube)
Development Tools
This cheatsheet covers the essentials of Bulma CSS Framework. For more detailed information and examples, refer to the official documentation at bulma.io.