<div class="wrapper">
  <h1>A smart and simple modal with css and modal only</h1>
  <p>By using the :target pseudo selectors, we can trigger layout state changes, like a modal animating in, and then out again.</p>
  <p>Clicking the button adds "#modal" to the url of the codepen iframe. Clicking the close icon of the modal, removes the modal and leaves only a hash (#) behind. These two states make it so we can trigger back and forth</p>
</div>

<a href="#modal" class="modal-trigger">Show modal</a>

<div class="modal" id="modal">
  <div class="overlay">
    <div class="inner">
      <a href="#" class="modal-close">&times;</a>
      <h1>HTML & CSS Modal</h1>
      A very simple modal, using no js, just html, css and :target selector for adding  behaviour.
    </div>
  </div>
</div>
$medium: 481px;
$ani-speed: 0.5s;
$ani-delay: 0.2s;

* {
  box-sizing: border-box;
}

html, body {
  min-height: 100%;
}

body {
  background: #eee;
  text-align: center;
}

img {
  display: block;
  float: left;
  margin: 0.5%;
  width: 19%;
}

.wrapper {
  margin: 0 auto;
  max-width: 600px;
}

.modal-trigger {
  box-shadow: 0 5px 10px rgba(#000, 0.2);
  color: #efefef;
  background: #222;
  padding: 10px 15px;
  position: fixed;
    left: 50%;
    top: 50%;
  text-decoration: none;
  transform: translate3d(-50%, -50%, 0);
}

.overlay {
  position: fixed;
  left: 0;
  top: 0;
  z-index: 3;
  background: rgba(#000, 0.3);
  width: 100%;
  height: 100%;
  
  @media (min-width: $medium) {
    padding: 10%;  
  }
}

.inner {
  background: #fff;
  box-shadow: 0 30px 70px rgba(#000, 0.5);
  height: 100%;
  margin: 0 auto;
  min-height: 300px;
  padding: 40px;
  position: relative;
  width: 100%;
  
  @media (min-width: $medium) {
    height: auto;
    max-width: 800px;
  }
}

.modal-close {
  color: #000;
  position: absolute;
    right: 10px;
    top: 5px;
  text-decoration: none;
  padding: 8px 16px;
  font-size: 30px;
}

// Behaviour

// Transition OUT
.modal:not(:target) {
  
  .overlay {
      opacity: 0;
      visibility: hidden;
      transition: opacity $ani-speed, visibility $ani-speed;
  }
  
  .inner {
    opacity: 0;
    transform: translateY(-1000px);
    visibility: hidden;
    transition: opacity $ani-speed, visibility $ani-speed, transform $ani-speed 1s;
  }
}

// Transition IN
.modal:target {
  
  .overlay {
    opacity: 1;
    visibility: visible;
    transition: opacity $ani-speed, visibility $ani-speed;
  }
  
  .inner {
    opacity: 1;
    transform: translateY(0);
    visibility: visible;
    transition: opacity $ani-speed, visibility $ani-speed, transform $ani-speed $ani-delay;
  }
}
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.