Radek Anuszewski
Radek Anuszewski

Reputation: 1910

Blind-like animation with CSS3 only

I want to toggle notification with jQuery UI-like blind effect: jQuery UI blind effect

To achieve it, I created CSS3 animations:

.blind-top-in{
    -webkit-animation-duration: 2s;
    -webkit-animation-name: blindTopIn;
    animation-duration: 2s;
    animation-name: blindTopIn;
}

.blind-top-out{
   -webkit-animation-duration: 2s;
   -webkit-animation-name: blindTopOut;
   animation-duration: 2s;
   animation-name: blindTopOut;
}

@-webkit-keyframes blindTopIn{
    from{
        max-height: 0px;
        height: 0 !important;
}
    to{
        max-height: 75px;
        height: auto !important;
    }
}
@-webkit-keyframes blindTopOut{
    from{
        max-height: 75px;
        height: auto !important;
    }
    to{
        max-height: 0px;
        height: 0 !important;
    }
}
@keyframes blindTopIn{
    from{
        max-height: 0px;
        height: 0 !important;
    }
    to{
        max-height: 75px;
        height: auto !important;
    }
}
@keyframes blindTopOut{
    from{
        max-height: 75px;
        height: auto !important;
    }
    to{
        max-height: 0px;
        height: 0 !important;
    }
}

And idea is that it should blind from 0px width to auto/75px and backwards. Unfortunately, this is not working - it looks like "half-height notification" appears and animate to normal height, then if I add blind-top-out class it animate to half-height and then dissapears without animation. What am I doing wrong? I would be very happy if anybody decides to help me - thank you in advance.

Snippet - working not exactly like it should (I don't know why), but you see that animation animate only "half" of notification

.blind-top-in{
    -webkit-animation-duration: 2s;
    -webkit-animation-name: blindTopIn;
    animation-duration: 2s;
    animation-name: blindTopIn;
}

.blind-top-out{
   -webkit-animation-duration: 2s;
   -webkit-animation-name: blindTopOut;
   animation-duration: 2s;
   animation-name: blindTopOut;
}

@-webkit-keyframes blindTopIn{
    from{
        max-height: 0px;
        height: 0 !important;
}
    to{
        max-height: 75px;
        height: 75px !important;
    }
}
@-webkit-keyframes blindTopOut{
    from{
        max-height: 75px;
        height: 75px !important;
    }
    to{
        max-height: 0px;
        height: 0 !important;
    }
}
@keyframes blindTopIn{
    from{
        max-height: 0px;
        height: 0 !important;
    }
    to{
        max-height: 75px;
        height: 75px !important;
    }
}
@keyframes blindTopOut{
    from{
        max-height: 75px;
        height: 75px !important;
    }
    to{
        max-height: 0px;
        height: 0 !important;
    }
}
<html>
    <head>
        <title>TODO supply a title</title>
        <meta charset="windows-1250">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
        <!-- Optional theme -->
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css">
        
        <script type="text/javascript" src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
            
        <script type="text/javascript">
            "use strict";
            $(document).ready(function(){
                $("#showBtn").click(function(){
                      $("#notification").addClass("blind-top-in").removeClass("blind-top-out")});
                  $("#hideBtn").click(function(){
                      $("#notification").addClass("blind-top-out").removeClass("blind-top-in");
                });
            });
            
        </script>
    </head>
    <body class="container">
      <div id="notification" class="alert alert-info">Notify user</div>
            <button id="showBtn" class="btn btn-success btn-sm" style="margin-top: 50px;">Show</button>
      <button id="hideBtn" class="btn btn-danger btn-sm" style="margin-top: 80px;">Hide</button>
        </div>
    </body>
</html>

Upvotes: 2

Views: 6704

Answers (1)

Nico O
Nico O

Reputation: 14102

Here is one way to do it with transitions. The nice thing about this, that you don't need to know the actual height of the element, you transit.

Click here for the jsFiddle demo

Here is the code:

.blind-content
{
   background-color: silver; 
}
.blind-content.origin-top
{
  transform-origin: top;  
}
.blind-content.origin-middle
{
  transform-origin: middle;  
}
.blind-content.origin-bottom
{
  transform-origin: bottom;  
}

.blind-content.in
{
     -webkit-animation: blind-in 1s infinite;
    animation: blind-in 1s infinite;
}

.blind-content.out
{
    -webkit-animation: blind-out 1s infinite;
    animation: blind-out 1s infinite;
}

@-webkit-keyframes blind-in {
      0% { transform: scaleY(0); }
    100% { transform: scaleY(1); }
}

@-webkit-keyframes blind-out {
    0% { transform: scaleY(1); }
    100% { transform: scaleY(0); }
}


@keyframes blind-in {
      0% { transform: scaleY(0); }
    100% { transform: scaleY(1); }
}

@keyframes blind-out {
    0% { transform: scaleY(1); }
    100% { transform: scaleY(0); }
}

And multiple sample usages with html:

<h2>Blind in</h2>
<h3>Blind in, from top</h3>
<div class="blind-content in origin-top">
    <p>Hello, i'am content.</p>
</div>

<h3>Blind in, from middle</h3>
<div class="blind-content in origin-middle">
    <p>Hello, i'am content.</p>
</div>

<h2>Blind in, from bottom</h2>
<div class="blind-content in origin-bottom">
    <p>Hello, i'am content.</p>
    <p>Hello, i'am content.</p>
    <p>Hello, i'am content.</p>
</div>

<h2>Blind out</h2>
<h3>Blind out, from top</h3>
<div class="blind-content out origin-top">
    <p>Hello, i'am content.</p>
</div>

<h3>Blind out, from middle</h3>
<div class="blind-content out origin-middle">
    <p>Hello, i'am content.</p>
</div>

<h3>Blind out, from bottom</h3>
<div class="blind-content out origin-bottom">
   <p>Hello, i'am content.</p>
    <p>Hello, i'am content.</p>
    <p>Hello, i'am content.</p>
</div>

You will of course have to use javascript to trigger the animations at the right time via adding and removing classes. And the animation may not need to be repeated, but played once. This is is just for the demo.


When you don't like the content to be shrinked by the animation, you may go for another solution. As we can not have a transition to: height: auto, we will have to use the max-height property for this.

JsFiddle Demo here

Some CSS:

.blind-content
{
   background-color: silver;
   transition-property: max-height, height;
   overflow: hidden;
}

.blind-content.in
{
     -webkit-animation: blind-in 3s infinite;
    animation: blind-in 3s infinite;
}

.blind-content.out
{
    -webkit-animation: blind-out 3s infinite;
    animation: blind-out 3s infinite;
}

@-webkit-keyframes blind-in {
      0% { max-height:0; }
    100% { max-height: 1000px; }
}

@-webkit-keyframes blind-out {
    0% { max-height: 1000px; }
    100% {  max-height:0;  }
}


@keyframes blind-in {
      0% { max-height:0; }
    100% { max-height: 1000px; }
}

@keyframes blind-out {
    0% { max-height: 1000px; }
    100% {  max-height:0;  }
}

Upvotes: 2

Related Questions