Native Modal
Native modal component with enhancements and customisation
- Based on the <dialog> element
- Customizable and mutable animation
- Accessibility: labelled close button, keyboard control with focus trap
- Multiple source options: HTML string, DOM element, external file
- Easy to use: nui.modal(content), anchor or button
- Colour theme with CSS variables and dark mode support
- Shadow and rounded edges options
- Full window option
- Transparent modal on page scroll, because scroll blocking is a can of worms
- No dependencies
Originally hidden, attached modal content only.
How to use various content sources
<script>
nui.modal('<b>HTML</b> string')
</script>
<a target="_blank" href="index.html#sidebar" class="n-modal-link">Open a modal with external file content</a>
<button data-href="index.html#sidebar" class="n-modal-link">Open a modal with external file content via a button</button>
<dialog class="n-modal" id="modal1">
<button class="n-modal__close"></button>
<div class="n-modal__content">
...
</div>
</dialog>
<button class="n-modal-link" data-for="modal1">Open an attached modal</button>
<script>
nui.modal(document.getElementById('modal1'));
</script>
<script>
var modal = document.createElement('dialog');
modal.classList.add('n-modal');
modal.innerHTML = `
<button class="n-modal__close"></button>
<div class="n-modal__content">
<p>Originally detached modal.</p>
</div>
`;
nui.modal(modal);
</script>
<div class="n-modal__content" id="modal2">
...
</div>
<button class="n-modal-link" data-for="modal2">Open a modal with attached, hidden content</button>
<div id="modal3">...</div>
<button class="n-modal-link" data-for="modal3">Open a modal with attached content</button>
<script>
let p = document.createElement('p');
p.innerText = 'Detached paragraph';
nui.modal(p);
</script>
How to customise the presentation
Custom animation
<a target="_blank" href="index.html" class="n-modal-link" data-anim="[{ "opacity": 0 }, { "opacity": 1 }]">Open a modal with custom animation</a>
<button data-href="index.html#sidebar" class="n-modal-link" data-anim="[{ "opacity": 0 }, { "opacity": 1 }]">Custom animation</button>
<script>
nui.modal({content: 'Custom animation', animation: '[{ "opacity": 0 }, { "opacity": 1 }]'});
</script>
<a target="_blank" href="index.html" class="n-modal-link n-modal--shadow">Shadow</a>
<button data-href="index.html" class="n-modal-link n-modal--shadow">Shadow</button>
<script>
nui.modal({content: 'Shadow', shadow: true})
</script>
<dialog class="n-modal n-modal--shadow" id="modal-shadow">
<button class="n-modal__close"></button>
<div class="n-modal__content"> ... </div>
</dialog>
<script>
nui.modal(document.getElementById('modal-shadow'));
</script>
<a target="_blank" href="index.html" class="n-modal-link n-modal--rounded">Rounded</a>
<button data-href="index.html" class="n-modal-link n-modal--rounded">Rounded</button>
<script>
nui.modal({content: 'Rounded', rounded: true})
</script>
<dialog class="n-modal n-modal--rounded" id="modal-rounded">
<button class="n-modal__close"></button>
<div class="n-modal__content"> ... </div>
</dialog>
<script>
nui.modal(document.getElementById('modal-rounded'));
</script>
<a target="_blank" href="index.html" class="n-modal-link n-modal--full">Full modal</a>
<button data-href="index.html" class="n-modal-link n-modal--full">Full</button>
<script>
nui.modal({content: 'Full', full: true});
</script>
<dialog class="n-modal n-modal--full" id="modal-full">
<button class="n-modal__close"></button>
<div class="n-modal__content"> ... </div>
</dialog>
<script>
nui.modal(document.getElementById('modal-full'));
</script>
<a target="_blank" href="index.html" class="n-modal-link n-modal--blur">Blur</a>
<button data-href="index.html" class="n-modal-link n-modal--blur">Blur</button>
<script>
nui.modal({content: 'Blur', blur: true});
</script>
<dialog class="n-modal n-modal--blur" id="modal-blur">
<button class="n-modal__close"></button>
<div class="n-modal__content"> ... </div>
</dialog>
<script>
nui.modal(document.getElementById('modal-blur'));
</script>
<a target="_blank" href="index.html" class="n-modal-link" data-close-symbol="⤫" data-close-label="Close this modal">Custom Close button</a>
<button data-href="index.html" class="n-modal-link" data-close-symbol="⤫" data-close-label="Close this modal">Custom Close button</button>
<script>
nui.modal({content: 'Custom Close button', closeSymbol: '⤫', closeLabel: 'Fermer'});
</script>
<dialog class="n-modal" id="modal1">
<button class="n-modal__close" aria-label="Fermer" data-close-symbol="Schliessen"></button>
<div class="n-modal__content"> ... </div>
</dialog>
<script>
nui.modal(document.getElementById('modal1'));
</script>
Options
- Customisation of .n-modal-link links and buttons:
- Styling classes .n-modal--blur, .n-modal--shadow, .n-modal--rounded, .n-modal--full (also apply to existing dialog.n-modal elements)
- Attribute data-anim for custom open animation in Element.animate() format (with HTML-entities-encoded quotes)
- Attribute data-close-label specifying the close button label (default "Close")
- Attribute data-close-symbol specifying the close button content (default "X")
- An .n-modal-link button's source is specified by its data-href attribute
- nui.modal() accepts either a single parameter (HTML string or element as content source) or {content: "", options...} where options can be blur, rounded, shadow and full. They are enabled by assigning the true value. Another option is animation for custom open animation. closeLabel specifies the close button label (default "Close"), while closeSymbol specifies the close button content (default "X")
- External file source file.html#element-id will load only the element with ID element-id
- nui.modal.init(container) hydrates newly added components. The container parameter is optional and defaults to the whole document
- dialog.n-modal.n-modal--uri will be opened automatically on page load if the URI hash matches its ID
- Theme CSS variables: --nui-color, --nui-bg, --nui-control-color, --nui-control-bg