Build a Responsive Modal using CSS 🚀
Tags: html, css, javascript, webdev
Published: 2023-02-26 13:27:52

👋 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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z1xt96y4kntr2x05x3rq.gif)

---

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

## Code Tutorial

{% youtube cW4Gmj1kTwY %}

---

> You can also view a [live demo](https://codepen.io/ananiket/pen/Exegezz) 📺 of it as well.

---

Now Let's start on building this from scratch !

## HTML Markup ⬇️


Let's start with html markup for the modal

```html
<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>

```


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](https://github.com/ananikets18/Responsive-modal-popup-using-html-css-js) 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.

```css
@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);
}
```

> 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

```css 

.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;
}

 ```

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1bhkz5d54yphdskxnm6c.png)

--- 

### 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.

```css

.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);
}

```

#### Result ⬇️

![Open State](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9skuhwqhajn46ilj419s.png)

---

### 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.

```css

.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);

```

---


### 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.

```css

.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;
}

```

---

### 5. Show modal

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

```css

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

```

---

### 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.

```css
@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;
  }
}

```

#### Desktop View

![Desktop-view](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8o70092h0wml48comnbn.png)

#### Mobile View

![mobile-view](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/apqsohrecym55s7gg4al.png)

---

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

## Javascript code ⬇️

```js

/*=============== 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();
  }
});

```


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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0ey7t9xupowblyzct3ai.gif)

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l7q9ovjlqcll587awip4.jpg)