Build a Responsive Modal using CSS 🚀
Aniket

Aniket @ananiket

About: 🙂

Location:
Mumbai, India
Joined:
Sep 2, 2020

Build a Responsive Modal using CSS 🚀

Publish Date: Feb 26 '23
33 2

👋 Hello, Dear developers 👩‍💻
Today we will be lookup on how to build a responsive modal using CSS, so stay tunned🔥

Introduction

Modal Popups are used very often in modern websites or Apps, to display notifications or alerts, handle user's sign up or login forms, newsletters & much more ✨


I created this tutorial, on how to create a responsive modal popup box with a clean design, with the help of HTML as markup, CSS for styling and vanilla javascript for adding functionality 🧠🚀


Here's how it will look once we are finished in the below GIF⬇️

Final Output


But Before that, You can view the code tutorial of the finished product before continuing this blog ⬇️

Code Tutorial


You can also view a live demo 📺 of it as well.


Now Let's start on building this from scratch !

HTML Markup ⬇️

Let's start with html markup for the modal



<div class="container">
    <button class="share__modal_btn">share</button>

    <main class="share__modal">
        <div class="share__modal_content">
            <div class="share__modal__header">
                <span>share</span>
                <button class="close_modal_btn">
                    <i class="bx bx-x bx-sm"></i>
                </button>
            </div>
            <div class="share__modal__options">
                <ul class="list">
                    <li class="list__item">
                        <div class="icon_holder" data-icon="twitter">
                            <img
                                class="social__logo"
                                src="./img/twitter-logo.png"
                                alt="twitter-logo"
                            />
                        </div>
                        <span>twitter</span>
                    </li>

                    <li class="list__item">
                        <div class="icon_holder" data-icon="facebook">
                            <img
                                class="social__logo"
                                src="./img/facebook-logo.png"
                                alt="facebook-logo"
                            />
                        </div>
                        <span>facebook</span>
                    </li>

                    <li class="list__item">
                        <div class="icon_holder" data-icon="reddit">
                            <img
                                class="social__logo"
                                src="./img/reddit-logo.png"
                                alt="reddit-logo"
                            />
                        </div>
                        <span>reddit</span>
                    </li>

                    <li class="list__item">
                        <div class="icon_holder" data-icon="discord">
                            <img
                                class="social__logo"
                                src="./img/discord-logo.png"
                                alt="discord-logo"
                            />
                        </div>
                        <span>discord</span>
                    </li>

                    <li class="list__item">
                        <div class="icon_holder" data-icon="whatsapp">
                            <img
                                class="social__logo"
                                src="./img/whatsapp-logo.png"
                                alt="whatsapp-logo"
                            />
                        </div>
                        <span>whatsapp</span>
                    </li>

                    <li class="list__item">
                        <div class="icon_holder" data-icon="messenger">
                            <img
                                class="social__logo"
                                src="./img/messenger-logo.png"
                                alt="messenger-logo"
                            />
                        </div>
                        <span>messenger</span>
                    </li>

                    <li class="list__item">
                        <div class="icon_holder" data-icon="telegram">
                            <img
                                class="social__logo"
                                src="./img/telegram-logo.png"
                                alt="telegram-logo"
                            />
                        </div>
                        <span>telegram</span>
                    </li>

                    <li class="list__item">
                        <div class="icon_holder" data-icon="wechat">
                            <img
                                class="social__logo"
                                src="./img/wechat-logo.png"
                                alt="wechat-logo"
                            />
                        </div>
                        <span>wechat</span>
                    </li>
                </ul>
            </div>

            <div class="share__modal_link">
                <span>page link</span>
                <div class="share__modal_input">
                    <input
                        type="text"
                        placeholder="https://www.sharethispage.io"
                    />
                    <i class="bx bx-copy copy_icon"></i>
                </div>
            </div>
        </div>
    </main>
</div>



Enter fullscreen mode Exit fullscreen mode

So here, we have a few components added to our markup.

First, we have a simple open modal button which is named a share button, when clicked on, it triggers the function of opening the modal, then we have the close modal button which performs the opposite operation/function to the open button to close modal, then we have few social sharing option's and at last, we have the input box with just fake placeholder value in it.


for images, please follow my GitHub repository inorder to use them.


CSS Styles 🎨

Let's add the styles stepwise to understand what we're doing,

First of all, we will look at making some basic changes in our CSS file which includes resets of the root, HTML & variables.



@import url("https://fonts.googleapis.com/css2?family=Inter:wght@200;300;400;600&display=swap");
*,
*::before,
*::after {
  box-sizing: border-box;
}
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  font-family: "Inter", sans-serif;
}

