1

I'm making a modal using CSS3 and alternating classes with jQuery.

The modal open correctly (with css3 effect) but my trouble is when I close the modal. I cannot make the modal close with the css3 effect in reverse way. In other words, I want open the modal with the effect and close the modal with it in reverse way.

The modal open 0%: -70deg%´ ---- ´100%: 0. I try create an animation called closemodal with reverse effect. 0%: 0 ---- 100%: -70deg but without successful.

How I can open and close the modal with effect appearing... and effect coming out?

Pls, looks the snippet:

$(document).ready(function(){
 $('.modal-open').click(function(){
  $('.overlay').addClass('modal-show');
  $('.modal').addClass('modal-show modal-perspective');
  $('.modal-content').addClass('modal-animate');
 });
 $('.modal-close').click(function(){
  $('.overlay').removeClass('modal-show');
  $('.modal').removeClass('modal-show modal-perspective');
  $('.modal-content').removeClass('modal-animate');
     $('.modal-content').addClass('modal-remove');

 });
});
html, body{
 margin: 0;
 padding: 0;
 box-sizing: border-box;
 background: #FF3300;
 font-family: 'Ubuntu', sans-serif;
}

.modal{
 position: fixed;
 top: 50%;
 left: 50%;
 transform: translate(-50%, -50%);
 width: 50%;
 height: auto;
 min-width: 300px; 
 z-index: 2;
 visibility: hidden; 
 display: flex;
 align-items: center;
 justify-content: center;

}

.modal-content{
 padding: 120px 10px;
 text-align: center;
 color: #000;
 background: #bd330f;
 border-radius: 10px; 
 border: 1px solid #909090; 
 box-shadow: 10px 10px 20px rgba(0, 0, 0, 0.9); 
}

.modal-open{
 position: absolute;
 top: 50%;
 left: 50%;
 transform: translate(-50%, -50%);
 border: transparent;
 background: #fff;
 font-size: 15px;
 font-weight: bold;
 padding: 20px 50px;
 border-radius: 5px;
}

.modal-open:active{
 outline: transparent;
}

.modal-close{
 padding: 8px 40px;
    border-radius: 8px;
    border: transparent;
    background: #212121;
    color: #fff;
    outline: transparent; 
}

.overlay {
 position: fixed;
 width: 100%;
 height: 100%;
 visibility: hidden;
 top: 0;
 left: 0;
 z-index: 1;
 opacity: 0;
 background: rgba(0, 0, 0, 0.5);
 transition: all 0.7s;
}

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

.modal-perspective{
     -webkit-perspective: 900px; 
     perspective: 900px;   
}

.modal-animate{
 animation: openmodal 300ms ease-in forwards; 
}

.modal-remove{
 animation: closemodal 300ms ease-in-out forwards; 
}

@keyframes openmodal{
 0%{
  transform: rotateX(-70deg);
  -webkit-transform: rotateX(-70deg);
  -moz-transform: rotateX(-70deg);
  -ms-transform: rotateX(-70deg);
 } 

 100%{
  transform: rotateX(0deg);
  -webkit-transform: rotateX(0deg);
  -moz-transform: rotateX(0deg);
  -ms-transform: rotateX(0deg);
 }
}

