Learn 2 ways to make a modal without Javascript

If you don't know the 2 techniques I am about to show you, you might think it's impossible to make a modal without Javascript. However, with a bit of CSS trickery, we can get this done quite easily.

You can use these tricks for other uses, such as opening a menu when clicking a hamburger menu.

Let's start with the first way, using a checkbox.

If you want to skip the explanation and just see it in action, visit my CSS Modal without Javascript (checkbox) Codepen

Here is the HTML structure.

<div class="container">
  <label for="modal-toggle" class="open-label">Open Modal</label>
  <div id="modal">
    <input type="checkbox" id="modal-toggle">
    <label for ="modal-toggle" class="modal-container">   </label>
    <div class="modal-box">
      <div class="modal-message">
            <label for ="modal-toggle" class="close-modal">x</label>
        Sed tempus fermentum lorem quis imperdiet. Pellentesque malesuada justo arcu
      </div>
    </div>
  </div>
</div>

Here is the CSS

body{
  margin:0;
  padding:0;
  box-sizing:border-box;
}

.container
{
  background-color:steelblue;
  display:flex;
  justify-content:center;
  align-items:center;
  height:100vh;
  width:100vw;
  position:relative;
  z-index:1;
}

.open-label{
  font-size:2rem;
  color:white;
  z-index:2;
  cursor:pointer;
}

#modal-toggle ~ .modal-container,
#modal-toggle ~ .modal-box
{
  visibility:hidden;
}

#modal-toggle:checked ~ .modal-container,
#modal-toggle:checked ~ .modal-box
{
  visibility:visible;
}

#modal-toggle:checked ~ .modal-box .modal-message{
  transform: translateY(0);
}

/* #modal-toggle:checked ~ #modal{
  display:flex;
} */

#modal{
  position: absolute;
  top:0;
  left:0;
  right:0;
  bottom:0;
}

.modal-container{
  position:absolute;
  top:0;
  left:0;
  right:0;
  bottom:0;
  z-index:4;
}

.modal-box{
  display:flex;
  justify-content:center;
  align-items:center;
  position:absolute;
  top:0;
  left:0;
  right:0;
  bottom:0;
  background-color:rgba(0,0,0,.5);
}

.modal-message{
  position:relative;
  background-color:black;
  z-index:5;
  color:white;
  padding:40px;
  max-width:40%;
  font-size:1.5rem;
  transform: translateY(-500px);
  transition:transform .3s ease-in-out;
}

#modal .modal-message .close-modal{
  top:0;
  right:20px;
  position:absolute;
  cursor:pointer;
}

input[type="checkbox"]{
  visibility:hidden;
}

The way it works is the following:

In the HTML, you will see we have a checkbox input element with the ID of "modal-toggle". In our CSS, we are able to check if the checkbox input element has been selected using the :checked selector (see: https://www.w3schools.com/cssref/sel_checked.asp).

This is useful because we can use labels (which are linked to the input elements using for="modal-toggle") to check and uncheck the checkboxes. In case you didn't know, you can click on the label to check or uncheck a checkbox. You don't have to click on the actual checkbox itself. For example:

The great thing about this is we can position the label anywhere we want, and it will still check and uncheck the checkbox, which, to repeat, we can check if it's been checked using CSS. This will control if the modal is showing or not showing.

So the first thing we do is hide our input element. This is because we will control it through the label - we will have 3 labels.

Label 1: We will have the label to Open the Modal (class="open-label" in the code),

Label 2: We will have the label to click out of the modal when clicking outside of the modal. (class="modal-container" in the code)

Label 3: The label for the "x" when the modal is open (class="close-modal" in the code)

So the important things to note are that the "modal-container" label (label 2) will span the entire screen because we want to be able to click outside of the modal to close it.

Initially hide everything related to do the modal using visibility:hidden. Then if someone clicks on "Open Modal", in the CSS using the :checked selector, set the visibility to visible.

To summarize, we will connect 3 labels to a checkbox element. This makes it so when you click on the label, the checkbox gets checked or unchecked. Then using the fact that CSS can check if a checkbox element is checked using :checked, we will make the modal visible or not visible.

If you want to skip the explanation and just see it in action, visit my CSS Modal without Javascript (:target selector) Codepen

Here is the HTML structure.

<div class="container">
  <h1><a href="#modal">Open Modal</a></h1>
  <div id="modal">
    <a href="#" class="close"></a>
    <div class="modal-content">  
      <a href="# ">x</a>
        <p>this is the modal!</p>
    </div>
  </div>
</div>

Here is the CSS

@import url(https://fonts.googleapis.com/css?family=Roboto);

body{
  margin:0;
  padding:0;
  box-sizing:border-box;
}

a{
  text-decoration:none;
  font-family: roboto;
}
.container
{
  background-color:steelblue;
  display:flex;
  justify-content:center;
  align-items:center;
  top:0;
  left:0;
  right:0;
  bottom:0;
  position:absolute;
}

.container h1
{
  font-family:roboto;
  z-index:10;
}

.container h1 a{
   color:white;
}

#modal{
  visibiliy:hidden;
  opacity:0;
  position:absolute;
  top:0;
  left:0;
  bottom:0;
  right:0;
  background-color:rgba(0,0,0,.4);
  z-index:1;
  display:flex;
  justify-content:center;
  align-items:center;
  transition: .3s opacity ease-in-out;
}

#modal:target{
  visibility:visible;
  opacity:1;
  z-index:11;
}

#modal .close{
  position:absolute;
  width:100%;
  height:100%;
  cursor:default;
  
}

#modal .modal-content{
  padding:10px;
  display:flex;
  position:relative;
  justify-content:center;
  align-items:center;
  width:40%;
  height: 200px;
  background-color:rgba(0,0,0,.8);
}

#modal .modal-content p{
  text-align:center;
  color:white;
  font-size:1.5rem;
}

#modal .modal-content a{
  position: absolute;
  color:white;
  font-size:1.5rem;
  top:0;
  right:10px;
}

The HTML for this one is a lot simpler.

For this one, we will use the :target selector https://www.w3schools.com/cssref/sel_target.asp. The target selector can be used to style the element that is currently active.

For example: Take a look at this code <h1><a href="#modal">Open Modal</a></h1>:

Open Modal

If I click on this link, the URL changes to #modal, and this element has been targeted. We can now check if it's been targeted in the CSS, using #model:target. If it has been targeted, change the styles. In the case of the modal, we will make the modal visible (change from visibility:hidden to visibility:visibile).

The other 2 links will go back to #, so the #modal is no longer targeted, and we change the visibility of the modal to hidden.


I hope you now learned 2 to open and close a modal using only CSS (no JavaScript). The first way is using a cool trick using Checkboxes. The second way is using the :target selector.

Make one page websites quickly using my Carrd Templates