Interactive examples of hcg-modal, a small, dependency-free popup modal in vanilla JavaScript. Click the buttons below to try sizes, positions, custom width, scroll modes, animations, auto-close timers, layered stacking, and bring-your-own-box dialogs. Full documentation is available at html-code-generator.com/javascript/modal-popup-library.
hcgModal({ size: 'small', content: '...' }).open();
// size: 'small' | 'medium' | 'large' | 'fullscreen'hcgModal({ width: 600, content: '...' }).open(); // number -> px
hcgModal({ width: '70%', content: '...' }).open(); // any CSS lengthAnimation comes entirely from the .demo-anim CSS class (in this page's
<style>) passed via the className option - the modal JS is untouched.
It animates in on open and out on close.
Requires a browser without reduced motion enabled.
/* CSS - start state + .hcg-modal--visible end state */
.demo-anim .hcg-modal-dialog {
opacity: 0; transform: translateY(40px) scale(.96);
transition: transform .4s, opacity .4s;
}
.demo-anim.hcg-modal--visible .hcg-modal-dialog { opacity: 1; transform: none; }
/* JS - drive the animation purely via className */
hcgModal({ content: '...', className: 'demo-anim' }).open();Ship-with-the-library classes passed via className - no extra CSS needed.
They use a spring easing curve and honor reduced motion (turn on OS animation
effects to see them).
hcgModal({ content: '...', className: 'hcg-modal--anim-fade' }).open();
hcgModal({ content: '...', className: 'hcg-modal--anim-slide' }).open();
hcgModal({ content: '...', className: 'hcg-modal--anim-pop' }).open();
// slide direction follows `position` (top / center / bottom)hcgModal({ position: 'top', content: '...' }).open();
// position: 'center' | 'top' | 'bottom'// Promise result - await the clicked button's value
const ok = await hcgModal({
title: 'Delete item?',
buttons: [
{ text: 'Cancel', value: false },
{ text: 'Delete', type: 'danger', value: true }
]
}).opened(); // dismissing resolves undefined
// beforeClose veto - return false (or a Promise) to cancel the close
hcgModal({ beforeClose: (reason) => window.confirm('Close?') }).open();
// auto-close timer + progress bar (pauses on hover)
hcgModal({ content: 'Saved', timer: 3000, timerProgressBar: true }).open();
// Enter triggers the primary button
hcgModal({ confirmOnEnter: true, buttons: [
{ text: 'No', value: 'no' },
{ text: 'Yes', type: 'primary', value: 'yes' }
]}).opened();hcgModal({ content: longHtml }).open(); // default: body scrolls, header/footer pinned
hcgModal({ scrollBody: false, content: longHtml }).open(); // whole dialog scrollshcgModal({ closeOnBackdrop: false }).open(); // backdrop click won't close
hcgModal({ closeOnEsc: false }).open(); // Escape won't close
hcgModal({ showClose: false }).open(); // no X buttonUse an existing HTML box (heading + content + footer) as the modal, instead of the
built-in title / buttons options.
<div id="myBox" style="display:none">
<div class="box-head">Heading</div>
<div class="box-body">Content</div>
<button class="close">Cancel</button> <!-- auto-wired -->
</div>
const box = document.getElementById('myBox').cloneNode(true);
hcgModal({ box: box }).open(); // box = the whole dialoghcgModal({ content: '...', className: 'hcg-modal--glass' }).open();Opens with closeOnBackButton: true. Press the browser/mobile Back
button (or swipe back) and the modal closes instead of navigating away. Closing it
with the X or Esc cleans up the history entry.
hcgModal({ content: '...', closeOnBackButton: true }).open();hcgModal({
title: 'Delete item?',
content: '...',
buttons: [
{ text: 'Cancel', type: 'secondary', onClick: m => m.close() },
{ text: 'Delete', type: 'danger', onClick: m => { /* ... */ m.close(); } }
]
}).open();Each layer opens above the previous one. Press Esc (or use the close
button) to dismiss them from the top down - C first, then B, then A.
hcgModal({
title: 'Layer A',
buttons: [
{ text: 'Open layer B', type: 'primary', onClick: () => {
hcgModal({ title: 'Layer B', content: '...' }).open(); // stacks on top
} },
{ text: 'Close A', type: 'secondary', onClick: m => m.close() }
]
}).open();
// Esc / back button close from the top down: C, then B, then ATall content to make the page scrollable.