I would like to define a CSS3 animation which, at some points during the animation, uses the natural value for a property as if the animation was not applied.
e.g.
#keyframes fadeblue
{
0%
{
background-color: natural;
}
100%
{
background-color: blue;
}
}
.thing1
{
background-color: red;
animation: fadeblue 2s;
}
.thing2
{
background-color: green;
animation: fadeblue 2s;
}
thing1 would fade from red to blue while thing2 would fade from green to blue.
What value should I use in the place of natural in the 0% keyframe?
I have tried both inherit and transparent but neither had the desired effect.
N.B. I know this can be done with a JavaScript solution but if possible I'd prefer a pure css3 solution.
So it seems you can't reference the original colour in keyframes. However, you can just specify one keyframe in a keyframes declaration and let the browser interpolate the colors for you. Using a keyframe of just 50% will use the original properties at 0% (aka from) and 100% (aka to).
With this knowledge we can also effectively queue animations using animation-delay to create what looks like a single animation, but isn't.
For example:
#keyframes fadeblue {
50% {
background-color: blue;
}
}
#keyframes fadewhite {
50% {
background-color: white;
}
}
.thing1 {
background-color: red;
animation: fadeblue 2s,
fadewhite 2s 2s;
/* shorthand here is: animation-name animation-duration animation-delay */
}
.thing2 {
background-color: green;
animation: fadeblue 2s,
fadewhite 2s 2s;
}
.thing3 {
background-color: yellow;
animation: fadeblue 2s,
fadewhite 2s 2s;
}
.thing4 {
background-color: purple;
animation: fadeblue 2s,
fadewhite 2s 2s;
}
<div class="thing1">Thing 1</div>
<div class="thing2">Thing 2</div>
<div class="thing3">Thing 2</div>
<div class="thing4">Thing 2</div>
You'll see the elements fade to blue and back to the original colour, then fade to white then the original colour.
jsfiddle for good measure.
You can achieve this if you use a pseudo-element (e.g. :before) for .thing1 and . thing2, set it's color to blue, and animate it's opacity. It's a bit more work, but I believe it will be more flexible solution:
(see working demo below)
#keyframes fadeblue {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
.thing1,
.thing2 {
width: 100px;
height: 100px;
display: inline-block;
position: relative;
}
.thing1:before,
.thing2:before {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: blue;
animation: fadeblue 2s infinite;
}
.thing1 {
background-color: red;
}
.thing2 {
background-color: green;
}
<div class="thing1"></div>
<div class="thing2"></div>
Related
I want to have two animations applied to an element. These animations will execute sequentially infinite number of times. I want to use pure CSS without JS.
#keyframes show {
from,
to {
z-index: 100;
}
}
#keyframes wait {
from,
to {
}
}
.block {
position: absolute;
z-index: -100;
width: 100px;
height: 100px;
border: 1px solid black;
animation: 1s show infinite, 1s wait infinite;
}
.block-a {
background-color: red;
animation-delay: 0s, 1s;
}
.block-b {
background-color: purple;
animation-delay: 1s, 2s;
}
.block-c {
background-color: yellow;
animation-delay: 2s, 3s;
}
<div class="container">
<div class="block block-a">1</div>
<div class="block block-b">2</div>
<div class="block block-c">3</div>
</div>
Here is my current solution on codepen: https://codepen.io/olafvolafka/pen/oNpPeqj
The issue is the animation stops after the last animation and doesn't repeat.
Here below you will see an implementation of A Haworth's Comment to enforce the z-index at the end of each animation iteration to return to the same value it was at the start (this case: -100).
Doing this is with the keyframe 50% setting the z-index at the front (100) . So that when each animation ends the properties are identical to when it began.
The animation is also set to cycle/repeat every 3 seconds rather than every 1 second as per your original code. This is that each iteration of the animation should run and complete before being called again; so 3 blocks means it runs for 3s. Each block having 1second as per your delay values in each blocks own class CSS code.
I have removed the wait animation because it simply didn't do anything. If you want an animation to wait there are various ways of doing this, not least with keyframes and animation-delay.
#keyframes show {
from {
z-index: -100;
}
50% {
z-index: 100;
}
to {
z-index: -100;
}
}
.block {
position: absolute;
z-index: -100;
width: 100px;
height: 100px;
border: 1px solid black;
animation: 3s show infinite;
}
.block-a {
background-color: red;
animation-delay: 0s;
}
.block-b {
background-color: purple;
animation-delay: 1s;
}
.block-c {
background-color: yellow;
animation-delay: 2s;
}
<div class="container">
<div class="block block-a">1</div>
<div class="block block-b">2</div>
<div class="block block-c">3</div>
</div>
I would like to use a single #keyframes rule to animate an element from one state to another and then to get back to the original state when I do an action (with the same animation). I saw that using animation-direction: reverse; is a way to play the animation in reverse. However, when I try to use it, the transitions on my element disappear. If I set a new #keyframes with the reversed state it works fine.
What is the point of animation-direction in this case? I am misunderstanding something?
Is there a way to play an animation in both directions with a single #keyframes rule without loosing the transitions? I can't use transition, I need animation.
Here is a example to play with (hover the squares):
div {
width: 100px;
height: 100px;
animation: fade 0.6s ease-in-out forwards;
margin: 15px;
display: inline-flex;
align-items: center;
justify-content: center;
color: white;
}
#box-1:hover {
animation: fade 0.6s ease-in-out forwards;
animation-direction: reverse;
}
#box-2:hover {
animation: fadeReverse 0.6s ease-in-out forwards;
}
#keyframes fade {
0% { background: red; }
100% { background: blue; }
}
#keyframes fadeReverse {
0% { background: blue; }
100% { background: red; }
}
<div id="box-1">:(</div>
<div id="box-2">:)</div>
It's because you apply the same animation to the element on hover as the animation that is on the default state of the element.
So the element already had that animation with the default direction but then you apply it again with the reverse. But it won't work. I don't really know why this happens. But applying the same animation on an element twice, won't work. So you need 2 different keyframes.
You can use a reverse animation or duplicate the existing one and use it with direction: reverse
Read more here
restart animation
more info here
another article here
If you REALLY want to use just 1 animation this can be solved with javascript by removing and adding an 'animate-me' class . But it still wouldn't be ideal
div {
width: 100px;
height: 100px;
animation: fade 0.6s ease-in-out forwards;
margin: 15px;
display: inline-flex;
align-items: center;
justify-content: center;
color: white;
}
#box-1:hover {
animation: fade2 0.6s ease-in-out forwards;
animation-direction: reverse;
}
#box-2:hover {
animation: fadeReverse 0.6s ease-in-out forwards;
}
#keyframes fade {
0% { background: red; }
100% { background: blue; }
}
#keyframes fade2 {
0% { background: red; }
100% { background: blue; }
}
#keyframes fadeReverse {
0% { background: blue; }
100% { background: red; }
}
<div id="box-1">:(</div>
<div id="box-2">:)</div>
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'm working on a css animation to switch the background color of an element.
This animation is only two phases and no smooth transitions between both phases.
It means, the first 50% of the animation, the background color will be blue, and the last 50% of the animation, the background color will be grey, without an transition in between.
Here's the animation fully working:
div {
width: 200px;
height: 200px;
animation: bg 4s linear infinite;
}
#keyframes bg {
0% {
background: blue;
}
50% {
background: blue;
}
50.00001% {
background: grey;
}
100% {
background: grey;
}
}
<div></div>
I'm wondering if there's a simpler way to do that. What I'm looking for is to use only from and to inside the keyframes without any additional step.
You can achieve it using the animation-timing-function: steps(1) as given in below snippet. You can find more details about the animation-timing-function here and the generic steps value here in MDN.
div {
width: 200px;
height: 200px;
animation: bg 4s steps(1) infinite;
}
#keyframes bg {
0% {
background: blue;
}
50% {
background: grey;
}
}
<div></div>
Note: I have set the keyframe for grey color at 50% instead of 100% due to the problem discussed in this answer.
You can also use a short-cut notation :
div {
width: 200px;
height: 200px;
animation: bg 4s linear infinite;
}
#keyframes bg {
from, 50% {
background: blue;
}
50.00001%, to {
background: grey;
}
}
<div></div>
I was discussing with someone the ability for CSS3 to do animations upon click and hover and I decided to make a little test to show them. I decided to do a bit of boundary pushing and made it so that when you hovered over the animation happened, and when you un-hovered it waited 3 seconds and then ran the animation to put it back.
The problem however is that when the page loads, it runs the "un-hover" animation.
Any ideas for getting around this or another method that's better?
What the below code does is when you hover over the red box it animates is blue. When you un-hover is animates it back red again after 3 seconds. Both of them calculate to a 1 second animation time.
I know this could be fixed with one very simple line of JavaScript, but I'm only interested in seeing if there's a CSS answer.
#-webkit-keyframes makeblue {
0% {
background: red;
}
100% {
background: blue;
}
}
#keyframes makeblue {
0% {
background: red;
}
100% {
background: blue;
}
}
#-webkit-keyframes makered {
0% {
background: blue;
}
75% {
background: blue;
}
100% {
background: red;
}
}
#keyframes makered {
0% {
background: blue;
}
75% {
background: blue;
}
100% {
background: red;
}
}
div {
width: 100px;
height: 100px;
background: red;
position: relative;
-webkit-animation: makered 4s;
animation: makered 4s;
}
div:hover {
-webkit-animation: makeblue 1s;
animation: makeblue 1s;
background: blue;
}
<div></div>
EDIT 1
Does anyone know if this type of functionality exists, or even potentially planned for the future?:
#keyframes makeblue {
0% {
background: [CurrentValue];
}
100% {
background: blue;
}
}
Having this would be able to fix the problem. If this doesn't exist, I think it should :).
If you are dealing with background or simple css only (not a keyframe animation), you can have it with transition delay, check it out at jsfiddle!:
div {
width: 100px;
height: 100px;
background-color: red;
position: relative;
transition:background-color 0.25s 3s linear;
}
div:hover {
background-color:blue;
transition:background-color 0.25s linear;
}