Stephen Last
Stephen Last

Reputation: 5781

CSS modal overlay with fade in and out?

I would like to have a content overlay, to grey-out the page contents when a modal opens. I would like the overlay to fade in, and fade out.

I can:

Constraints:

Obviously, the overlay can't block clicks on content when it's hidden, so I can't just animate opacity.

I'm currently using background-color: rgba(0, 0, 0, 0.5); and transition: background-color 1s ease-in; to animate, but I can't seem to get the overlay "in the way" and "out of the way" of the content (while also fading in AND out).

I've tried using the height property (set to 100% for overlay on, 0 for overlay off), but I think I can only use transition: height 0s ease-in 0; once, not twice (because I need a delay for this when fading out).

How can I do this..?

Update

Request to see what I've tired:

.overlay {
  display: block;
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 0;
  z-index: 10;
  transition: background-color .5s ease-in;
  background-color: rgba(0, 0, 0, 0);
}
.overlay-start-off {
  transition: height 0s ease-in 0;
}
.overlay-start-on {
  transition: height 0s ease-in .5s;
}
.overlay--show {
  height: 100%;
  background-color: rgba(0, 0, 0, 0.4);
}

Classes are switched in/out using state in a React component, which happens as soon as you click to open/close the modal.

The bit I'm struggling with is getting the fade out to happen, then the removal of the overlay from blocking the content.

I know this code doesn't work!

Upvotes: 7

Views: 52580

Answers (5)

Drako Tech
Drako Tech

Reputation: 36

Fade Out

Expanding on the answer by @mdss, for the fade in then fade out animation effects you can add JavaScript with @keyframe custom animation rules to be able to use it on an element transitioning from display none to block.

Make sure that the setInterval timer matches the timing of the transition effect:

More info on KeyFrames.

