Show / hide content recursively base on a delay - css

I am wondering if there is a way in full CSS to reproduce the following animation (the tool-tip box that appears and disappears) and appears again.
I wanted it to be recursive
http://bourbon.io/

You can do this using animations properties (with a custom animation).
Example:
HTML
<div id="container">
<div id="animatediv">
</div>
</div>
CSS
#container {
background-color: yellow;
display: inline-block;
padding: 40px;
}
#animatediv {
width: 100px;
height: 100px;
background-color: red;
position: relative;
animation-name: hideshow;
animation-duration: 3s;
animation-iteration-count: infinite;
animation-direction: alternate;
}
#keyframes hideshow {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
Here's a jsfiddle:
https://jsfiddle.net/fabio1983/j6jj9766/
You can also check this page for more informations:
https://www.w3schools.com/css/css3_animations.asp

Related

How to make CSS animation to do vice versa after being completed?

The code below is a part of my code :
.myBox:hover::after {
animation-name: underline;
animation-duration: 350ms;
animation-fill-mode: forwards;
}
#keyframes underline {
from { width: 0; }
to { width: 100%; }
}
It works nicley, but I want to do it vice versa when animation completed, I mean when it finished then width should be 0 again, In fact for this part I want to do it when my element is not hovered. Which property can help me ?
You need to use alternate and run 2 iterations of the animation:
.box {
height:200px;
background:red;
animation: underline 500ms alternate 2 forwards;
}
#keyframes underline {
from { width: 0; }
to { width: 100%; }
}
<div class="box">
</div>
Or consider the use of transition if you want the effect on hover:
.box {
height: 200px;
background: red;
width: 0;
transition: 500ms;
}
body:hover .box {
width: 100%;
}
<div class="box">
</div>
You can specify multiple values for animations rather then from and to using percentage:
#keyframes underline {
0%, 100% { width: 0; }
50% { width: 100%; }
}
More detailed information can be found here.
.myBox:hover::after {
animation-name: underline infinite;
animation-duration: 350ms;
animation-fill-mode: forwards;
}
#keyframes underline {
from { width: 0; }
to { width: 100%; }
}
You infinite for this

CSS slider with arrows using animation