:root {
  /*========== Colors ==========*/

  --first-color: #373d46;
  --modal-bg-color: #fff;
  --text-input-bg: #f8f9fa;
  --text-color: #95989d;
  --container-bg: #c7ad91;
  --btn-color: #ddc0a1;

  /* ===== SOCIAL ICONS BACKGROUND COLOR =====  */
  --twitter: #e8f6fe;
  --whatsapp: #e9fbf0;
  --facebook: #e8f1fe;
  --reddit: #ffece6;
  --discord: #f1f3fb;
  --messenger: #e6f3ff;
  --telegram: #e6f3fa;
  --wechat: #f2f7ea;

  /*========== Font and typography ==========*/

  --normal-font-size: 0.88rem;
  --large-font-size: 1.25rem;
  --share-link-span: 0.9869em;
  --share-input-font-size: 0.8em;

  /*========== z index ==========*/
  --z-modal: 1000;
}

@media screen and (min-width: 991px) {
  :root {
    --large-font-size: 1.5rem;
    --normal-font-size: 1rem;
    --share-link-span: 1.1em;
    --share-input-font-size: 1em;
  }
}

/*=============== BASE ===============*/
body{
  font-weight: 500;
  background-color: var(--btn-color);
}
button{
  background-color: transparent;
  outline: none;
  border: none;
  cursor: pointer;
  font-family: inherit;
}

img{
  max-width: 100%;
  height: auto;
}
ul li {
  margin: 0;
  padding: 0;
  list-style-type: none;
}
.container{
  height: 100vh;
  display: grid;
  place-items: center;
  background-color: var(--container-bg);
}


Enter fullscreen mode Exit fullscreen mode

Okay Nice ! we are moving further 🏃‍♀️🏃‍♂️

So after adding those base styles, we look up our markup and use the classes that we have given to each component (tag) in order to add them styles individually.

1. Share modal button




.share__modal_btn {
  background-color: #857361;
  padding: 0.9em 1.5em;
  font-size: var(--share-link-span);
  text-transform: capitalize;
  border-radius: 0.7em;
  box-shadow: 0 10px 10px -2px rgba(0, 0, 0, 0.1);
  color: #eee;
  letter-spacing: 0.25px;
}
.share__modal_btn:hover {
  background-color: #6f6051;
}



Enter fullscreen mode Exit fullscreen mode

The styles for the share modal button are background color, font size along with visual goodies like padding, border-radius & pseudo hover class on background color.

Result ⬇️

share-modal-button


2. Share modal

The share modal is the most important, where all of the content is situated

we added an absolute position on it at the bottom with a 0% percentage value along the visual goodies like box shadow, border radius, opacity, and extra white space by using padding and transition property as well.




.share__modal {
  background-color: var(--modal-bg-color);
  position: absolute;
  bottom: 0;
  width: 100%;
  height: 50%;
  display: grid;
  align-items: flex-end;
  overflow: auto;
  box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.2);

  border-radius: 1.3em 1em 0 0;
  z-index: var(--z-modal);
  opacity: 0;
  transition: 0.5s ease;
  visibility: hidden;
}

.share__modal_content {
  padding: 1.5em;
  display: flex;
  flex-direction: column;
  row-gap: 2.6em;
}

.share__modal__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.share__modal__header span {
  font-size: var(--large-font-size);
  font-weight: 600;
  color: var(--first-clr);
  text-transform: capitalize;
  opacity: 0.88;
}
.close_modal_btn {
  color: var(--first-clr);
}



Enter fullscreen mode Exit fullscreen mode

Result ⬇️

Open State


3. Social sharing options

These options are structured with the help of CSS Grid, for the background color of social sharing options, we used the data-icon attribute property on each tag in html file & added light color as a background to add contrast against the actual logo.




.list {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-gap: 1.125em;
}

.list__item {
  display: flex;
  flex-direction: column;
  row-gap: 0.5em;
  align-items: center;
  justify-content: center;
  text-transform: capitalize;
  color: var(--first-clr);
  font-size: var(--normal-font-size);
  font-weight: 500;
  opacity: 0.9;
  cursor: pointer;
}
.icon_holder {
  width: 4.5em;
  height: 4.5em;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
}
.social__logo {
  width: 2em;
  height: 2em;
}

