Vanilla JS + CSS - Modal Popup (Dialog) Tutorial with Example
Example built with Vanilla JS and CSS
Other versions available:
This is a quick post to show how easy it is to implement modal popups in pure HTML, CSS and JavaScript.
JS + CSS Example App
The example app contains a single page with some text and a couple of buttons to open two modal popups:
- Modal #1 - a simple custom modal popup.
- Modal #2 - a tall popup to demonstrate that the modal is scrollable while keeping the page below locked in position.
Here it is in action: (See on StackBlitz at https://stackblitz.com/edit/vanilla-js-css-modal-popup-example)
The HTML, CSS and JavaScript Code
The example app consists of just three files for the HTML, Vanilla JS and CSS code:
Modal HTML
The index.html file contains three main div
elements, one for the page heading and buttons to open the modals (modal-1
and modal-2
), and two divs for the modals themselves.
It includes styles.css
and script.js
in the head to handle modal styling and behaviour.
Unique id required
Each modal must have a unique id
attribute (e.g. <div id="modal-1">
), it is used to identify which modal you want to open when calling the open modal function (e.g. openModal('modal-1')
).
<!DOCTYPE html>
<html>
<head>
<title>Vanilla JS + CSS - Modal Popup Example</title>
<meta name="viewport" content="width=device-width" />
<link rel="stylesheet" href="styles.css" />
<script src="script.js"></script>
</head>
<body>
<!-- main app container -->
<div>
<div>
<h1>Vanilla JS + CSS - Modal Popup Example</h1>
<p>Click the buttons below to open the example modals</p>
<button onclick="openModal('modal-1')">Open Modal 1</button>
<button onclick="openModal('modal-2')">Open Modal 2</button>
</div>
<div id="modal-1" class="jw-modal">
<div class="jw-modal-body">
<h1>A custom modal popup</h1>
<button onclick="closeModal()">Close</button>
</div>
</div>
<div id="modal-2" class="jw-modal">
<div class="jw-modal-body">
<h1>A tall modal popup</h1>
<p style="padding-bottom: 1500px;">Close with the button below or by clicking the background.</p>
<button onclick="closeModal()">Close</button>
</div>
</div>
</div>
</body>
</html>
Modal JavaScript
JavaScript is used to implement modal behaviour, i.e. opening and closing modal popups.
Modal functions
openModal() - makes the modal appear by adding the CSS class open
to the modal element. Adds the jw-modal-open
CSS class to the <body>
tag to lock scrolling on the underlying body.
closeModal() - makes the modal disappear by removing the open
class from the modal element. Removes the jw-modal-open
CSS class from the <body>
tag to unlock scrolling on the body.
Close on background click
On window load a 'click'
event listener is added to the document to close any modal on background click.
// open modal by id
function openModal(id) {
document.getElementById(id).classList.add('open');
document.body.classList.add('jw-modal-open');
}
// close currently open modal
function closeModal() {
document.querySelector('.jw-modal.open').classList.remove('open');
document.body.classList.remove('jw-modal-open');
}
window.addEventListener('load', function() {
// close modals on background click
document.addEventListener('click', event => {
if (event.target.classList.contains('jw-modal')) {
closeModal();
}
});
});
Modal CSS Styles
This stylesheet is the main file in the modal tutorial, the below CSS styles are what turn a couple of divs in the HTML into modal popups in your browser. The javascript code just controls opening and closing.
General styles
The top of the file contains a few styles to pretty up the example a bit since it doesn't use Bootstrap or anything other CSS.
Modal styles
.jw-modal
- the root element of each modal is set to hidden (closed) by default. The outer container div is fixed across the whole screen above all other elements with a semi-transparent black background and scrolling enabled in case the content is longer than the screen.
.jw-modal.open
- the root modal element is visible when it includes the open
class.
.jw-modal-body
- the inner container div just has a white background and some padding.
body.jw-modal-open
- this class is added to the HTML <body>
tag when a modal is open. Scrolling is disabled on the underlying body content when a modal is open above.
Prefixed with jw-
I prefixed the modal classes with jw-
to prevent name clashes with any 3rd party CSS libraries you might be using (e.g. Bootstrap).
/* GENERAL STYLES
-------------------------------*/
body {
font-family: Arial, Helvetica, sans-serif;
padding: 20px;
}
h1 {
font-weight: normal;
margin-top: 0;
}
button {
padding: 7px 10px;
margin-right: 5px;
}
/* MODAL STYLES
-------------------------------*/
.jw-modal {
/* modals are hidden by default */
display: none;
/* modal container fixed across whole screen */
position: fixed;
inset: 0;
/* z-index must be higher than everything else on the page */
z-index: 10000;
/* semi-transparent black background exposed by padding */
background-color: rgba(0, 0, 0, .75);
padding: 40px;
/* enables scrolling for tall modals */
overflow: auto;
}
.jw-modal.open {
display: block;
}
.jw-modal-body {
padding: 20px;
background: #fff;
}
body.jw-modal-open {
/* body overflow is hidden to hide main scrollbar when modal window is open */
overflow: hidden;
}
Need Some Vanilla JS Help?
Search fiverr for freelance Vanilla JS developers.
Follow me for updates
When I'm not coding...
Me and Tina are on a motorcycle adventure around Australia.
Come along for the ride!