Translate Bulma css api to vue components

  • By null
  • Last update: Dec 16, 2022
  • Comments: 11


Build Status

The goal of this library is to use the bulma class syntax as components and props.

3kb minified

Demo and try the live demo too :)


Exemple with grid system

Original Bulma way:

<div class="columns is-mobile">
  <div class="column is-half is-offset-one-quarter">
    A column

Vue-bulma-component way:

<b-columns is-mobile>
  <b-column is-half is-offset-one-quarter>
    A column

Using css class as directives at your advantage

One cool feature of using the Bulma css api as directives is toggling them. See how the is-loading class is handled


<button class="button is-dark" :class="{ 'is-loading': bool }">

Vue-bulma-component way:

<b-button is-dark :is-loading="bool">

Much nicer right ? ;)


You can also use the Pascal case notation, example:

<BButton is-dark :is-loading="bool">

Using custom classes

If you want to add any other class simply use the normal class attribute

<b-button is-dark :class="my-custom-class">


yarn add vue-bulma-components


npm install --save vue-bulma-components

Then install Bulma however you want :).

Use all components globally in your app

Inside your main.js

import vueBulmaComponents from 'vue-bulma-components'

It will make globallly available all these bulma components with the prefix b- or B if you prefer the Pascal case component naming.

You can also change the default prefix of all the bulma components (to avoid collision with existing components in your project)

import vueBulmaComponents from 'vue-bulma-components'
Vue.use(vueBulmaComponents, {prefix: 'y-'})

Instead of using <b-columns/> you need to use <y-columns/>

Use specific bulma components in your components


  import { bulmaComponentGenerator } from 'vue-bulma-components'

  export default {
    components: {
        box: bulmaComponentGenerator('box')

Yes, you can actually create any vue-bulma-component by calling bulmaComponentGenerator(bulmaComponentStr).


By default, most of the components are rendered as <div>. You can also use the prop outerElement="span" to change this behavior.

If you want to globally apply default outer element for some bulma component, you can use outerElement option on Vue.use().

import vueBulmaComponents from 'vue-bulma-components'
Vue.use(vueBulmaComponents, {
  outerElement: {
    'navbar': 'nav',
    'navbar-item': 'a'

If you use the Vue.use() method to use the vue-bulma-components.

Most of the components are named after the bulma class they belong to. Ex: <box/> <card/> <panel/> ...

However, some bulma components are also named after native html element. This is why they are prefixed.

Ex :

  • Bulma : input
  • vue-component-bulma: <b-input>. This prefix is used to avoid collision with native html <input> element.

If you generate bulma components

  import { bulmaComponentGenerator } from 'vue-bulma-components'

  export default {
    components: {
        box: bulmaComponentGenerator('box', 'span')

Usage: bulmaComponentGenerator(bulma_coponent_name,rendered_outer_html_element ).

Note: rendered_outer_html_element is optional.

Known limitations:

Currently you cannot use v-model with <b-input> as expected. Because vue-bulma-components use functional components.

Don't worry, you can still bind a value to a <b-input> component using @input event (it's what v-model does under the hood):

    <b-input :value="foo" @input="handleInputChange"/>


  export default {
    data: () => ({
      foo: ''
    method: {
      handleInputChange (e) { =

Note: If you come from the version 1.x.x, there is a breaking change.

From 2.x.x when using Vue.use(vueBulmaComponents), default available components are prefixed by <b-[bulmacomponent]/> instead of <[bulmacomponent]/>



  • 1

    Hi there!!

    in the last weeks i was working in a implementation of vue-bulma, i searched for a existing project but i dont found any one. So I was working in a new one... but in the morning of today playing with codesandbox I found this awesome project. I wish to help with this project so I made a demo for the documentation with vuepress and update the project to the new vue-cli.

    Documentation demo

    If you wan I can continue with the documentation

  • 2

    Register component name to PascalCase

    <BButton> will be an unknown custom element, because this plugin was registered the component with name like kebab-case.

    Register the component with name like PascalCase, works fine with <b-button> and <BButton>.

  • 3


    Hello maintainers

    I am interested in making use of this as part of a Uni project, but there is no defined licence, so suggests that all rights are reserved. Is this the case? If so is there a point of contact regarding use?

    Many thanks

  • 4

    Add support for custom classes

    I essentially changed the order in which the data is applied to the component. This way no class are overwritten.

    I also updated node_js in travis so it could fix the other pull request

  • 5

    Is it possible to add a custom class?

    For example I want to have a component that changes it's class based on a value

    I could do <b-button is-small :is-danger="notConnected" :is-success="connected" />, but is there a way to do <b-button is-small :class="connectedClass"> without overriding the already specified classes?

  • 6

    update built lib to version 1.7.0

    Hi, I was just checking pull request #8 is already merged and I tried to update vue-bulma-components to version 1.7.0 on my project. However, I don't think the build lib is updated to version 1.7.0, its still using version 1.6.0. Please kindly check, thanks!

  • 7

    Add navbar child classes

    I found there are some components which are in bulma 0.6.1 but are not in vue-bulma-components. This patch will add some components, navbar and navbar-*.

    Components in bulma are listed by this snippet...

    ~/.g/g/j/bulma ❯❯❯ ruby -ne 'puts $_.match(/\.navbar(-|[a-zA-Z0-9])*/)' < sass/components/navbar.sass | sort | uniq
  • 8

    Added support for bulma "icon" component + fa/fa- support

    Consider the following bulma snippet:

    <span class="icon">
        <i class="fa fa-home"></i>

    Before this PR, it needs to be done like this:

    <icon outerElement="span">
        <i class="fa fa-home"></i>

    After this PR:

        <fa fa-home></fa>

    I hope you agree this is better! :)

  • 9

    Image attributes errors

    Hi, Just started getting into vue and bulma, stumbled upon this project and very much like it. I'm running into an issue where CamelCaseToDash has an issue handling image attributes such as is-128x128

    Expected: <b-image is-128x128> --> <figure class="image is-128x128"> Result: <b-image is-128x128> --> <figure class="image is-128x-128">

    I'm guess camelCaseToDash is seeing 128x128 and assuming it is to be separated.

  • 10


    This PR passes the project to v2

    This will introduce a breaking change whe using Vue.use(vueBulmaComponents).

    It was a bad decision not to prefix by default all components.


  • 11

    Version 2

    Hey !

    I am thinking about 2.0, i would like to tackle few things with vue-bulma-components.

    • See if we can simplify the code base ?
    • Better contributing doc


    • I would like to change the way the components are being called. Right now, if we add all components, we can have this:
    <box is-primary />
    <b-input is-loading/>

    The issue i see here is how the component name do not follow the same pattern. One sticks to bulma names, the other have a predefined prefix to it.

    More over, i believe it's better to know that we are using a component coming from X library just by using it.

    A good example of what i am trying to say is vuetify:


    What if we alway prefix bulma components in the same way:

    <b-box is-primary />
    <b-input is-loading/>

    It will be much easier to split dumb/visual/library components and logic/your own components too.

    The only issues:

    Will break users code if they use Vue.use(defaultImport). <box /> will have to be changed to <b-box />

    Possible solution? : Handling both cases and add a deprecation warning in the log.

    What do you guys think ?