๐ŸŽˆ Customization of Oruga components with Bulma CSS framework

  • By Oruga
  • Last update: Jan 4, 2023
  • Comments: 16

Bulma theme for Oruga


npm install @oruga-ui/theme-bulma


yarn add @oruga-ui/theme-bulma


import { createApp } from 'vue'
import App from './App.vue'

import Oruga from '@oruga-ui/oruga-next'
import { bulmaConfig } from '@oruga-ui/theme-bulma'

import '@oruga-ui/theme-bulma/dist/bulma.css'

    .use(Oruga, bulmaConfig)

Please note, the package also works for @oruga-ui/oruga (Vue 2) and you can use it without importing the full Oruga bundle.

Customization (SASS/SCSS)

Using the following sample code you don't need import '@oruga-ui/theme-bulma/dist/bulma.css' but you have to add a custom sass/scss file to customize Bulma and theme variables.

@import "~bulma/sass/utilities/_all";

// Set your colors
$primary: #8c67ef;
$primary-light: findLightColor($primary);
$primary-dark: findDarkColor($primary);
$primary-invert: findColorInvert($primary);
$twitter: #4099FF;
$twitter-invert: findColorInvert($twitter);

// Lists and maps
$custom-colors: null !default;
$custom-shades: null !default;

// Setup $colors to use as bulma classes (e.g. 'is-twitter')
$colors: mergeColorMaps(
        "white": (
        "black": (
        "light": (
        "dark": (
        "primary": (
        "link": (
        "info": (
        "success": (
        "warning": (
        "danger": (

// Links
$link: $primary;
$link-invert: $primary-invert;
$link-focus-border: $primary;

@import "~bulma/bulma";
@import '~@oruga-ui/theme-bulma/dist/scss/bulma';

Override default config

In case you want to replace the default style of a component you can override or add new classes changing bulmaConfig; more details about components customization on https://oruga.io/documentation/#customization

import { createApp } from 'vue'

import Oruga from '@oruga-ui/oruga-next'
import { bulmaConfig } from '@oruga-ui/theme-bulma'

import '@oruga-ui/theme-bulma/dist/bulma.css'

const customBulmaConfig = {
    checkbox: {
        override: true,
        rootClass: 'checkbox'

    .use(Oruga, customBulmaConfig)

Buefy users


Buefy Oruga Note
Taginput Inputitems
Toast N.A. You can customize Notification with noticeClass and/or passing a component using programmatic way
Snackbar N.A. You can customize Notification with noticeClass and/or passing a component using programmatic way

At the moment you won't find Carousel, Dialog, Navbar, Menu but we'll add them soon in Oruga core code.


Buefy Oruga Component Note
type variant - Removed prefix is-
size size - Removed prefix is-
loading N.A. - Not supported
label-position N.A. Field Not suppported but you can easily add is-floating-label or is-floating-in-label class to root-class prop
size N.A. Tooltip You can use multiline-class or content-class
custom N.A. Dropdown Item You can use tag prop
has-modal-card N.A. Modal You have to add content-class="modal-content" when you don't use modal-card classes as content


Thank you to everyone involved for improving this project, day by day ๐Ÿ’š

Complete list.


Logo designed by rubjo


Code released under MIT license.




  • 1

    Docs: New logo

    Using Oruga logo and Bulma logo "draw" a new logo to publish in the Readme and in the official docs.

    Your profile will be mentioned in the README ๐ŸŽ‰

  • 2

    Datepicker header fields are not attached


    I have an issue with the datepicker component: month and year fields are not attached.

    Following HTML rendered (differences seems to be <div class="pagination-list"> children) and screenshots

    With Buefy (0.9.10) / bulma (0.9.3), I got this:


          <div class="field">
            <div class="field-body">
              <div class="field has-addons">
                <div class="control">
                  <span class="select"><select>
                      <option value="0"> January </option>
                <div class="control">
                  <span class="select">
                      <option value="2022"> 2022 </option>

    And now with oruga-next: (0.5.4) / theme-bulma (0.2.3), it display like this:


        <div class="pagination-list">
          <div class="control select">
            <select class="">
              <option value="0">January</option>
          <div class="control select">
            <select class="">
              <option value="2022">2022</option>

    I presume we need to have this missing part:

    <div class="field">
      <div class="field-body">
        <div class="field has-addons">

    I tried to add the Bulma field has-addons classes to the div.pagination-list using the listsClass prop but it overflows ๐Ÿ˜ž:


    Last (ugly) try, I updated the .dropdown-menu with min-width: 25rem ...

  • 3

    Cannot load externally because of unexpected characters in global namespace


    I like to load theme-bulma externally using webpack. But because the global name @orugaUi/themeBulma used in bulma.js contains non-ascii characters this is not possible. Works fine if I modify the bulma.js file myself to use a global name such as themeBulma.

    Is there any chance the global name will be changed to something compatible with webpack in the near future? Or do you see this as a bug in webpack itself?


      module.exports.configureWebpack = {
        externals: {
          "@oruga-ui/oruga-next": 'Oruga',
          "@oruga-ui/theme-bulma": "@orugaUi/themeBulma"

    npm run build

    Unexpected character '@' (1:35)
    | var __WEBPACK_NAMESPACE_OBJECT__ = @orugaUi/themeBulma;
    while analyzing module external var "@orugaUi/themeBulma" for concatenation
     ERROR  Error: Build failed with errors.
  • 4

    Upload component shows extra, standard HTML "Choose File" button

    Vue version: 3.2.25 Bulma theme: 0.2.2 Oruga: 0.5.4

    Using the example of the base Upload component in the Oruga documentation, I'm getting two buttons: one o-button, and one that seems to be the standard upload element's button reading "Choose File".

    I haven't looked into it yet, but has this component been confirmed working before with the Bulma plugin? Can't use it like this. :)

  • 5

    Notification renders double close button

    First off, great library, keep up the good work!

    I'm using @oruga-ui/oruga-next 0.5.6 and @oruga-ui/theme-bulma 0.2.7 in a Vue 3 app with fontawesome. When I open a notification like this

    	const { oruga } = useProgrammatic();
    		message: 'This is a test error message',
    		variant: 'danger',
    		closable: true,

    oruga creates a notification with a double close button like this

    Screen Shot 2022-09-16 at 12 39 03 PM

    This issue is theme applies bulma's delete class to the close element (creating the circular close button using css) and also generates an icon using the default value of the closeIcon prop in the component. I was able to get around this problem by passing an empty string for closeIcon in my config like this:

    import oruga from '@oruga-ui/oruga-next';
    import { bulmaConfig } from '@oruga-ui/theme-bulma';
    import { merge } from 'lodash';
    export const overrideConfig = {
    	notification: {
    		// This removes a duplicate close icon
    		closeIcon: '',
    app.use(oruga, merge(bulmaConfig, overrideConfig));

    I would recommend making this a part of the theme for a smoother dev experience.

  • 6

    fix: vertical tabs and bottom border of boxed tabs

    a new try to fix the bottom border of boxed tabs. this time there is a bottom border over the whole length, just like in Bulma. Additionaly I fixed vertical tabs and the positions.

  • 7

    Please provide examples on how to use theme-bulma with Vue 2, especially when importing single components

    the readme states: 'Please note, the package also works for @oruga-ui/oruga (Vue 2) and you can use it without importing the full Oruga bundle.'.

    I am using Vue 3 however, but am using the Options API like so.

    import { OButton } from '@oruga-ui/oruga-next';
    import { bulmaConfig } from '@oruga-ui/theme-bulma';
    export default {
      components: {
      ...blah blah blah

    But how would I use the bulmaConfig to configure that individual components where there are needed? I really do not want to import the entire package into my app, I only need a few components.

  • 8

    Buttons (and selects) in fields with has-addons don't attach correctly

    Buttons in fields with has-addons don't attach to the field corrctly and keep their border-radius set. Button_as_addon Wrapping the button in a <div class="control"> fixes this, is this the intended behaviour?

  • 9

    o-table pagination issue

    Hey guys, I'm currently trying to integrate Oruga into my app that has been using Buefy.

    I'm using Oruga 0.5.2 and theme-bulma 0.2.1.

    I'm having an issue with the appearance of the pagination section when I use the Oruga Table Component o-table.

    When I compare it to Buefy's pagination for b-table, I notice that all the level classes aren't being applied. For example: level top, level-right, level-left and so on.

    As a temporary fix, I manually wrote the scss for the level classes to be applied to the pagination divs.

    I've included the styles below...

    I think a more permanent solution will have to be an update to both theme-bulma and oruga. Oruga needs to have the customizations for those divs so theme-bulma can set the configuration for the level classes. Right now, the only customization for this is paginationWrapperClass, and theme-bulma sets this to empty when it should at least make it the level class.

    // Temp solution to getting the pagination to look right.
    .b-table.table-wrapper {
      margin-bottom: 0;
      .pagination-link {
        padding-left: 0.5em;
        padding-right: 0.5em;
      + div {
        padding: 1.125rem 1.5rem;
        margin: 0;
        border-top: rgba(24, 28, 33, 0.06);
        background: #f5f5f5;
        display: flex;
        -webkit-box-align: center;
        -ms-flex-align: center;
        align-items: center;
        -webkit-box-pack: justify;
        -ms-flex-pack: justify;
        justify-content: space-between;
        div {
          display: flex;
          flex-basis: auto;
          -webkit-box-flex: 0;
          flex-grow: 0;
          flex-shrink: 0;
          -webkit-box-align: center;
          -ms-flex-align: center;
          align-items: center;
        div:nth-child(1) {
          -webkit-box-pack: start;
          -ms-flex-pack: start;
          justify-content: flex-start;
        div:nth-child(2) {
          -webkit-box-pack: end;
          -ms-flex-pack: end;
          justify-content: flex-end;
          div {
            -webkit-box-align: center;
            -ms-flex-align: center;
            align-items: center;
            display: -webkit-box;
            display: -ms-flexbox;
            display: flex;
            flex-basis: auto;
            -webkit-box-flex: 0;
            flex-grow: 0;
            flex-shrink: 0;
            -webkit-box-pack: center;
            -ms-flex-pack: center;
            justify-content: center;
  • 10

    Switch not showing after upgrade to Oruga 0.5.x

    After upgrading to Oruga 0.5, the Switch component did not show on screen, as can be seen here: image if I remove theme-bulma, the switch appears again, as can be seen here: image the HTML code is:

    <OField label="Estado">
          <OSwitch v-model="estado_cliente"
                {{ estado_cliente }}

    and the app file is:

    import './plageco_iconos'
    import { createApp } from 'vue'
    import App from './components/landing/App.vue'
    import router from './router/index_back'
    import store from './store'
    import mitt from 'mitt'
    import Oruga from '@oruga-ui/oruga-next'
    import { bulmaConfig } from '@oruga-ui/theme-bulma'
    import '../sass/backplageco.scss'
    // import '@oruga-ui/oruga-next/dist/oruga.css'
    import '@oruga-ui/theme-bulma/dist/bulma.css'
    const plagecov1 = createApp(App)
    const emitter = mitt()
    plagecov1.config.globalProperties.emitter = emitter
    // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
    const customBulmaConfig = {
        iconPack: 'far'
    // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
    plagecov1.use(Oruga, customBulmaConfig)
    // plagecov1.use(Oruga)

    I think that some detil sliped during the Oruga upgrade and is afecting theme-bulma. Will be alert for any test request or aditional information needed.

  • 11

    Feature: create packaging

    This repository aims to bring a default configuration to use Oruga components with Bulma styles.

    We need some help to

    • create build scripts
    • reorganize code
    • reorganize dependencies

    to make it ready to be built as a NPM package.

  • 12

    fix: Add datepicker classes for monthly mode

    I was messing around with this library and noticed that when the datepicker was created in monthly mode, the styling broke (also reported in https://github.com/oruga-ui/theme-bulma/issues/71).

    From inspecting the DOM tree it looked like none of the classes were set, so this explicitly adds the class props in the bulma config.

    A screenshot of how it looked for me when I did it using the override

    Screen Shot 2022-12-11 at 9 54 41 AM

    I'm not sure if there's a better way to fix this or if it's a bug in the Oruga lib itself when it generates classes, though, so worth a review!

  • 13

    datepicker appearance with month type


    Thank you very much for the project!

    My environment:

    With the following code (from Oruga documentation):

      placeholder="Click to select..."

    I get the following result: image

    From Oruga documentation (https://oruga.io/components/datepicker.html), I should get something like this: image

    firefox inspector gives the following html:
    <div class="dropdown dropdown-menu-animation is-active" aria-modal="true"><div tabindex="-1" class="dropdown-trigger" aria-haspopup="true"><div class="control has-icons-left"><input placeholder="Click to select..." readonly="" class="input" type="text" autocomplete="off"><span class="icon is-left"><!-- custom icon component --><svg class="svg-inline--fa fa-calendar" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="calendar" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path class="" fill="currentColor" d="M96 32V64H48C21.5 64 0 85.5 0 112v48H448V112c0-26.5-21.5-48-48-48H352V32c0-17.7-14.3-32-32-32s-32 14.3-32 32V64H160V32c0-17.7-14.3-32-32-32S96 14.3 96 32zM448 192H0V464c0 26.5 21.5 48 48 48H400c26.5 0 48-21.5 48-48V192z"></path></svg></span><!--v-if--><!--v-if--></div></div><div class="background" aria-hidden="false" style=""></div><div is="div" class="dropdown-content dropdown-menu" aria-hidden="false" role="dialog" aria-modal="true" style=""><div class="dropdown-item" tabindex="0"><header class="datepicker-header"><div class="pagination field is-centered"><a class="pagination-previous" role="button" href="#"><span class="icon is-clickable"><!-- custom icon component --><svg class="svg-inline--fa fa-angle-left" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="angle-left" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path class="" fill="currentColor" d="M41.4 233.4c-12.5 12.5-12.5 32.8 0 45.3l160 160c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L109.3 256 246.6 118.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-160 160z"></path></svg></span></a><a class="pagination-next" role="button" href="#"><span class="icon is-clickable"><!-- custom icon component --><svg class="svg-inline--fa fa-angle-right" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="angle-right" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path class="" fill="currentColor" d="M278.6 233.4c12.5 12.5 12.5 32.8 0 45.3l-160 160c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3L210.7 256 73.4 118.6c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0l160 160z"></path></svg></span></a><div class="pagination-list"><!--v-if--><div class="control select"><select class=""><!--v-if--><option value="2032">2032</option><option value="2031">2031</option><option value="2030">2030</option><option value="2029">2029</option><option value="2028">2028</option><option value="2027">2027</option><option value="2026">2026</option><option value="2025">2025</option><option value="2024">2024</option><option value="2023">2023</option><option value="2022">2022</option><option value="2021">2021</option><option value="2020">2020</option><option value="2019">2019</option><option value="2018">2018</option><option value="2017">2017</option><option value="2016">2016</option><option value="2015">2015</option><option value="2014">2014</option><option value="2013">2013</option><option value="2012">2012</option><option value="2011">2011</option><option value="2010">2010</option><option value="2009">2009</option><option value="2008">2008</option><option value="2007">2007</option><option value="2006">2006</option><option value="2005">2005</option><option value="2004">2004</option><option value="2003">2003</option><option value="2002">2002</option><option value="2001">2001</option><option value="2000">2000</option><option value="1999">1999</option><option value="1998">1998</option><option value="1997">1997</option><option value="1996">1996</option><option value="1995">1995</option><option value="1994">1994</option><option value="1993">1993</option><option value="1992">1992</option><option value="1991">1991</option><option value="1990">1990</option><option value="1989">1989</option><option value="1988">1988</option><option value="1987">1987</option><option value="1986">1986</option><option value="1985">1985</option><option value="1984">1984</option><option value="1983">1983</option><option value="1982">1982</option><option value="1981">1981</option><option value="1980">1980</option><option value="1979">1979</option><option value="1978">1978</option><option value="1977">1977</option><option value="1976">1976</option><option value="1975">1975</option><option value="1974">1974</option><option value="1973">1973</option><option value="1972">1972</option><option value="1971">1971</option><option value="1970">1970</option><option value="1969">1969</option><option value="1968">1968</option><option value="1967">1967</option><option value="1966">1966</option><option value="1965">1965</option><option value="1964">1964</option><option value="1963">1963</option><option value="1962">1962</option><option value="1961">1961</option><option value="1960">1960</option><option value="1959">1959</option><option value="1958">1958</option><option value="1957">1957</option><option value="1956">1956</option><option value="1955">1955</option><option value="1954">1954</option><option value="1953">1953</option><option value="1952">1952</option><option value="1951">1951</option><option value="1950">1950</option><option value="1949">1949</option><option value="1948">1948</option><option value="1947">1947</option><option value="1946">1946</option><option value="1945">1945</option><option value="1944">1944</option><option value="1943">1943</option><option value="1942">1942</option><option value="1941">1941</option><option value="1940">1940</option><option value="1939">1939</option><option value="1938">1938</option><option value="1937">1937</option><option value="1936">1936</option><option value="1935">1935</option><option value="1934">1934</option><option value="1933">1933</option><option value="1932">1932</option><option value="1931">1931</option><option value="1930">1930</option><option value="1929">1929</option><option value="1928">1928</option><option value="1927">1927</option><option value="1926">1926</option><option value="1925">1925</option><option value="1924">1924</option><option value="1923">1923</option><option value="1922">1922</option></select><!--v-if--><!--v-if--></div></div></div></header><!--v-if--><section class=""><div class=""><div class=""><a class="" role="button" href="#" disabled="false" tabindex="-1">janvier <!--v-if--></a><a class="" role="button" href="#" disabled="false" tabindex="-1">fรฉvrier <!--v-if--></a><a class="" role="button" href="#" disabled="false" tabindex="-1">mars <!--v-if--></a><a class="" role="button" href="#" disabled="false" tabindex="-1">avril <!--v-if--></a><a class="" role="button" href="#" disabled="false" tabindex="-1">mai <!--v-if--></a><a class="" role="button" href="#" disabled="false" tabindex="-1">juin <!--v-if--></a><a class="" role="button" href="#" disabled="false" tabindex="-1">juillet <!--v-if--></a><a class="" role="button" href="#" disabled="false" tabindex="-1">aoรปt <!--v-if--></a><a class="" role="button" href="#" disabled="false" tabindex="-1">septembre <!--v-if--></a><a class="" role="button" href="#" disabled="false" tabindex="-1">octobre <!--v-if--></a><a class="" role="button" href="#" disabled="false">novembre <!--v-if--></a><a class="" role="button" href="#" disabled="false" tabindex="-1">dรฉcembre <!--v-if--></a></div></div></section><!--v-if--></div></div></div>
  • 14

    inputitems sizing does not work correctly.

    When I set the size to small

    <o-inputitems size="small"/>

    the component display small initially, however as soon as an entry is selected it increases in size.

    The issues I've found so far are:

    1. when blank the o-inputitems component renders at 30.7px high (vs a o-input control as small renders at 30px)

      • this causes visual discontinuity between the two components when next to each other (e.g. as filter on an o-table) image
    2. when an entry is added to the o-inputitems the size increases to 36.1667px image

    Other sizes are also not inline either. default 40 vs 39.8 medium 50 vs 48.9 large 60 vs 58

    for Buefy the taginput sizes are 29.6, 39.8, 50, 60.2 and do not have the issue of changing sizes with or without the "tags".

  • 15

    sticky-header on table does not work with theme-bulma

    adding the sticky-header prop on an o-table when using theme-bulma does nothing as

    1. the configuration does not set a class for stickyHeaderClass
    2. when using "has-sticky-header" it some-what works
      • the first TR in the thead sticks
      • sticky columns, however, do not work

    Other usability-questions regarding sticky Headers.

    1. how does one get the filter row to also be sticky?
    2. how does one control the height of the table when in "sticky" mode. It seems odd to fix it at 300px always. (on a per-table basis not globally)
  • 16

    Replace the use of @import

    According to https://sass-lang.com/blog/the-module-system-is-launched we should replace @import that has been deprecated since last October and we'll be removed before the end of year.