Modal Disappearing Act
Now you see me, now you don’t
I built a modal. Armed with old faithful HTML, my good friend JavaScript, and my new friend CSS, building a modal can become a breeze.
A modal is an html element on a web page that allows you to overlay elements over a website after a specific event. The modal is hidden from the user and only becomes visible after a specific event. Modals are all over the internet. Common uses include forms at log in and advertisements.
Behold, in all of its disappearing act glory!
This modal has three building blocks.
- HTML : The modal is built with div elements in the body of the html file
- CSS: The style sheet defines the visual components of the modal divs as well as their animation fade ins and fade outs, going from hidden to visible.
- JavaScript: The scripts attach event listeners to elements of the DOM to listen for the clicks to trigger the fade in and fade out of the modal.
Let’s peek the HTML
There is a button
element with an id of myBtn
which will eventually trigger the modal’s appearance. There is a div
with an id of myModal
. This will be the parent of our modal-content
div
that will have our form
with an id of sign-up-form
nested inside. That’s the basics!
CSS
Our CSS file has a little more going on, including some animation properties. Here are the most important parts to getting our modal working. Let’s take a look at the style block for the .modal
class which houses the whole modal and effectively serves as the modal form’s background.
.modal {
display: none;
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-color: rgba(0,0,0,0.4);
animation-name: fade-in;
animation-duration: 1.0s
}.modal-content {
position: relative;
background-color: #fefefe;
margin: 10% auto;
padding: 20px;
border: 1px solid #888;
border-radius: 20px;
width: 80%;
animation-name: topdrop;
animation-duration: 1.0s
}
The display
property is set to none
. This makes the modal div hidden on the DOM when the page is loaded. The modal div is in the markup in index.html
, but invisible to the user on load. The position
set to fixed
ensures that the div will not change its position on the DOM. Setting left
and top
to 0
, and width
and height
to 100%
makes sure that the modal’s background covers the entire browser window and any content on the page. The background-color
is set with the rgba
property. The last value passed to rgba
is the opacity of the color on a scale from 0.0 to 1 with 0 being being completely transparent and 1 having no opacity at all. This setting rgba(0,0,0,0.4)
will give the modal a grey background.
CSS Animations and Keyframes
The final essential property is animation-name
and animation-duration
. CSS animations allow the gradual changing of an element’s property over time. Declaring an animation-name binds the CSS class to a @keyframe
. A @keyframe
is a declaration of which properties need to be changed in the animation sequence along with their starting values and ending values. The animation-duration defined on the class specifies the duration of the change. Check out the @keyframes defined in index.css
@keyframes topdrop {
from {top: -300px; opacity: 0}
to {top: 0; opacity: 1}
}@keyframes disappear {
from {top: 0; opacity: 1}
to {top: -300px; opacity: 0}
}@keyframes fade-in {
from {background-color: rgba(0,0,0,0);}
to {background-color: rgba(0,0,0,0.4 );}
}@keyframes fade-out {
from {background-color: rgba(0,0,0,0.4);}
to {background-color: rgba(0,0,0,0 );}
}
fade-in
and fade-out
will animate the opaque background. topdrop
will animate our modal form to appear by changing its top
value from -300px
to 0px
while disappear
will cause it to disappear in the same manner. animation-duration is the property in which we define how long the animation should take. Here, it is set to one second on both classes.
JavaScript
index.js
holds our JavaScript code that will set up our event listeners and trigger events on the DOM.
//index.jsdocument.addEventListener('DOMContentLoaded', () => {
const modal = document.getElementById('myModal');
const myBtn = document.getElementById('myBtn');
const span = document.getElementsByClassName('close')[0]
const form = document.getElementById('sign-up-form')
myBtn.addEventListener('click', () => openModal(modal) )
span.addEventListener('click', () => closeModal(modal))
form.addEventListener('submit', (event) => handleSubmit(form, modal))
})
First we set up an event listener on the DOM for when our content is loaded. Then we grab the elements of the DOM that we need listeners for and set them to variables.
Next, we take those DOM elements and add event listeners. We listen for a click on myBtn
to trigger the appearance of the modal. Our span
element, which appears on the DOM as an X will listen for a click to close the modal. Our form
element will listen for a submit in which we will alert
the user upon submission. All three of these event listeners take an event type and an event handler as parameters that we will use to manipulate the DOM.
Let’s look at our event handlers
//index.jsconst openModal = modal => {
modal.style.display = 'block';
}const closeModal = modal => {
const modalContent = modal.firstElementChild
modalContent.style.animationName = 'disappear';
modal.style.animationName = 'fade-out';
setTimeout(() => {
modalContent.style.animationName = 'topdrop';
modal.style.display = 'none';
modal.style.animationName = 'fade-in'
}, 1000)
}const handleSubmit = (form, modal) => {
event.preventDefault()
const name = form.elements.name.value
const email = form.elements.email.value
alert(`Hey ${name}! Your email is ${email}!`)
closeModal(modal)
form.reset()
}
openModal
. Short and sweet and what we have been waiting for! It takes in our modal element from the DOM and changes it’s style.display
property from ‘none’
to ‘block’
. After the click on myBtn
, our beautiful modal will become visible and its initial fade-in
and topdrop
animations will trigger.
closeModal
closes and fades the modal background. It takes in our whole modal
element and grabs the modal’s background and form. It sets the animationName
properties to disappear
for our form and fade-out
for our background. POOF! Our beautiful modal is gone. We then call setTimeout
that resets our display
and animiationName
properties to their original properties after one second (the time it takes the animation to finish). That way, we can click myBtn
again and the modal will behave as expected.
handleSubmit
takes in a user’s name and email and fired an alert box with their entered content. It then calls closeModal
to hide the modal. In a robust app, handleSubmit would send the user data to the backend for some work.
And that’s it! There are plenty of CSS libraries that can do this for you, but there is nothing like writing from scratch. Also, if you have made it this far and can see a more efficient way to build a modal, please shoot me a message! I’d love to hear from you!