bulma/docs/documentation/components/modal.html
Jeremy Thomas 69877a652c Init v1
2024-03-21 16:11:54 +00:00

308 lines
8.0 KiB
HTML

---
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>