---
title: Modal
layout: docs
theme: library
doc-tab: components
doc-subtab: modal
breadcrumb:
- home
- documentation
- components
- components-modal
meta:
  colors: false
  sizes: false
  variables: true
modals:
- docs/modals/example-modal.html
- docs/modals/example-modal-bis.html
- docs/modals/example-modal-ter.html
- docs/modals/example-js-modal.html
---
{% capture modal %}
<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>
{% endcapture %}

{% capture image_modal %}
<div class="modal">
  <div class="modal-background"></div>
  <div class="modal-content">
    <p class="image is-4by3">
      <img src="{{site.url}}/assets/images/placeholders/1280x960.png" alt="">
    </p>
  </div>
  <button class="modal-close is-large" aria-label="close"></button>
</div>
{% endcapture %}

{% capture 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">
      <div class="buttons">
        <button class="button is-success">Save changes</button>
        <button class="button">Cancel</button>
      </div>
    </footer>
  </div>
</div>
{% endcapture %}

{% capture modal_js_html %}
<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>
{% endcapture %}

{% capture modal_js_trigger %}
<button class="js-modal-trigger" data-target="modal-js-example">
  Open JS example modal
</button>
{% endcapture %}

{% capture modal_js_trigger_bulma %}
<button class="js-modal-trigger button is-primary" data-target="modal-js-example">
  Open JS example modal
</button>
{% endcapture %}

{% capture modal_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.key === "Escape") {
      closeAllModals();
    }
  });
});
{% endcapture %}

<!--  -->

<div class="content">
  <p>The modal structure is very simple:</p>
  <ul>
    <li>
      <code>modal</code>: the main container
      <ul>
        <li><code>modal-background</code>: a transparent overlay that can act as a click target to close the modal</li>
        <li>
          <code>modal-content</code>: a horizontally and vertically centered container, with a maximum width of 640px,
          in which you can include <em>any</em> content
        </li>
        <li><code>modal-close</code>: a simple cross located in the top right corner</li>
      </ul>
    </li>
  </ul>
  <p>
    <button class="button is-primary is-large modal-button js-modal-trigger" data-target="modal" aria-haspopup="true">
      Launch example modal
    </button>
  </p>
</div>

{% highlight html -%}
{{- modal -}}
{%- endhighlight %}

<div class="content">
  <p>
    To <strong>activate</strong> the modal, just add the <code>is-active</code> modifier on the
    <code>.modal</code> container. You may also want to add <code>is-clipped</code> modifier to a containing element
    (usually <code>html</code>) to stop scroll overflow.
  </p>
</div>

<div class="message is-info">
  <div class="message-header">JavaScript implementation example</div>
  <div class="message-body">
    Bulma does not include any JavaScript. However, this documentation provides a
    <a href="#javascript-implementation-example">JS implementation example</a> that you are free to use.
  </div>
</div>

{% include docs/elements/anchor.html name="Image modal" %}

<div class="content">
  <p>
    Because a modal can contain <strong>anything you want</strong>, you can very simply use it to build an image gallery
    for example:
  </p>
  <p>
    <a class="button is-primary is-large modal-button js-modal-trigger" data-target="modal-bis">Launch image modal</a>
  </p>
</div>

{% highlight html -%}
{{- image_modal -}}
{%- endhighlight %}

{% include docs/elements/anchor.html name="Modal card" %}

<div class="content">
  <p>
    If you want a more classic modal, with a <strong>head</strong>, a <strong>body</strong> and a <strong>foot</strong>,
    use the <code>modal-card</code>.
  </p>
  <p>
    <button
      class="button is-primary is-large modal-button js-modal-trigger"
      data-target="modal-ter"
      aria-haspopup="true"
    >
      Launch card modal
    </button>
  </p>
</div>

<div class="bd-highlight-full">
  {% highlight html -%}
  {{- modal_card -}}
  {%- endhighlight %}
</div>

{% include docs/elements/anchor.html name="JavaScript implementation example" %}

<div class="content">
  <p>
    The Bulma package <strong>does not come with any JavaScript</strong>. Here is however an implementation example,
    which sets the <code>click</code> handlers for custom elements, in vanilla JavaScript.
  </p>

  <p>There are 3 parts to this implementation:</p>

  <ul>
    <li>add the HTML for the <strong>modal</strong> (this modal is hidden by default)</li>
    <li>
      add the HTML for a button to <strong>trigger</strong> the modal (you can style this button however you want)
    </li>
    <li>
      add the JS code to add the <code>click</code> event on the <strong>trigger</strong> to open the
      <strong>modal</strong>
    </li>
  </ul>
</div>

<div class="content">
  <h4>1. Add the HTML for the modal</h4>

  <p>At the end of your page, before the closing <code>&lt;/body&gt;</code> tag, at the following HTML snippet:</p>
</div>

{% highlight html -%}
{{- modal_js_html -}}
{%- endhighlight %}

<div class="content">
  <p>The <code>id</code> attribute's value must be <strong>unique</strong>.</p>
</div>

<div class="content">
  <h4>2. Add the HTML for the trigger</h4>

  <p>Somewhere on your page, add the following HTML button:</p>
</div>

<div class="block">
  {{ modal_js_trigger }}
</div>

{% highlight html -%}
{{- modal_js_trigger -}}
{%- endhighlight %}

<div class="content">
  <p>
    You can style it however you want, as long as it has the <code>js-modal-trigger</code> CSS class and the appropriate
    <code>data-target</code> value. For example, you can add the <code>button is-primary</code> Bulma classes:
  </p>
</div>

<div class="block">
  {{ modal_js_trigger_bulma }}
</div>

<div class="content">
  <h4>3. Add the JS for the trigger</h4>

  <p>In a <code>script</code> element (or in a seperate <code>.js</code> file), add the following JS code:</p>
</div>

{% highlight javascript -%}
{{- modal_js_code -}}
{%- endhighlight %}

<div class="content">
  <p>
    As long as you can toggle the <code>is-active</code> modifier class on the <code>modal</code> element, you can
    choose how you want to implement it.
  </p>
</div>



<script type="text/javascript">
  {
    {
      modal_js_code;
    }
  }
</script>
