Skip to content

Migrate from Bulma

Planning to migrate from Bulma to WovenUI? This guide maps Bulma classes and components to WovenUI core and the kit.

This page is for teams that build with Bulma’s modifier classes (button is-primary, columns, has-text-centered) and want the same ready-made HTML and CSS components on a token system. Layout and helpers come from WovenUI core, and @wovenui/components has the components. Install the kit from the install page. For the framework-level comparison, read WovenUI vs Bulma.

Bulma writes is- and has- modifiers. Core uses short words: flex modifiers apply on a flex element (flex between x-center), and a breakpoint is a suffix (col-span-6@md). Spacing scales differ, so check the number rather than copying it. These are WovenUI core grid classes (Grid). The twelve columns are a default, and core’s $column-count setting changes it; breakpoint names such as md are a default too, set by $breakpoints. See the configuration page.

Bulma WovenUI core Notes
columns with equal column children grid cols-3 gap-4 Set the column count on the parent
column is-half col-span-6 inside grid cols-12 Twelve-column grid
column is-4 col-span-4 inside grid cols-12 Same number as Bulma’s twelve-column sizes
is-half-tablet col-span-6@md Closest breakpoint; check the widths
is-flex flex
is-justify-content-space-between flex between Main axis, no prefix
is-align-items-center x-center x- is the cross axis
is-flex-direction-column col On a flex element
is-flex-wrap-wrap wrap On a flex element
container container Centered, with responsive max widths
has-text-centered text-center
has-text-weight-bold font-bold
has-text-grey text-muted Semantic word that follows the theme
is-uppercase uppercase
is-hidden hide
table is-fullwidth w-full on the table Together with wu-table
mt-4, p-4 mt-4, p-4 Same names, different scale: core 4 is 1rem

Anything with a custom value or a state goes through apply(), for example @include apply(p(13px), bg(brand-hover) hover). Read more in Utility classes, apply() and Grid.

The kit uses a wu- root and bare words for variants, valid only together with the root: wu-btn brand sm. Colors use the core role names, so is-primary becomes brand.

Bulma WovenUI Components Notes
<button class="button is-primary"> <button class="wu-btn brand"> On a <button> or a link
<button class="button is-danger"> <button class="wu-btn danger"> Destructive actions
<button class="button"> <button class="wu-btn"> The plain button is the neutral one
<button class="button is-primary is-light"> <button class="wu-btn brand subtle"> A tinted outline, the closest match; is-outlined maps the same way
button is-small, is-large sm, lg wu-btn brand sm
button is-rounded round wu-btn round
button is-loading aria-busy="true" State in an attribute, not a class
button is-fullwidth w-full Core class next to wu-btn
<div class="buttons has-addons"> <div class="wu-btn-group"> Pressed state from aria-pressed="true"
<div class="notification is-success"> <div class="wu-alert success"> Title in wu-alert-title; the marker shape repeats the role
<button class="delete"> in a notification <button class="wu-alert-close"> A <button> with aria-label
<span class="tag is-success"> <span class="wu-badge success"> Add solid for a filled badge
<span class="tag"> <span class="wu-tag"> Also wu-tag hues such as blue and green
<div class="card"> <article class="wu-card"> Parts: <header class="wu-card-header">, <div class="wu-card-body">, <footer class="wu-card-footer">; heading in wu-card-title
<div class="modal is-active"> <dialog class="wu-modal"> Replaces modal-card too; opened with commandfor and command="show-modal", no script
<header class="modal-card-head">, <section class="modal-card-body">, <footer class="modal-card-foot"> <header class="wu-modal-header">, <div class="wu-modal-body">, <form class="wu-modal-footer"> The footer is a <form method="dialog">
<button class="modal-close"> <button class="wu-modal-close"> A <button> with command="close"
<nav class="navbar"> <header class="wu-topbar"> Add pinned to stick to the top
<div class="navbar-brand"> <a class="wu-topbar-brand">
<div class="navbar-start"> <ul class="wu-topbar-nav"> A list of links inside a <nav>
<a class="navbar-item"> <a class="wu-topbar-link"> aria-current="page" marks the current page
<div class="navbar-end"> <div class="wu-topbar-end">
<div class="dropdown is-active"> <div class="wu-dropdown" popover> Items are wu-dropdown-item links or buttons; opened with popovertarget, no script
<div class="field"> <div class="wu-field">
<label class="label"> <label class="wu-field-label">
<input class="input"> <input class="wu-input"> On a text-like <input>
<div class="select"> around a <select> <select class="wu-select"> On the native <select> itself, no wrapper
<label class="checkbox">, <label class="radio"> <label class="wu-checkbox">, <label class="wu-radio"> With wu-checkbox-input or wu-radio-input inside the <label>
<p class="help">, <p class="help is-danger"> <p class="wu-field-message">, <p class="wu-field-message error"> Link it with aria-describedby
<div class="field has-addons"> <div class="wu-input-group"> Addons use wu-input-group-text
<table class="table is-striped"> <table class="wu-table striped"> Also hover, bordered, sm
<div class="tabs"> <div class="wu-tabs"> Parts wu-tabs-list, wu-tabs-tab, wu-tabs-panel; ARIA tabs; the kit script adds the keyboard
<nav class="breadcrumb" aria-label="breadcrumbs"> <nav class="wu-breadcrumb"> Wraps <ol class="wu-breadcrumb-list">
<nav class="pagination" aria-label="pagination"> <nav class="wu-pagination"> Wraps <ul class="wu-pagination-list"> of wu-btn links; aria-current="page" marks the current page
<progress class="progress is-danger"> <progress class="wu-progress danger"> On a native <progress>
<h2 class="title"> <h2 class="wu-title"> Sizes sm, lg, xl; pick the heading level for the outline

Bulma is CSS only, so its modals and dropdowns work only after you write the script that adds and removes is-active. With the kit you do not write that script. A button opens the modal with commandfor and command="show-modal", and a button opens the dropdown with popovertarget. The browser handles Esc, focus and click outside. The accordion is <details>, with no script either.

  • Native elements. Modals are <dialog>, menus and popovers use the popover attribute, and accordions are <details>. The browser handles focus, Esc and the top layer, so there is no is-active class to toggle and most components need no JavaScript.
  • State lives in attributes. Loading, pressed, selected and current states come from aria-busy, aria-pressed, aria-selected and aria-current, not from extra classes.
  • No wrapper elements. A form control is the styled element itself, so Bulma’s control and select wrappers are not needed.
  • Tokens and themes. Every component reads core --wu-* tokens, so light, dark, inverse and high contrast need no extra classes and no Sass rebuild.
  • No icon set. The kit ships no icons. Markers such as the select arrow and the close cross are drawn in CSS. Bring the icon set you already use.
  • Motion is opt-in. Components are calm by default. Add animated (or wu-animated on an ancestor) to turn motion on; it still respects prefers-reduced-motion.
  1. Install the kit. Load the bundle or per-component entries, not both.
  2. Replace layout and helper classes with core utilities, using the first table.
  3. Swap components one at a time with the component table. Keep the old CSS loaded until the last one is gone.
  4. Move colors and spacing to core tokens, and switch themes with data-theme.
  5. Remove the old framework’s CSS and script.