Modal

A classic modal overlay, in which you can include any content you want

The modal structure is very simple:

  • modal: the main container
    • modal-background: a transparent overlay that can act as a click target to close the modal
    • modal-content: a horizontally and vertically centered container, with a maximum width of 640px, in which you can include any content
    • modal-close: a simple cross located in the top right corner

<div class="modal">
  <div class="modal-background"></div>
  <div class="modal-content">
    <!-- Any other Bulma elements you want -->
  </div>
  <button class="modal-close is-large" aria-label="close"></button>
</div>

To activate the modal, just add the is-active modifier on the .modal container. You may also want to add is-clipped modifier to a containing element (usually html) to stop scroll overflow.

JavaScript implementation example
Bulma does not include any JavaScript. However, this documentation provides a JS implementation example that you are free to use.

Image modal #

Because a modal can contain anything you want, you can very simply use it to build an image gallery for example:

Launch image modal

<div class="modal">
  <div class="modal-background"></div>
  <div class="modal-content">
    <p class="image is-4by3">
      <img src="https://bulma.zcopy.site/images/placeholders/1280x960.png" alt="">
    </p>
  </div>
  <button class="modal-close is-large" aria-label="close"></button>
</div>

If you want a more classic modal, with a head, a body and a foot, use the modal-card.

<div class="modal">
  <div class="modal-background"></div>
  <div class="modal-card">
    <header class="modal-card-head">
      <p class="modal-card-title">Modal title</p>
      <button class="delete" aria-label="close"></button>
    </header>
    <section class="modal-card-body">
      <!-- Content ... -->
    </section>
    <footer class="modal-card-foot">
      <button class="button is-success">Save changes</button>
      <button class="button">Cancel</button>
    </footer>
  </div>
</div>

JavaScript implementation example #

The Bulma package does not come with any JavaScript. Here is however an implementation example, which sets the click handlers for custom elements, in vanilla JavaScript.

There are 3 parts to this implementation:

  • add the HTML for the modal (this modal is hidden by default)
  • add the HTML for a button to trigger the modal (you can style this button however you want)
  • add the JS code to add the click event on the trigger to open the modal

1. Add the HTML for the modal

At the end of your page, before the closing </body> tag, at the following HTML snippet:

<div id="modal-js-example" class="modal">
  <div class="modal-background"></div>

  <div class="modal-content">
    <div class="box">
      <p>Modal JS example</p>
      <!-- Your content -->
    </div>
  </div>

  <button class="modal-close is-large" aria-label="close"></button>
</div>

The id attribute's value must be unique.

2. Add the HTML for the trigger

Somewhere on your page, add the following HTML button:

<button class="js-modal-trigger" data-target="modal-js-example">
  Open JS example modal
</button>

You can style it however you want, as long as it has the js-modal-trigger CSS class and the appropriate data-target value. For example, you can add the button is-primary Bulma classes:

3. Add the JS for the trigger

In a script element (or in a seperate .js file), add the following JS code:

document.addEventListener('DOMContentLoaded', () => {
  // Functions to open and close a modal
  function openModal($el) {
    $el.classList.add('is-active');
  }

  function closeModal($el) {
    $el.classList.remove('is-active');
  }

  function closeAllModals() {
    (document.querySelectorAll('.modal') || []).forEach(($modal) => {
      closeModal($modal);
    });
  }

  // Add a click event on buttons to open a specific modal
  (document.querySelectorAll('.js-modal-trigger') || []).forEach(($trigger) => {
    const modal = $trigger.dataset.target;
    const $target = document.getElementById(modal);

    $trigger.addEventListener('click', () => {
      openModal($target);
    });
  });

  // Add a click event on various child elements to close the parent modal
  (document.querySelectorAll('.modal-background, .modal-close, .modal-card-head .delete, .modal-card-foot .button') || []).forEach(($close) => {
    const $target = $close.closest('.modal');

    $close.addEventListener('click', () => {
      closeModal($target);
    });
  });

  // Add a keyboard event to close all modals
  document.addEventListener('keydown', (event) => {
    if (event.code === 'Escape') {
      closeAllModals();
    }
  });
});

As long as you can toggle the is-active modifier class on the modal element, you can choose how you want to implement it.

Variables #

Name
Type
Value
Computed Value
Computed Type
$modal-z
string
40
$modal-background-background-color
compound
bulmaRgba($scheme-invert, 0.86)
$modal-content-width
size
640px
$modal-content-margin-mobile
size
20px
$modal-content-spacing-mobile
size
160px
$modal-content-spacing-tablet
size
40px
$modal-close-dimensions
size
40px
$modal-close-right
size
20px
$modal-close-top
size
20px
$modal-card-spacing
size
40px
$modal-card-head-background-color
variable
$background
hsl(0, 0%, 96%)
color
$modal-card-head-border-bottom
size
1px solid $border
$modal-card-head-padding
size
20px
$modal-card-head-radius
variable
$radius-large
6px
size
$modal-card-title-color
variable
$text-strong
hsl(0, 0%, 21%)
color
$modal-card-title-line-height
string
1
$modal-card-title-size
variable
$size-4
1.5rem
size
$modal-card-foot-radius
variable
$radius-large
6px
size
$modal-card-foot-border-top
size
1px solid $border
$modal-card-body-background-color
variable
$scheme-main
hsl(0, 0%, 100%)
color
$modal-card-body-padding
size
20px
$modal-breakpoint
variable
$tablet
769px
size