DEV Community

Ediomo Jose
Ediomo Jose

Posted on

Pop-up Modal: Using HTML, CSS, and JavaScript to Create a Modal.

An introduction to using modal pop-ups to make your website more engaging and interactive.

Introduction

This article's main focus is on using the HTML dialog element to create a Modal Pop-up. To do this, we'll develop a subscription form that pops up a Modal success message after the form is submitted.

Prerequsite

  • JavaScript fundamentals (beginning level is acceptable; I'd go into great length to explain everything )
  • You have a basic understanding of HTML and CSS and have used them to build at least one webpage.
  • An editor for code (VS Code is suggested).
  • Of course, a browser—we advise using Chrome or Firefox.

Table of content

  • What is a Modal?
  • When to use a Modal.
  • Exploring the HTML Dialog element.
  • The open attribute
  • Building our HTML Structure
  • Building our form structure.
  • Building our Modal Pop-up using the HTML Dialog element.
  • Styling our form
  • Styling our dialog
  • Backdrop pseudo-element
  • Adding JavaScript functionality to our elements.
  • Javascript show() and showmodal() function.
  • Javascript close() function.

What is a Modal?

A modal is a type of display that pops up as an overlay over the main page of a website, its appearance deactivates all the page content just like an alert. But the difference is that a modal needs to be interacted with to deactivate, it either comes with a dismiss button or is deactivated when the user clicks on the keyboard or the mouse.
Modals do not allow users to interact with the web page when it appears. Aside from interactivity, modals allow for focusing increase in the user focus as it appears.

Image description

When to use a modal

Modals can be used for a variety of purposes, which are alerts, warnings, confirmations,
Forms, media shows(Like videos and music), and an onboarding page for a multi-step procedure as an example.

Exploring the HTML dialog element

The dialog element is a representation of a dialog box or other interactive web components, like a subwindow or an alert that can be dismissed. It is simple to develop an interactive modal thanks to the dialog element.

<dialog>

</dialog>
Enter fullscreen mode Exit fullscreen mode

The open attribute -

Without the open attribute, the dialog element will be hidden from our browser by default. Additionally, it will allow us to see the dialog's content as we style it using CSS.

Image description

The open attribute appears as follows:

<dialog open>

</dialog>
Enter fullscreen mode Exit fullscreen mode

Building our HTML structure

Building the form

We will create a subscription form that asks for the user's email address before we can develop the structure of how our modal should appear. When the subscribe button is hit, a modal with a confirmation message will appear.

<section class="signup__container">
        <picture>
          <source
            media="(min-width:700px)"
            srcset="./assets/images/illustration-sign-up desktop.svg"
            class="desktop__img"
          />
          <img
          src="./assets/images/illustration-sign-up-mobile.svg"
          alt=""
          srcset=""
          class="mobile__img"
        />
        </picture>
        <form method="dialog">
          <h1 class="form__header">Stay updated!</h1>
          <p class="form__paragraph">
            Join 60,000+ product managers receiving monthly updates on:
          </p>
          <ul class="outline">
            <li class="outline__text">
              Product discovery and building what matters
            </li>
            <li class="outline__text">
              Measuring to ensure updates are a success
            </li>
            <li class="outline__text">And much more!</li>
          </ul>
          <div class="label__error__text">
            <label for="email__address">Email Address</label>
            <span class="error__state__text"></span>
          </div>

          <input
            type="email"
            name="email"
            id="email__address"
            placeholder="email@company.com"
          />
          <button class="form__submit" type="submit">Subscribe to monthly newsletter</button>
        </form>
</section>
    <!-- Sign-up form end -->
Enter fullscreen mode Exit fullscreen mode

The form method is dialog, which is a crucial point to keep in mind.

Building the modal

As demonstrated in the code below, the dialog element must be used to create the modal.

<dialog>

<dialog/>
Enter fullscreen mode Exit fullscreen mode

We must use the open attribute, which was discussed at the beginning of this article, to see the result of what our dialog structure will look like. Remember to remove the open attribute once you're finished because adding it only serves to show the developer how the modal would appear on his browser.

Code breakdown

If you carefully go through the code, you will notice that we created a div with the class success__msg__container, which contains the entire content of our success message. If I give the dialog element a display grid property directly, we will have defeated the purpose of a dialog because the dialog would no longer disappear from view even if the open attribute was removed. I took this step because I want to give a display grid property to the sccess__msg__container.

<dialog class="success__msg">
      <div class="success__msg__container">
        <img src="./assets/images/icon-success.svg" alt="" />
        <h2 class="success__msg__head">
          Thanks for subscribing!
        </h2>
        <p class="success__note">
          A confirmation email has been sent to
          <span id="user__email__address"></span>. Please open
          it and click the button inside to confirm your subscription.
        </p>
        <button type="button" title="dismiss" class="dismiss__btn">Dismiss message</button>
      </div>
</dialog>
Enter fullscreen mode Exit fullscreen mode

Also, take note that we added a button after adding all the content that is required and that we wish to display. The modal will be closed when this button is clicked.

Finally, here is the structure of our HTML code.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Newsletter sign-up form with success message</title>
    <link rel="stylesheet" href="style.css" />
    <script src="./script.js" defer></script>
  </head>
  <body>
    <!-- Sign-up form start -->


      <section class="signup__container">
        <picture>
          <source
            media="(min-width:700px)"
            srcset="./assets/images/illustration-sign-up-desktop.svg"
            class="desktop__img"
          />
          <img
          src="./assets/images/illustration-sign-up-mobile.svg"
          alt=""
          srcset=""
          class="mobile__img"
        />
        </picture>
        <form method="dialog">
          <h1 class="form__header">Stay updated!</h1>
          <p class="form__paragraph">
            Join 60,000+ product managers receiving monthly updates on:
          </p>
          <ul class="outline">
            <li class="outline__text">
              Product discovery and building what matters
            </li>
            <li class="outline__text">
              Measuring to ensure updates are a success
            </li>
            <li class="outline__text">And much more!</li>
          </ul>
          <div class="label__error__text">
            <label for="email__address">Email Address</label>
            <span class="error__state__text"></span>
          </div>

          <input
            type="email"
            name="email"
            id="email__address"
            placeholder="email@company.com"
          />
          <button class="form__submit" type="submit">Subscribe to monthly newsletter</button>
        </form>
      </section>
    <!-- Sign-up form end -->

    <!-- Success message start -->
    <dialog class="success__msg">
      <div class="success__msg__container">
        <img src="./assets/images/icon-success.svg" alt="" />
        <h2 class="success__msg__head">
          Thanks for subscribing!
        </h2>
        <p class="success__note">
          A confirmation email has been sent to
          <span id="user__email__address"></span>. Please open
          it and click the button inside to confirm your subscription.
        </p>
        <button type="button" title="dismiss" class="dismiss__btn">Dismiss message</button>
      </div>

    </dialog>
    <!-- Success message end -->
  </body>
</html>

Enter fullscreen mode Exit fullscreen mode

Take note of the class name given to each of the elements.

Styling our Form and our Dialog Element

The first step is to link our CSS stylesheet to our HTML file. Since the modal is the main focus of this article, I created some basic styling for the form and its container. We also added some basic styling to our dialog, which you can see in the code below.

@import url("https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap");
@import url("https://fonts.googleapis.com/css2?family=Roboto+Condensed&display=swap");

:root {
  --sucesspage-list: url(./assets/images/icon-list.svg);
  --dark-slate-grey: hsl(234, 29%, 20%);
  --charcoal-grey: hsl(235, 18%, 26%);
  --grey: hsl(231, 7%, 60%);
  --tomato: hsl(4, 100%, 67%);
  --white: hsl(0, 0%, 100%);
}

html {
  scroll-behavior: smooth;
}

*,
*::before,
*::after {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

img {
  max-width: 100%;
}

body {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
  font-family: "Roboto", sans-serif;
  font-size: 1rem;
  background-color: var(--white);
}

.signup__container {
  display: grid;
  grid-template-columns: repeat(1, 1fr);
  grid-auto-flow: dense;
  border: none;
  border-radius: 0.5rem;
  margin: 2rem 1.2rem;
  box-shadow: 1px 2px 5px var(--grey);
}

.mobile__img {
  border-radius: 10px;
}

form {
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 1.5rem 1rem;
  gap: 1rem;
  color: var(--dark-slate-grey);
}

.form__header {
  font-size: 2em;
}

.form__paragraph {
  font-size: 0.9em;
  margin-bottom: 0.8rem;
}

.outline {
  list-style: none;
  font-size: 0.9em;
}

.outline__text {
  margin-bottom: 1rem;
  display: flex;
  gap: 1rem;
}

.outline__text::before {
  content: var(--sucesspage-list);
}

.label__error__text {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

label {
  font-weight: bold;
  font-size: 0.8em;
  color: var(--dark-slate-grey);
}

.error__state__text {
  font-weight: bold;
  font-size: 0.8em;
  color: red;
}

input {
  padding: 0.7rem;
  font-size: 1em;
  font-family: "Roboto Condensed", sans-serif;
  border-radius: 0.4rem;
  border: 1px solid var(--grey);
}

form button {
  padding: 1.2rem;
  margin-bottom: 2rem;
  background: var(--dark-slate-grey);
  color: var(--white);
  font-family: "Roboto", sans-serif;
  font-weight: 700;
  outline: none;
  border: none;
  border-radius: 0.4rem;
  cursor: pointer;
  box-shadow: 1px 2px 5px var(--grey);
  transition: all 5s ease;
}

form button:hover{
  background: linear-gradient(0.25turn,#e04313, hsl(4, 100%, 67%));
}

.success__msg {
  margin: auto;
  height: 70vh;
  width: 100%;
  padding: 3rem 2rem;
  border: none;
  border-radius: 1rem;
}

dialog::backdrop {
  background-color: hsl(234, 29%, 20%);
}

.success__msg__container {
  display: grid;
  grid-template-columns: repeat(1, 1fr);
  gap: 2rem;

}

.success__msg__head {
  font-size: 2.5em;
  color: var(--dark-slate-grey);
}

.success__note {
  color: var(--dark-slate-grey);
  line-height: 1.5rem;
}

#user__email__address {
  font-weight: 700;
}

.dismiss__btn {
  padding: 0.9rem;
  background: var(--dark-slate-grey);
  color: var(--white);
  font-family: "Roboto", sans-serif;
  font-weight: 700;
  outline: none;
  border: none;
  border-radius: 0.4rem;
  cursor: pointer;
  box-shadow: 1px 2px 5px var(--grey);
  transition: all 0.5s ease-in-out;
}

.dismiss__btn:hover {
  background: linear-gradient(0.25turn,#e04313, hsl(4, 100%, 67%));

}

/* Js class */

.error__state {
  border: 2px solid red;
}

.error__placeholder::placeholder {
  color: red;
}

.input__background {
  background-color: rgba(219, 26, 26, 0.1);
}

.body__position {
  position: fixed;
}

@media (width >= 600px) {
  body {
    margin: auto;
  }

  .signup__container {
    grid-template-columns: repeat(2, 1fr);
    margin: 0;
    width: 80%;
    border-radius: 1rem;
  }

  form button {
    margin: 0;
  }

  picture {
    grid-column: 2;
    padding: 1rem;
    display: flex;
  }

  .success__msg {
    width: 50%;
    height: 45vh;
    padding: 2rem;
  }

  .success__msg__container {
    gap: 2rem;
  }
}

@media (width >= 1024px) {
  .signup__container {
    width: 50%;
  }

  .success__msg {
    width: 30%;
    min-height: 70vh;
  }

  .success__msg__container {
    gap: 1rem;
  }
}

@media (width >= 1800px) {
  .signup__container {
    width: 35%;
  }

  .success__msg {
    width: 20%;
    min-height: 50%;
    padding: 2rem;
  }
}
Enter fullscreen mode Exit fullscreen mode

Backdrop pseudo-element

The area behind our dialog is styled using the ::backdrop pseudo-element in this case, we gave it a background color.

dialog::backdrop {
  background-color: hsl(234, 29%, 20%);
}

Enter fullscreen mode Exit fullscreen mode

Moda pop-up large screen

Modal pop-up mobile

Adding JavaScript functionality to our elements.

Moving on to where the magic happens, we'll get a detailed understanding of how the modal pop-up is triggered, but first, we'll run a few lines of code to authenticate the input field. Although there are other methods of form authentication, for the purposes of this article, we'll stick with this one.

const pageBody = document.querySelector("body");
const openModalBtn = document.querySelector(".form__submit");
let emailInput = document.querySelector("#email__address");
let errorStateText = document.querySelector(".error__state__text");
const successMessage = document.querySelector(".success__msg");
const successMsgEmail = document.querySelector("#user__email__address");
const dismissSucessMsgBtn = document.querySelector(".dismiss__btn");

const emptyFieldMsg = "Input field can not be blank";

openModalBtn.addEventListener("click", function () {
  if (!emailInput.value) {
    emailInput.classList.add("error__state");
    emailInput.classList.add("error__placeholder");
    emailInput.classList.add("input__background");
    errorStateText.innerText = emptyFieldMsg;
  } else {
    successMessage.showModal();
    successMsgEmail.innerText = emailInput.value;
  }
});

dismissSucessMsgBtn.addEventListener("click", function () {
  successMessage.close();
});
Enter fullscreen mode Exit fullscreen mode

To store elements in a variable, the document.querySelector() method calls the appropriate element in our DOM.

The body of our website is stored in the pageBody variable. Why must we perform this? This is done because we want to make the page unscrollable by adding the position:fixed property to the body when the Modal comes into view.

The button that will cause the modal to populate is the subscribe button from our form, and it is stored in the openModalBtn variable.

The email input field is stored in the emailInput variable.

In our HTML, the span with the class of error__state__text is stored in the errorStateText variable. If the input field is left empty, this should display the error message.

successMessage variable stores the dialog element which is the modal

successMsgEmail represents the empty span we included in our success__note in our HTML, and it is intended to display the email address the user supplied in the form.

dismissSuccessMsgBtn variable keeps track of the button in our modal, which closes the modal.

The emptyFieldMsg variable, which records the error message that will be displayed, is the last of the variables.

Next, a callBack function that monitors the openModalBtn click event is launched using the addEventListener method. We added a conditional statement to the code that checks whether emailInput contains a value. If it doesn’t, the error states should be triggered; else, the success message should appear.

Javascript show() and showmodal() function.

JavaScript includes two methods called show() and showModal(). You may specify exactly how you want your dialog element to function by utilizing the show() and showModal() methods because sometimes you want a genuine modal and other times you want more of a popup-style dialog. To display our modal in our code, we utilized the showModal() method.

Simply use the close() method to close a dialog element. Therefore, we utilize the addEventListener method to start a callBack function that watches for the dismissSuccessBtn click event.

Modal pop-up

Modal pop-up

Source Code

Live project preview

Conclusion

Sharing knowledge gives it its full power. I will ask you to do well to spread this information if it has been useful to you, as I know it has. There may be someone out there who is having trouble or needs clarification incorporating this into Modal-pop.

Top comments (0)