@keyframes fadein {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

@keyframes fadeout {
  from {
    opacity: 1;
  }
  to {
    opacity: 0;
  }
}

.checkbox-control + .modal {
  top: 25%;
  left: 25%;
  width: 50vw;
  height: 50vh;
  position: fixed;
  display: none;
  animation: fadein 0.4s forwards;
}

.checkbox-control:checked + .modal {
  display: block;
  background: rgba(0, 0, 0, 0.8);
}

.fadeout {
  animation: fadeout 0.4s;
}
<input type="checkbox" id="trigger" class="checkbox-control" onclick="fadeOut(this)">

<div id="modal" class="modal">
</div>

<script>
  let modal = document.getElementById("modal");
  
  function fadeOut(checkbox) {
    if (! checkbox.checked){
      modal.classList.add("fadeout");

      setTimeout(() => {
        modal.style.display = "none";
        modal.classList.remove("fadeout");
      }, 400);
    } else {
      modal.style.display = "block";
    }
  }
</script>

Upvotes: 0

Kevin Danikowski
Kevin Danikowski

Reputation: 5206

So I didn't do any transition items, but for those of you who who are stumbling across this post in search of a copy and paste modalOverlay background that's easy to use, here you go:

.modalOverlay 
  z-index 100
  position fixed
  width 100vw
  height 100vh
  top 0
  left 0
  background-color rgba(255, 255, 255, 0.9)
  display flex
  justify-content center
  overflow-y auto

Upvotes: 0

mdss
mdss

Reputation: 331

Try to use custom animation function. For example

.test {
}
.test + label {
  display:none;
  position:absolute;
  top:0; right:0; bottom:0; left:0;
  animation:fadein .5s;
}
.test:checked + label {
  display:block;
  background-color:rgba(0, 0, 0, .5);
}
@keyframes fadein {
	from {
		opacity:0;
	}
	to {
		opacity:1;
	}
}
<input type="checkbox" id="1" class="test">
<label for="1"></label>

Upvotes: 6

I haz kode
I haz kode

Reputation: 1625

I use :target to achieve the desired result of a pure CSS modal.

As for the overlay, I use an empty anchor tag with z-index stacking to create a clickable overlay which only shows up when the modal is open. Clicking the overlay closes the modal.

The modal also has a separate close button.

When the modal is closed it doesn't interfere with the body content.

The fade in part is simple. You just need to add a transition property to the whole setup.

/* essential code */

.modal {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  opacity: 0;
  pointer-events: none;
  background: rgba(0, 0, 0, .5);
  transition: all ease 1s;
}

.closeoverlay {
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  opacity: 0;
  display: block;
  z-index: 2;
  position: fixed;
  cursor: pointer;
}

.closebutton {
  color: red;
  text-decoration: none;
  font-size: 30px;
  margin: 0 auto;
  display: table;
}

.modal:target {
  opacity: 1;
  pointer-events: auto;
  
}

.modal:target>.closeoverlay {
  display: block;
}

.modal>div {
  width: 300px;
  height: 500px;
  max-width: 75vw;
  max-height: 75vh;
  text-align: center;
  position: relative;
  background: #131418;
  z-index: 3
}

.wrap,
.modal {
  display: flex;
  align-items: center;
  justify-content: center
}

.modal-content {
 overflow-y:auto
}


/*demo fluff */

p {
  color: green;
  font-size: 20px;
  display: block;
}

button {
  margin: 2em 0 0 0;
  cursor: pointer;
}

.closebutton:hover {
  color: white;
  cursor: pointer;
}

.clutter, .modal-content p {
  margin: 2em auto;
  padding: 40px;
  max-width: 100%;
  text-align: justify;
}


.clutter {width: 400px}
<div class="wrap">
  <a href="#M"><button>Open Modal</button></a>
  <div id="M" class="modal">
    <div class="modal-content">
      <a class="closebutton" href="#">&times;</a>
      <p>Prosciutto leberkas boudin pastrami sausage pork. Hamburger pancetta jowl venison pastrami. Filet mignon alcatra burgdoggen salami, ham hock shoulder pork loin sirloin jowl </p>
    </div>
    <a href="#" class="closeoverlay"></a>
  </div>
</div>
<div class="clutter">Bacon ipsum dolor amet shoulder sausage rump venison kevin prosciutto salami shank. Venison salami flank doner burgdoggen, shoulder beef sausage swine alcatra short loin pig chuck. Pastrami sirloin shoulder, swine frankfurter beef strip steak sausage
  salami tri-tip. Prosciutto leberkas boudin pastrami sausage pork. Hamburger pancetta jowl venison pastrami. Filet mignon alcatra burgdoggen salami, ham hock shoulder pork loin sirloin jowl picanha flank drumstick pancetta. Turkey shoulder cupim rump
  ball tip strip steak turducken tri-tip biltong pork doner. Turducken leberkas chuck filet mignon bresaola picanha ball tip pig ground round shankle. Shank pork ribeye fatback, capicola pork loin tri-tip porchetta biltong landjaeger ham hock hamburger.
  Strip steak pork chop sirloin</div>

Upvotes: 8

Tom
Tom

Reputation: 369

Here are couple of options for you. Note that I do not own any of this projects it's just quick search for css modal window.

http://jsfiddle.net/kumarmuthaliar/GG9Sa/1/ Open Modal

<div id="openModal" class="modalDialog">
<div>   <a href="#close" title="Close" class="close">X</a>

        <h2>Modal Box</h2>

    <p>This is a sample modal box that can be created using the powers of CSS3.</p>
    <p>You could do a lot of things here like have a pop-up ad that shows when your website loads, or create a login/register form for users.</p>
</div>
</div>

.modalDialog {
    position: fixed;
    font-family: Arial, Helvetica, sans-serif;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    background: rgba(0, 0, 0, 0.8);
    z-index: 99999;
    opacity:0;
    -webkit-transition: opacity 400ms ease-in;
    -moz-transition: opacity 400ms ease-in;
    transition: opacity 400ms ease-in;
    pointer-events: none;
}
.modalDialog:target {
    opacity:1;
    pointer-events: auto;
}
.modalDialog > div {
    width: 400px;
    position: relative;
    margin: 10% auto;
    padding: 5px 20px 13px 20px;
    border-radius: 10px;
    background: #fff;
    background: -moz-linear-gradient(#fff, #999);
    background: -webkit-linear-gradient(#fff, #999);
    background: -o-linear-gradient(#fff, #999);
}
.close {
    background: #606061;
    color: #FFFFFF;
    line-height: 25px;
    position: absolute;
    right: -12px;
    text-align: center;
    top: -10px;
    width: 24px;
    text-decoration: none;
    font-weight: bold;
    -webkit-border-radius: 12px;
    -moz-border-radius: 12px;
    border-radius: 12px;
    -moz-box-shadow: 1px 1px 3px #000;
    -webkit-box-shadow: 1px 1px 3px #000;
    box-shadow: 1px 1px 3px #000;
}
.close:hover {
    background: #00d9ff;
}

https://codepen.io/timothylong/pen/HhAer

<div class="container">
  <div class="interior">
    <a class="btn" href="#open-modal">Basic CSS-Only Modal</a>
  </div>
</div>
<div id="open-modal" class="modal-window">
  <div>
    <a href="#modal-close" title="Close" class="modal-close">Close</a>
    <h1>Voilà!</h1>
    <div>A CSS-only modal based on the :target pseudo-class. Hope you find it helpful. <a href="https://twitter.com/timothylong" target="_blank">Say hello on Twitter.</div>
    </div>
</div>

html,
body {
  height: 100%;
}

body {
  font: 600 18px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
  padding: 2rem;
  background-color: #5A7A9B;
  color: #5A7A9B
}

a {
  color: inherit;
}

.container {
  display: table;
  width: 100%;
  height: 100%;
}

.interior {
  display: table-cell;
  vertical-align: middle;
  text-align: center;
}

.btn {
  background-color: #fff;
  padding: 1em 3em;
  border-radius: 3px;
  text-decoration: none;
}

.modal-window {
  position: fixed;
  background-color: rgba(255, 255, 255, 0.15);
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 999;
  opacity: 0;
  pointer-events: none;
  -webkit-transition: all 0.3s;
  -moz-transition: all 0.3s;
  transition: all 0.3s;
}

.modal-window:target {
  opacity: 1;
  pointer-events: auto;
}

.modal-window>div {
  width: 400px;
  position: relative;
  margin: 10% auto;
  padding: 2rem;
  background: #fff;
  color: #444;
}

.modal-window header {
  font-weight: bold;
}

.modal-close {
  color: #aaa;
  line-height: 50px;
  font-size: 80%;
  position: absolute;
  right: 0;
  text-align: center;
  top: 0;
  width: 70px;
  text-decoration: none;
}

.modal-close:hover {
  color: #000;
}

.modal-window h1 {
  font-size: 150%;
  margin: 0 0 15px;
}

https://codepen.io/samirc/pen/bVLXPV

<div class="wrap">

  <h1>Modal - Pure CSS (no Javascript)</h1>

  <p>Example of modal in CSS only, here I use the pseudo selector ":target" and no javascript for modal action.</p>

  <p>This works in IE9+ and all modern browsers.</p>

  <hr />

  <a href="#modal-one" class="btn btn-big">Modal!</a>

</div>

<!-- Modal -->
<div class="modal" id="modal-one" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-header">
      <h2>Modal in CSS?</h2>
      <a href="#close" class="btn-close" aria-hidden="true">×</a> <!--CHANGED TO "#close"-->
    </div>
    <div class="modal-body">
      <p>One modal example here! :D</p>
    </div>
    <div class="modal-footer">
      <a href="#close" class="btn">Nice!</a>  <!--CHANGED TO "#close"-->
    </div>
    </div>
  </div>
</div>
<!-- /Modal -->
//
// Variables
// ----------------------

@gray: #333;
@gray-light: #aaa;
@gray-lighter: #eee;
@space: 40px;
@blue: #428bca;
@blue-dark: darken(@blue, 5%);

// Mixin for transition/transform
.translate(@x; @y) {
  -webkit-transform: translate(@x, @y);
      -ms-transform: translate(@x, @y); // IE9+
          transform: translate(@x, @y);
}
.transition(@transition) {
  -webkit-transition: @transition;
          transition: @transition;
}
.transition-transform(@transition) {
  -webkit-transition: -webkit-transform @transition;
    -moz-transition: -moz-transform @transition;
      -o-transition: -o-transform @transition;
          transition: transform @transition;
}

//
// Body
// ----------------------

body{
  color: @gray;
  font-family: 'Helvetica', arial;
  height: 80em;
}

.wrap{
  padding: @space;
  text-align: center;
}

hr {
  clear: both;
  margin-top: @space;
  margin-bottom: @space;
  border: 0;
  border-top: 1px solid @gray-light;
}

h1{
  font-size: 30px;
  margin-bottom: @space;
}

p{
  margin-bottom: @space/2;
}

//
// Btn 
// ----------------------

.btn{
  background: @blue;
  border: @blue-dark solid 1px;
  border-radius: 3px;
  color: #fff;
  display: inline-block;
  font-size: 14px;
  padding: 8px 15px;
  text-decoration: none;
  text-align: center;
  min-width: 60px;
  position: relative;
  transition: color .1s ease;
/* top: 40em;*/

  &:hover{
    background: @blue-dark;
  }

  &.btn-big{
    font-size: 18px;
    padding: 15px 20px;
    min-width: 100px;
  }

}

.btn-close{
  color: @gray-light;
  font-size: 30px;
  text-decoration: none;
  position: absolute; right: 5px; top: 0;

  &:hover{
    color: darken(@gray-light, 10%);
  }

}

//
// Modal
// ----------------------

.modal{


  // This is modal bg
  &:before{
    content: ""; 
    display: none;
    background: rgba(0,0,0,.6);
    position: fixed;
    top: 0; left: 0; right: 0; bottom: 0; 
    z-index: 10;
  }

  &:target{

    // Active animate in modal
    &:before{
      display: block;
    }  
    .modal-dialog{
      .translate(0, 0); 
      top: 20%;  
    }

  }

}

// Modal Dialog
// ----------------------

.modal-dialog{
  background: #fefefe;
  border: @gray solid 1px;
  border-radius: 5px;
  margin-left: -200px;
  position: fixed; 
  left: 50%; 
  top: -100%;  
  z-index: 11; 
  width: 360px;
  .translate(0, -500%);
  .transition-transform(~"0.3s ease-out");
}

.modal-body{
  padding: @space/2;
}

.modal-header,
.modal-footer{
  padding: @space/4 @space/2;
}

.modal-header{
  border-bottom: @gray-lighter solid 1px;

  h2{
    font-size: 20px;
  }

}

.modal-footer{
  border-top: @gray-lighter solid 1px;
  text-align: right;
}

/*ADDED TO STOP SCROLLING TO TOP*/
#close {
  display: none; 
}

Upvotes: 2

Related Questions