@keyframes closemodal{
 0%{
  transform: rotateX(0deg);
  -webkit-transform: rotateX(0deg);
  -moz-transform: rotateX(0deg);
  -ms-transform: rotateX(0deg);
 } 

 100%{
  transform: rotateX(-70deg);
  -webkit-transform: rotateX(-70deg);
  -moz-transform: rotateX(-70deg);
  -ms-transform: rotateX(-70deg);  
 }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="modal">
 <div class="modal-content">
  <h3>Modal Dialog</h3>
  <div>    
   <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi gravida libero nec velit. Morbi scelerisque luctus velit. Etiam dui sem, fermentum vitae, sagittis id, malesuada in, quam. Proin mattis lacinia justo. Vestibulum facilisis auctor urna. Aliquam in lorem sit amet leo accumsan.</p>
   <button class="modal-close">CLOSE ME!</button>
  </div>
 </div>
</div>

<button class="modal-open">~ OPEN MODAL ~</button>

<div class="overlay"></div>

In addition, in my jQuery code, there are a better way to toggle the classes? I think that is a better way to toggle them. How I can make it?

Zkk
  • 741
  • 13
  • 29
  • For the class toggling, http://api.jquery.com/toggleclass/ is probably what you are looking for. – Gerrit0 Dec 03 '16 at 02:53

1 Answers1

3

You must avoid using CSS3 keyframe animations when you need the reverse effect. What you really should use (and need) is CSS3 transition which is capable of producing the reverse effect whenever the class that adds the forward effect is removed.

Just set the transform: rotateX(-70deg) to the original state (that is, .modal-content) and then set the transform: rotateX(0deg) on the open state (.modal-animate). This means the element will be invisible originally and gets displayed when open. Finally add the transition property to the element.

(Note: As discussed in comments and in this post it is generally not good to use all in transition but the impact of that in this example is very minimal in my opinion.)

$(document).ready(function() {
  $('.modal-open').click(function() {
    $('.overlay').addClass('modal-show');
    $('.modal').addClass('modal-show modal-perspective');
    $('.modal-content').addClass('modal-animate');
  });
  $('.modal-close').click(function() {
    $('.overlay').removeClass('modal-show');
    $('.modal').removeClass('modal-show modal-perspective');
    $('.modal-content').removeClass('modal-animate');
  });
});
html,
body {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  background: #FF3300;
  font-family: 'Ubuntu', sans-serif;
}
.modal {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 50%;
  height: auto;
  min-width: 300px;
  z-index: 2;
  visibility: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}
.modal-content {
  padding: 120px 10px;
  text-align: center;
  color: #000;
  background: #bd330f;
  border-radius: 10px;
  border: 1px solid #909090;
  box-shadow: 10px 10px 20px rgba(0, 0, 0, 0.9);
  
  transition: all 300ms ease-in;
  
  /* added for original state - vendor prefixed version should come before unprefixed property */
  -webkit-transform: rotateX(-70deg);
  -moz-transform: rotateX(-70deg);
  -ms-transform: rotateX(-70deg);
  transform: rotateX(-70deg);
}
.modal-open {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  border: transparent;
  background: #fff;
  font-size: 15px;
  font-weight: bold;
  padding: 20px 50px;
  border-radius: 5px;
}
.modal-open:active {
  outline: transparent;
}
.modal-close {
  padding: 8px 40px;
  border-radius: 8px;
  border: transparent;
  background: #212121;
  color: #fff;
  outline: transparent;
}
.overlay {
  position: fixed;
  width: 100%;
  height: 100%;
  visibility: hidden;
  top: 0;
  left: 0;
  z-index: 1;
  opacity: 0;
  background: rgba(0, 0, 0, 0.5);
  transition: all 0.7s;
}
.modal-show {
  opacity: 1;
  visibility: visible;
}
.modal-perspective {
  -webkit-perspective: 900px;
  perspective: 900px;
}
.modal-animate {
  transition: all 300ms ease-in-out;
  /* remove animation, set below for open state */
  -webkit-transform: rotateX(0deg);
  -moz-transform: rotateX(0deg);
  -ms-transform: rotateX(0deg);
  transform: rotateX(0deg);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="modal">
  <div class="modal-content">
    <h3>Modal Dialog</h3>
    <div>
      <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi gravida libero nec velit. Morbi scelerisque luctus velit. Etiam dui sem, fermentum vitae, sagittis id, malesuada in, quam. Proin mattis lacinia justo. Vestibulum facilisis auctor urna.
        Aliquam in lorem sit amet leo accumsan.</p>
      <button class="modal-close">CLOSE ME!</button>
    </div>
  </div>
</div>

<button class="modal-open">~ OPEN MODAL ~</button>

<div class="overlay"></div>
Community
  • 1
  • 1
Harry
  • 87,580
  • 25
  • 202
  • 214
  • 2
    Plus 1 ... Based on own experience and according to [this post](http://stackoverflow.com/a/8962837/2827823), using `transition: all` is not recommended. What's your opinion on that? – Asons Dec 03 '16 at 09:43
  • @LGSon: Yes that is correct. Thanks for linking that here because the OP needs to be aware of it. But I think the impact of using `all` in this example is minimal. – Harry Dec 03 '16 at 11:02
  • Thank's a lot for your help @Harry!! Only adding and removing the `transform: rotate()´. Very simple! Pls, answer me a question: Why I must avoid use keyframe to made a reverse effects? It's only for modals or generally way? – Zkk Dec 03 '16 at 23:52
  • 1
    @Zkk: It is the general way. Animations are generally used when you want to run an effect without any user interaction (or) run only one way etc. If you want to produce the reverse effect it is very complex with CSS animations because you have to write two keyframes, remove the first animation using JS then add the reverse animation etc. Whereas transitions can automatically produce the reverse effect while the reverse state change happens, no extra coding is required. – Harry Dec 04 '16 at 05:09
  • 1
    So I end up writing less code and making the same effect in a simple and better way. I understand! Thank's a lot!! – Zkk Dec 04 '16 at 15:13