[data-icon="twitter"] {
  background-color: var(--twitter);
}
[data-icon="facebook"] {
  background-color: var(--facebook);
}
[data-icon="reddit"] {
  background-color: var(--reddit);
}
[data-icon="discord"] {
  background-color: var(--discord);
}
[data-icon="whatsapp"] {
  background-color: var(--whatsapp);
}
[data-icon="messenger"] {
  background-color: var(--messenger);
}
[data-icon="telegram"] {
  background-color: var(--telegram);
}
[data-icon="wechat"] {
  background-color: var(--wechat);



Enter fullscreen mode Exit fullscreen mode

4. Share link input

we use the input with the fake placeholder value to share the link of the current page, the style for these is pretty generic & straight forward.




.share__modal_link {
  display: flex;
  flex-direction: column;
  row-gap: 1.1em;
}
.share__modal_link span {
  font-weight: 500;
  font-size: var(--share-link-span);
  text-transform: capitalize;
  color: var(--first-clr);
}
.share__modal_input {
  position: relative;
}
.share__modal_input input {
  width: 100%;
  background-color: var(--text-input-bg);
  padding: 0.88em;
  border-radius: 0.5em;
  border: none;
  outline: none;
  font-size: var(--share-input-font-size);
}
.copy_icon {
  position: absolute;
  right: 1.5em;
  top: 1em;
  color: var(--first-clr);
  cursor: pointer;
}



Enter fullscreen mode Exit fullscreen mode

5. Show modal

Before moving to the final, here is the class that handles the styles when the modal is opened.




.show-modal {
  opacity: 1;
  visibility: visible;
}



Enter fullscreen mode Exit fullscreen mode

6. Media queries to make it responsive 📱

Finally, we want to make it responsive or at least look good on both mobile and desktop, so below are the few breakpoints on the share modal button, modal, modal content, and list.



@media screen and (min-width: 768px) {
  .share__modal_btn {
    padding: 0.9em 1.75em;
    font-size: var(--share-link-span);
  }
  .share__modal {
    width: 28em;
    height: 30em;
    border-radius: 1.3em;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    overflow: hidden;
  }
  .share__modal_content {
    padding: 2.5em;
  }
  .list {
    grid-template-columns: repeat(4, 1fr);
    row-gap: 1.5em;
    column-gap: 1em;
  }
}



Enter fullscreen mode Exit fullscreen mode

Desktop View

Desktop-view

Mobile View

mobile-view


😤 Finally, To make our modal popup box intractive or actually work, we will be using few lines of javascript logic 🧠

Javascript code ⬇️




/*=============== SHOW MODAL ===============*/

const openBtn = document.querySelector(".share__modal_btn");
const modalContainer = document.querySelector(".share__modal");

if (openBtn && modalContainer) {
  openBtn.addEventListener("click", () => {
    modalContainer.classList.add("show-modal");
  });
}

/*=============== CLOSE MODAL ===============*/

const closeBtn = document.querySelector(".close_modal_btn");

function closeModal() {
  const modalContainer = document.querySelector(".share__modal");
  modalContainer.classList.remove("show-modal");
}
closeBtn.addEventListener("click", closeModal);

/*====== ESC BUTTON TO CLOSE MODAL ======*/

document.addEventListener("keydown", (event) => {
  if (event.key === "Escape") {
    closeModal();
  }
});



Enter fullscreen mode Exit fullscreen mode

So here we have three event listeners who are adding or removing the show-modal class from the modalContainer :

  1. When OpenBtn is clicked, we want to add a show-modal class to modalContainer in order to show the modal to users.

  2. When closeBtn is clicked, we perform the opposite operation to open the button that is to remove the show-modal class & hide the modal.

  3. Escape key-down event listener on dom to hide the modal by simply calling the closeModal() function.


So, the end result will finally look like this ⬇️

Reupload-final-output

and that's what we wanted 🥳🤘

I hope you find this post to be helpful and thanks for reading it 😇

Conclusion
As always, I hope you found it interesting. If you noticed any
errors in this article, please mention them in the comments. 🧑🏻‍💻

Hope you have a great day! ✌️

Thumbs meme

Comments 2 total

  • Gabriel Linassi
    Gabriel LinassiFeb 26, 2023

    Although this is a good task to challenge yourself, I don't recommend you do this in business projects. Building a modal requires much attention, like locking the screen, close on clicking outside, beying responsive to keyboard events, having the correct aria, dynamic loading modal content, render it in a higher place in the DOM, etc.

    • Aniket
      AniketFeb 27, 2023

      Thank You & Yeah sure, I will definitely try to make it to the business level by considering the above suggestions. Thanks for reading this blog 🥳🤘

Add comment