I am trying to achieve a CSS only slider.
When hovering left and right arrows, the slider has to slide. Of course.
I tried something using animation-play-state, animation-fill-mode (to keep the positions) and animation-direction but I'm not able to fully make it work.
Starting with animation-play-state: paused, hovering the arrows changes it to running.
On hover of the right arrow, everything is fine. We can hover, leave, hover again.
But, as soon as I hover the left arrow (that changes the animation-direction to reverse), it's broken.
Simplified snippet:
.wrapper {
overflow: hidden;
position: relative;
width: 500px;
}
.arrows {
z-index: 2;
position: absolute;
top: 0;
height: 100%;
background: #ddd;
opacity: 0.66;
}
.arrows:hover {
opacity: 1;
}
.arrow-l {
left: 0;
}
.arrow-r {
right: 0;
}
.sliding {
height: 160px;
width: 2000px;
background: linear-gradient(to bottom right, transparent 49.9%, gray 50.1%);
animation: slide 2s linear;
animation-play-state: paused;
animation-fill-mode: both;
}
.arrows:hover~.sliding {
animation-play-state: running;
}
.arrow-l:hover~.sliding {
animation-direction: reverse;
}
#keyframes slide {
0% {
transform: translate(0px, 0);
}
100% {
transform: translate(-1500px, 0);
}
}
<div class="wrapper">
<div class="arrows arrow-l">[ ← ]</div>
<div class="arrows arrow-r">[ → ]</div>
<div class="sliding"></div>
</div>
Can someone help me understand what is happening, and correct this unwanted behaviour?
The main issue here is that changing the direction will keep the current state of the animation BUT it will consider the new direction. Let's take an easy example:
Suppose you have an animation from left:0 to left:100%. If you first run the animation untill left:80% and then you change the direction to reverse you will have left:20%!
Why?
Because with the default direction you reached the 80% (left:80%) of the animation and 80% of the same animation with reverse direction is simply left:20%.
Hover on reverse and you will see that the position of the box is jumping to switch to the new state considering the new direction. It's obvious when the animation ends and you will be switching between the first and last state:
.sliding {
width:100px;
height:100px;
background:red;
left:0%;
position:relative;
animation:slide 5s linear forwards;
animation-play-state:paused;
}
.arrows {
margin:20px;
}
.arrow-r:hover~.sliding {
animation-play-state: running;
}
.arrow-l:hover~.sliding {
animation-direction: reverse;
}
#keyframes slide {
0% {
left: 0%;
}
100% {
left: 100%;
}
}
<div class="wrapper">
<div class="arrows arrow-r">move normal</div>
<div class="arrows arrow-l">reverse !!</div>
<div class="sliding"></div>
</div>
There is no fix for this since it's the default behavior of animation, but instead you can rely on transition to obtain a similar effect. The trick is to play with the duration that you increase/decrease to create the needed effect.
Here is an idea:
.wrapper {
overflow: hidden;
position: relative;
width: 500px;
}
.arrows {
z-index: 2;
position: absolute;
top: 0;
height: 100%;
background: #ddd;
opacity: 0.66;
}
.arrows:hover {
opacity: 1;
}
.arrow-l {
left: 0;
}
.arrow-r {
right: 0;
}
.sliding {
height: 160px;
width: 2000px;
background: linear-gradient(to bottom right, transparent 49.9%, gray 50.1%);
transition:all 2000s linear; /*This will block the current state*/
}
.arrow-r:hover ~ .sliding {
transform: translate(-1500px, 0);
transition:all 2s;
}
.arrow-l:hover ~ .sliding {
transform: translate(0px, 0);
transition:all 2s;
}
<div class="wrapper">
<div class="arrows arrow-l">[ ← ]</div>
<div class="arrows arrow-r">[ → ]</div>
<div class="sliding"></div>
</div>

Why does `animation-direction: reverse` not work for my CSS keyframe animation?

