Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS modal overlay with fade in and out?

Tags:

css

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:

  • Add and remove classes using JavaScript (React, not jQuery)
  • Run any CSS/SASS code

Constraints:

  • The overlay div I'm using is always in the DOM, it's not added and removed.
  • I can't use any JavaScript timing (no setTimeout()), all timing must be in CSS/SASS

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!

like image 908
Stephen Last Avatar asked Jul 17 '17 13:07

Stephen Last


3 Answers

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>
like image 59
I haz kode Avatar answered Sep 20 '22 20:09

I haz kode


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>
like image 43
mdss Avatar answered Sep 16 '22 20:09

mdss


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; 
}
like image 27
Tom Avatar answered Sep 18 '22 20:09

Tom