Bulma's Columns System: Building Responsive Layouts Without Writing Flexbox
Bulma's columns system gives you responsive flexbox layouts with no custom CSS — if you understand its equal-width default, mobile stacking, and opt-in breakpoint classes.
08 Nov 2025, 01:59 UTC

If you picked Bulma for layout, the decision that matters most is how you use its columns system — and the single most useful fact is this: columns are equal-width by default, stack vertically on mobile by default, and only become responsive when you opt in per breakpoint. Get those three behaviors right and you can build most page layouts with zero custom CSS.
How the columns system actually works
Bulma's grid is a thin layer over CSS flexbox. A .columns container is a flex row; every direct .column child gets flex: 1 1 0-style equal sharing of the available width. Two children means 50/50, three means thirds — no classes needed.
To break the equal split, add a size modifier to one column and let the others absorb the rest:
<div class="columns">
<div class="column is-two-thirds">Main content</div>
<div class="column">Sidebar</div>
</div>This gives a 2:1 layout because is-two-thirds fixes the first column's basis while the bare .column flexes into the remainder. Other modifiers include is-half, is-one-third, is-one-quarter, and the twelve-column-style numeric classes is-1 through is-12. Nesting a .columns block inside a .column creates a sub-grid, which is how you build card rows inside a main content area.
Making it responsive: opt in per breakpoint
Here is the behavior that surprises newcomers: by default, on viewports below the tablet breakpoint (768px in Bulma's defaults), columns stack full-width. A bare is-two-thirds applies at all sizes, which often squashes content on phones. The fix is breakpoint-suffixed classes:
<div class="columns">
<div class="column is-two-thirds-tablet">Main</div>
<div class="column">Sidebar</div>
</div>is-two-thirds-tablet applies from the tablet breakpoint upward; below it, both columns stack at full width. Suffixes exist for -mobile, -tablet, -desktop, and -widescreen. Conversely, if you want columns side-by-side even on phones, add is-mobile to the .columns container.
A practical rule: write the mobile stacked layout first, then add suffixed size classes for larger screens. This matches how the modifiers cascade and avoids the classic mistake of a desktop-only class crushing mobile content.
Theming in Bulma 1.x: CSS variables, not recompilation
Bulma 1.x moved customization to CSS custom properties and Sass @use modules. In practice this means you can retheme a page at runtime without touching Sass:
:root {
--bulma-primary: #485fc7;
}Set that after the Bulma stylesheet loads and components using the primary color pick it up. This is a real workflow change from 0.9.x, where theming meant overriding Sass variables before an @import and recompiling. Check your installed version first (look at package.json or the comment header in the CSS file): guides written for 0.9.x use @import "bulma/bulma", while 1.x uses @use "bulma/sass"-style module imports. Mixing the two eras is the most common cause of broken builds.
Limits and common mistakes
- No JavaScript ships with Bulma. The navbar burger, modals, and dropdowns are styled but inert. You must toggle
is-activeyourself and wire uparia-expandedand focus handling — a deliberate tradeoff that keeps Bulma framework-agnostic but surprises teams expecting Bootstrap-style behavior. - Size classes without a breakpoint suffix apply everywhere. This is the top mobile-layout bug in Bulma codebases.
- Helper-heavy markup drifts. Spacing helpers (
m-4,px-2) and visibility helpers (is-hidden-mobile) reduce custom CSS, but pages built entirely from utilities become hard to refactor. Extract repeated patterns into components in your app framework. - Payload size. The full
bulma.cssbundle includes everything. If you import via Sass in 1.x, pull in only the modules you use, or run a purge step against your templates. - Equal-width assumption. Because bare columns share space evenly, a column with long unbreakable content (a wide table, a code block) can force siblings to shrink. Add
is-clippedor overflow handling inside the column rather than fighting the flex behavior.
Verifying the result
Create a minimal page linking your installed Bulma build with the 2:1 example above. Confirm two things: on a wide viewport the columns sit side-by-side in a 2:1 ratio, and when you narrow the browser below ~768px (or use devtools device emulation) they stack full-width. If you set a --bulma-primary override, inspect a button in devtools and confirm the computed background color reflects your variable — if it doesn't, you're likely on 0.9.x, where CSS variables don't exist and Sass recompilation is required.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.