Modal and dropdown
A modal (modal) appears over the page and dims everything else: confirm a deletion, fill in a short form. A dropdown (dropdown) opens a list of actions under a button. Bulma draws both, but your JavaScript has to open and close them: the element is visible only while it has the is-active class.
Modal
A modal has three parts: the modal-background overlay, the modal-content and the modal-close cross button. The markup goes at the end of <body>:
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@1.0.4/css/bulma.min.css">
<div style="min-height: 260px">
<button class="button is-danger js-open" data-target="cancel-modal">Cancel order</button>
</div>
<div class="modal" id="cancel-modal">
<div class="modal-background"></div>
<div class="modal-content">
<div class="box">
<p class="title is-5">Cancel order #1042?</p>
<p class="mb-4">The guest will be notified about the cancellation.</p>
<div class="buttons">
<button class="button is-danger">Yes, cancel</button>
<button class="button js-close">No</button>
</div>
</div>
</div>
<button class="modal-close is-large" aria-label="Close"></button>
</div>
<script>
const openModal = (modal) => modal.classList.add('is-active');
const closeModal = (modal) => modal.classList.remove('is-active');
document.querySelectorAll('.js-open').forEach((button) => {
const modal = document.getElementById(button.dataset.target);
button.addEventListener('click', () => openModal(modal));
});
document.querySelectorAll('.modal-background, .modal-close, .js-close').forEach((el) => {
el.addEventListener('click', () => closeModal(el.closest('.modal')));
});
document.addEventListener('keydown', (event) => {
if (event.key === 'Escape') {
document.querySelectorAll('.modal.is-active').forEach(closeModal);
}
});
</script>Click the red button: the background dims and a white window with the question appears in the centre. The cross, the "No" button, a click on the overlay and the Escape key close it — the script handles each of these separately. The min-height block is only there to give the modal enough height in the preview.
A modal card
For a modal with a header and buttons at the bottom, use modal-card instead of modal-content:
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@1.0.4/css/bulma.min.css">
<div style="min-height: 300px"></div>
<div class="modal is-active">
<div class="modal-background"></div>
<div class="modal-card">
<header class="modal-card-head">
<p class="modal-card-title">New dish</p>
<button class="delete js-close" aria-label="Close"></button>
</header>
<section class="modal-card-body">A form with the name and price goes here.</section>
<footer class="modal-card-foot">
<div class="buttons">
<button class="button is-success">Save</button>
<button class="button js-close">Cancel</button>
</div>
</footer>
</div>
</div>A modal with a grey header, a white body and buttons at the bottom. To make it visible in the preview straight away, the modal already has is-active; in a project the script from the example above sets that class. The modal-close button is not used here: the delete cross in the header and "Cancel" close the modal, and their js-close class is already in that script's selector list.
Dropdown
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@1.0.4/css/bulma.min.css">
<div style="min-height: 180px">
<div class="dropdown" id="order-actions">
<div class="dropdown-trigger">
<button class="button" aria-haspopup="true" aria-controls="order-menu">Actions ▾</button>
</div>
<div class="dropdown-menu" id="order-menu" role="menu">
<div class="dropdown-content">
<a href="#" class="dropdown-item">Print receipt</a>
<a href="#" class="dropdown-item">Edit</a>
<hr class="dropdown-divider">
<a href="#" class="dropdown-item has-text-danger">Delete</a>
</div>
</div>
</div>
</div>
<script>
const dropdown = document.getElementById('order-actions');
dropdown.querySelector('.dropdown-trigger button').addEventListener('click', (event) => {
event.stopPropagation();
dropdown.classList.toggle('is-active');
});
document.addEventListener('click', () => dropdown.classList.remove('is-active'));
</script>Click "Actions" and a white list of three items opens under the button. A click anywhere else on the page closes it: stopPropagation stops the click on the button from reaching document straight away.
Without JavaScript
If opening the menu on mouse hover is enough, no script is needed: add the is-hoverable modifier to the dropdown. Phones have no hover, though, so for mobile sites the click version is more reliable. The is-right and is-up modifiers align the menu to the right edge or open it upwards.
Common mistake
Placing a modal inside a card or a column. If a parent has transform or overflow: hidden, the modal may be clipped or not centred on the screen. Keep the modal markup directly in <body>, at the end of the page.