I'm trying to use animation-direction: reverse to refactor my CSS keyframe animation. I have a container div when clicked will toggle an "active" class on it via jQuery which triggers the animation (forward or backward depending on the "active" state). The forward and backward animations are exactly the same thing except the keyframes are in the reverse order. I figured that animation-direction: reverse would enable me to refactor it by just using one animation and reversing it for the other, but it's not working the way I thought it would.
Link to codepen (without using animation-direction: reverse):
https://codepen.io/soultrust/pen/gogKjN
The following markup and CSS (Sass) code snippet is the way it works now without reverse.
<div class="container">
<div class="line"></div>
</div>
$width-height: 100px;
$duration: 1s;
$line-width: 10%;
$animation-distance: $width-height * .45;
#keyframes line-in {
0% { transform: translateY(-$animation-distance); }
50% { transform: translateY(0); }
100% { transform: rotate(-135deg); }
}
#keyframes line-out {
0% { transform: rotate(-135deg); }
50% { transform: translateY(0); }
100% { transform: translateY(-$animation-distance); }
}
.container {
margin: 10rem auto 0;
width: $width-height;
height: $width-height;
position: relative;
border: 1px solid black;
&.active {
.line {
animation-name: line-in;
animation-direction: normal;
}
}
}
.line {
width: 100%;
height: $line-width;
position: absolute;
top: 45%;
background-color: orange;
animation-direction: normal;
animation-name: line-out;
animation-duration: $duration;
animation-fill-mode: forwards;
}
When I change the "active" animation to following, animations in both directions stop working.
&.active {
.line {
animation-name: line-out;
animation-direction: reverse;
}
}
I believe it has something to do with using the same animation because if I just set the animation-direction: reverse and use animation-name: line-in, it correctly plays the line-in animation in reverse.
Very good question. You have already noticed that animation-direction: reverse; does work. You where very close to figuring out this css quirkiness all by yourself.
There are some additional rules to take note off.
When removing/replacing a css animation, the animation will start from 0%,
When you set reverse (while not changing the actual animation), the animation will continue from whatever % it was at.
So when you clicked the element and set the line-out animation:
The animation will start from 0%
Play in whatever direction you've set.
When only applying a new animation direction:
The animation continous from whatever percentage it was, eg, 100%.
You can restart the animation with several forms of trickery. you'll see that the animation is being played in reverse when the element is recreated.
var clickFunc =function(e) {
//toggle the state
$(this).toggleClass("active");
//reset the animatino state by cloning and replacing the element.
var newone = this.cloneNode(true);
this.parentNode.replaceChild(newone, this);
// reapply click handler to the cloned element
$(newone).click(clickFunc)
}
$(function() {
$(".question").click(function() {
$(this).toggleClass("active");
});
$(".answer").click(clickFunc);
$(".restart").click(function() {
$(".line").each(function() {
var newone = this.cloneNode(true);
this.parentNode.replaceChild(newone, this);
});
});
});
#keyframes line-in {
0% {
transform: translateY(-45px);
}
50% {
transform: translateY(0);
}
100% {
transform: rotate(-135deg);
}
}
#keyframes line-out {
0% {
transform: rotate(-135deg);
}
50% {
transform: translateY(0);
}
100% {
transform: translateY(-45px);
}
}
.line {
width: 100%;
height: 10%;
position: absolute;
top: 45%;
background-color: orange;
animation-direction: normal;
animation-name: line-in;
animation-duration: 1s;
animation-fill-mode: forwards;
}
.container {
margin: 1rem auto 0;
width: 100px;
height: 100px;
position: relative;
border: 1px solid black;
}
.container.reverse .line {
animation-name: line-in;
animation-direction: reverse;
}
.container.active .line {
animation-name: line-in;
animation-direction: reverse;
}
.container.active.reverse .line {
animation-name:line-in;
animation-direction: normal;
}
.container.out.active .line {
animation-name: line-out;
animation-direction: normal;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="restart">reset animation state</button><br>
in -out
<div class="container question out">
<div class="line"></div>
</div>
active reversed
<div class="container question">
<div class="line"></div>
</div>
<br>
workaround
<div class="container answer reverse">
<div class="line"></div>
</div>
In order to debug this. You can inspect the animation states in the web dev tools of your browser:
With regards to your refactor:
I would rather have multiple animations in different directions, than doing js tricks in order to restart/reverse an animation.
Depending on how complicated your animation is, you might be better of using css transitions as opposed to animation frames. You would not have to worry about reversing/resetting the animation.

CSS Animation: how to trigger the reverse animation?

I'm trying to create a simple reusable CSS class so I can have this animation everywhere.
Everything works fine except that I can't find any example/documentation on how to trigger the reverse animation.
Here is my HTML:
<div class="cards">
<div class="card">
<div class="frontpage">
<img src="http://lorempixel.com/400/200/"/>
</div>
<div class="rearpage">
<img src="http://lorempixel.com/g/400/200/"/>
</div>
</div>
<div class="card">
<div class="frontpage">
<img src="http://lorempixel.com/400/200/"/>
</div>
<div class="rearpage">
<img src="http://lorempixel.com/g/400/200/"/>
</div>
</div>
</div>
My animation is a "card-flip"-like animation using a simple toggleClass in Javascript to trigger the animation:
$('.card').click(function(){
$(this).toggleClass('opened');
});
And here is my CSS:
.cards {
width: 800px;
margin: auto;
}
.card {
width: 200px;
height: 100px;
position: relative;
display: inline-block;
margin: 10px;
}
.card .frontpage, .card .rearpage {
width: 100%;
height: 100%;
overflow: hidden;
position: absolute;
}
.card .rearpage {
width: 0%;
}
.card .frontpage img, .card .rearpage img {
width: 100%;
height: 100%;
}
/***** ANIMATIONS *****/
/* ANIMATION 1 */
.card .frontpage {
-webkit-animation-duration: 1s;
-webkit-animation-direction: alternate;
-webkit-animation-timing-function: ease-in;
-webkit-animation-fill-mode: forwards;
}
.card.opened .frontpage {
-webkit-animation-name: frontToRear;
}
#-webkit-keyframes frontToRear {
0% { width: 100%; }
50% { width: 0%; margin-left: 50%; }
100% { width: 0%; }
}
/* ANIMATION 2 */
.card .rearpage {
-webkit-animation-duration: 1s;
-webkit-animation-direction: alternate;
-webkit-animation-timing-function: ease-in;
-webkit-animation-fill-mode: forwards;
}
.card.opened .rearpage {
-webkit-animation-name: rearToFront;
}
#-webkit-keyframes rearToFront {
0% { width: 0%; }
50% { width: 0%; margin-left: 50%; }
100% { width: 100%; }
}
What is the smart way of doing this? I wish I could just put some trigger on my .rearcard to trigger the reversed animation but I can't find any way of doing this.
I know I could just write 2 other "reversed" animations and apply them but it seems so dumb that I can't try to do better.
I set up a jsfiddle to help you analyze and test out: http://jsfiddle.net/9yp3U/
Your approach with margin and width to fake a rotation is very interesting, but you can do this much more simply with rotateY
.cards {
width: 800px;
margin:auto;
-webkit-perspective:1000;
}
.card {
width: 200px;
height: 100px;
position: relative;
display: inline-block;
margin: 10px;
-webkit-transition: 1s ease-in;
-webkit-transform-style: preserve-3d;
-webkit-transform:translateZ(1px);
}
.card .frontpage, .card .rearpage, img {
width: 100%;
height: 100%;
position: absolute;
top:0;
left:0;
-webkit-transform-style: preserve-3d;
-webkit-backface-visibility: hidden;
}
.card img {
width: 100%;
height: 100%;
}
.card .rearpage,
.card.opened {
-webkit-transform:rotateY(180deg);
}
Demo
As for the question you asked, you can play animations backwards by using the animation-direction:backwards property, though with CSS toggling animations is hard. Thus, I'd recommend you use a transition instead since it's only a change between two states.
And FYI just in case, CSS selector don't always have to be in the parent child format. In your case applying just .child will do the same. The parent child selector is only necessary when needing to a higher selector specificity than existing properties.
Oh, and also FYI, jQuery isn't needed for this. I included an (untested) javascript equivalent if you want. If this is the only place where you're using jQuery on your page I'd recommend not using it because loading the whole jQuery library takes some time and data.

