I have a working animation that starts on load with pure CSS. The problem with both opacity and visibility is that even if the div is hidden, it still takes up space.
Question
How can I make the div disapear like display: none after the animation is done?
Notes
I would prefer to have a pure CSS solution. The less hackish solution, the better.
I've seen similar questions, but not exactly this case and no good answers for this problem.
I use animation and not transition because it animates on load.
.message.success {
background: #28a745;
color: #fff;
animation: autohide 2s forwards;
padding: 1rem;
}
#keyframes autohide {
0% {
opacity: 1;
}
90% {
opacity: 1;
}
100% {
opacity: 0;
}
}
<div class="message success">
Success!
</div>
This text below is expected to jump up after animation is done.
You could use the height property to achieve this effect:
#keyframes autohide {
0% {
opacity: 1;
}
90% {
opacity: 1;
}
99% {
height: auto;
padding: 1rem;
}
100% {
opacity: 0;
height: 0;
padding: 0;
}
}
height is kept auto until near the end of the animation (99%), then set to 0 as it completes.
You could set to zero the padding and the font-size at the last keyframe
.message.success {
background: #28a745;
color: #fff;
animation: autohide 2s forwards;
padding: 1rem;
}
#keyframes autohide {
0% {
opacity: 1;
}
85% {
opacity: 1;
}
95% {
opacity: 0;
padding: 1rem;
font-size: inherit;
}
100% {
padding: 0;
font-size: 0;
opacity: 0;
}
}
<div class="message success">
Success!
</div>
This text below is expected to jump up after animation is done.
There you go i think this is what you want.
By giving height to 0 works perfectly with transition
.message.success {
background: #28a745;
color: #fff;
animation: autohide 2s forwards;
transition: height 2s ease;
}
#keyframes autohide {
0% {
opacity: 1;
height: auto;
}
90% {
opacity: 1;
height: auto;
}
100% {
opacity: 0;
height: 0;
}
}
<div class="message success">
Success!
</div>
This text below is expected to jump up after animation is done.
You can play with transition as per req.
Related
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
I want to make the first square appear after 3s and then it needs to disappear. After it disappears, the second square becomes visible after 11s. How to make the second square appear only after the first one has disappeared after 11 seconds?
.one, .two{
background-color: black;
height: 50px;
width: 50px;
}
.one{
animation: fadein 3s, fadeout 7s ;
}
.two{
animation: fadein 11s, fadeout 17s ;
}
#keyframes fadein {
from { opacity: 0; }
to { opacity: 1; }
}
#keyframes fadeout {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
<div class="one"></div>
<br>
<div class="two"></div>
Use animation-delay maybe?
Also note that you cannot animate the same css attribute in multiple keyframes on the same element. The css defined in the last keyframe will always override the earlier ones. You can try to use % to achieve something similar to what you want.
.one, .two{
background-color: black;
height: 50px;
width: 50px;
opacity: 0;
}
.one{
animation: fadeinout1 10s;
}
.two{
animation: fadeinout2 28s ;
animation-delay: 10s ;
}
#keyframes fadeinout1 {
0%, 100% { opacity: 0; }
30% { opacity: 1; } /*Simulate 3s, out of the whole animation of 10s*/
}
#keyframes fadeinout2 {
0%, 100% { opacity: 0; }
39% { opacity: 1; } /*Simulate 11s, out of the whole animation of 28s*/
}
<div class="one"></div>
<br>
<div class="two"></div>
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>
I would like each <div> to stay on screen for 8 sec before it fades out.
Also I would like them to fade into each other, opposed to fading to black and then the other fades in.
This works great thanks to #giovannipds except for a pop and not on screen for 8 sec. If you remove the z-index change it transitions clean.
.slider {
line-height: 1.5;
height: 200px;
margin: 20px auto;
position: relative;
width: 300px;
}
.slide {
padding: 20px;
position: absolute;
width: 100%;
height: 100%;
}
.slide,.slide a {
color: #fff;
}
.slide1 {
animation: fade 8s infinite;
background: red;
}
.slide2 {
animation: fade2 8s infinite;
background: blue;
}
#keyframes fade
{
0% { opacity: 1 ; z-index: 2; }
33.333% { opacity: 0; z-index: 1; }
66.666% { opacity: 0; z-index: 1; }
100% { opacity: 1; z-index: 2; }
}
#keyframes fade2
{
0% { opacity: 0; z-index: 1; }
33.333% { opacity: 1; z-index: 2; }
66.666% { opacity: 1; z-index: 2; }
100% { opacity: 0; z-index: 1; }
}
<div class="slider">
<div class="slide slide1">
<ul>
<li>Google</li>
<li>Globo.com</li>
</ul>
</div>
<div class="slide slide2">
<ul>
<li>Love Mondays</li>
<li>Hotmail</li>
</ul>
</div>
</div>
Old question but I was recently confronted with the same POP problem and I managed to solve it by separating the image and caption markup on each slide and by assigning separate cross-fade animations to each:
image animation (with opacity but without z-index) => just like fade and fade2 in the snippet above but without z-index; this actually solved the POP
caption animation (with both opacity and z-index) => just like fade and fade2 in the snippet above, this would address links or any other HTML you might want on top of image
I have a link that's running an infinite animation with the background color. I want to stop the animation and transition into a different background color on hover.
.startlink{
background-color:#206a9e;
color:#fff;
border-radius:15px;
font-family: 'Myriad Pro';
-webkit-animation:changeColor 3.4s infinite;
-webkit-transition:all 0.2s ease-in;
}
.startlink:hover{
-webkit-animation-play-state: paused;
background-color: #014a2a;
}
#-webkit-keyframes changeColor
{
0% {background:#206a9e;}
50% {background:#012c4a;}
100% {background:#206a9e;}
}
Why is this code not working? And is there an alternate way to get this done? (preferably without Javascript).
Try -webkit-animation: 0;. Demo here. 0 is the default value for animation or what you must set to disable any existing CSS3 animations.
-webkit-animation-play-state: paused
and
-webkit-animation-play-state: running
Found another way round to achieve this.
Write another animation keyframe sequence and call it on your hover.
.startlink{
background-color:#206a9e;
color:#fff;
border-radius:15px;
font-family: 'Myriad Pro';
-webkit-animation:changeColor 3.4s infinite;
-webkit-transition:all 0.2s ease-in;
}
.startlink:hover{
-webkit-animation:hoverColor infinite;
}
#-webkit-keyframes changeColor
{
0% {background:#206a9e;}
50% {background:#012c4a;}
100% {background:#206a9e;}
}
#-webkit-keyframes hoverColor
{
background: #014a2a;
}
I was trying to achieve the same kind of thing and after trying to dynamically change keyframes and all, I found a weird solution by using basic css, see fiddle here. It is not very elegant but does exactly what I (and you, I hope) want.
#menu, #yellow{
position: fixed;
top: 2.5vw;
right: 2.5%;
height: 25px;
width: 25px;
border-radius: 30px;
}
#menu{
animation: blink 2s infinite;
transition: 1s;
}
#keyframes blink{
0% { background-color: grey; }
50% { background-color: black; }
100% { background-color: grey; }
}
#yellow{
background-color: rgba(255, 0, 0, 0);
transition: 1s;
}
#disque:hover #yellow{
pointer-events: none;
background-color: rgba(255, 0, 0, 1);
}
#disque:hover #menu{
opacity: 0;
}
<div id="disque">
<div id="menu"></div>
<div id="yellow"></div>
</div>
I have the same issue and the solution I found is the following.
Create the animation you want and for the element you and to each assign each one a different class.
Then use .mouseover() or .mouseenter() jQuery events toggle between the classes you assigned to each animation.
It is similar to what you use for a burger menu, just with a different handler.
For those who are interested by animation slide with stop between 2 images
var NumImg = 1; //Img Number to show
var MaxImg = 3; //How many Img in directory ( named 1.jpg,2.jpg ...)
function AnimFond() {
NumImg = NumImg> MaxImg ? 1 : NumImg +=1;
var MyImage = "http://startinbio.com/Lib/Images/Fond/" + NumImg + ".jpg";
$("#ImgFond1").attr("src", MyImage);
$("#ImgFond2").fadeOut(3000, function() {
$("#ImgFond2").attr("src", MyImage);
$("#ImgFond2").fadeIn(1);
});
}
setInterval("AnimFond()", 10000); //delay between 2 img
#AnimFond {
position: fixed;
height: 100%;
width: 100%;
margin: 0 0 0 -8;
}
#AnimFond img {
position: absolute;
left: 0;
height: 100%;
width: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.2.3/jquery.min.js"></script>
<div id="AnimFond">
<img id="ImgFond1" src="http://startinbio.com/Lib/Images/Fond/1.jpg" />
<img id="ImgFond2" src="http://startinbio.com/Lib/Images/Fond/1.jpg" />
</div>