Delayed slide after page load using CSS

I have a header inside of a DIV and I would like to add in a transition so it slides into view a couple of seconds after the pages loads.
Is this possible using CSS alone? I understand how transitions and transform works but they load in immediately and that isn't what I want.
In order for this to work, you'll need to place the CSS at the bottom of your Body content, to ensure the DOM has rendered as well as any other CSS/scripts run (e.g. the page has loaded). That said, the better way would be to listen to the document load event in Javascript, and apply a transitioning class at that point, as noted by Josiah in the comment to your question.
Demo Fiddle
HTML
<div id="slidingContent"></div>
CSS
html,body{
padding:0;
margin:0;
}
#slidingContent {
height: 100px;
width: 100%;
margin-top: -120px;
color: red;
background-color: grey;
-webkit-animation-name: slideIn;
-webkit-animation-duration: 0.3s;
-webkit-animation-delay: 2s;
-webkit-animation-fill-mode:forwards;
animation-name: slideIn;
animation-duration: 0.3s;
animation-delay: 2s;
animation-fill-mode:forwards;
}
#-webkit-keyframes slideIn {
0% { margin-top: -120px; }
100% { margin-top: 0px; }
}
#keyframes slideIn {
0% { margin-top: -120px; }
100% { margin-top: 0px; }
}

Resources