CSS keyframes only works in Chrome - css

i'm trying to make a simple animation using keyframes, but it only works in Chrome. Here is the code (i've only included keyframes code once, for shorter post):
#keyframes logokf {
0% {
background-image: url('gfx/logo1.png');
}
20% {
background-image: url('gfx/logo2.png');
}
40% {
background-image: url('gfx/logo3.png');
}
60% {
background-image: url('gfx/logo4.png');
}
80% {
background-image: url('gfx/logo1.png');
}
100% {
background-image: url('gfx/logo1.png');
}
}
#-webkit-keyframes logokf {
}
#-moz-keyframes logokf {
}
#-o-keyframes logokf {
}
#-ms-keyframes logokf {
}
#logo:hover {
float: left;
height: 75px;
margin: 28px 0 22px;
width: 276px;
/*animation-name*/
-webkit-animation-name:logokf;
-moz-animation-name:logokf;
-ms-animation-name:logokf;
-o-animation-name:logokf;
animation-name:logokf;
/*animation-duration*/
-webkit-animation-duration:1s;
-moz-animation-duration:1s;
-ms-animation-duration:1s;
-o-animation-duration:1s;
animation-duration:1s;
/*animation-iteration-count*/
-webkit-animation-iteration-count:infinite;
-moz-animation-iteration-count:infinite;
-ms-animation-iteration-count:infinite;
-o-animation-iteration-count:infinite;
animation-iteration-count:infinite;
/*animation-timing-function*/
-webkit-animation-timing-function:lineare;
-moz-animation-timing-function:lineare;
-ms-animation-timing-function:lineare;
-o-animation-timing-function:lineare;
animation-timing-function:lineare;
/*animation-delay*/
-webkit-animation-delay:0s;
-moz-animation-delay:0s;
-ms-animation-delay:0s;
-o-animation-delay:0s;
animation-delay:0s;
}
Any thoughts of how can i fix it or keyframes are not yet supported from other browsers?

background-image itself does not appear to be a valid transitionable property. It may happen to work in Chrome, but it's probably just lucky. When it's implemented, you'll be looking to use the crossfade capability in CSS images.

Related

CSS #keyframes translate3d Compatibility

How do I specifically check for compatibility of #keyframes translate3d animations with the browser ?
Please Don't close this question since I've tried many stackoverflow solutions before asking this question.
I want to check whether the browser my webpage runs is compatible for running animations, since many android browsers(Old Ones) are not capable of running them, they just stop displaying output text when animation fails (In MY Case). So, I would like to either stop animations or redirect them to another copy of my same website without any animations :)
P.S I've also tried using #supports, but of no use :(
h1,h2{
height: 40px;
animation: an 1s ease-out 1 both;
}
#keyframes an {
from {
opacity: 0;
transform: perspective(500px) translate3d(-35px, -40px, -150px) rotate3d(1, -1, 0, 35deg);
}
to {
opacity: 1;
transform: perspective(500px) translate3d(0, 0, 0);
}
}
<h1 id="h1" class="th">Test Texts</h1>
<h2 id="h2" class="th">Also Test Texts..</div>
#supports query works just fine. It has to be at top level of the code. You also need to provide some dummy values for the translate3d.
#supports(transform: translate3d(100px,100px,10px)){
div{
background: blue;
}
}
#supports not (transform: translate3d(100px,100px,10px)){
div{
background: red;
}
}
div{
width: 250px;
height: 250px;
)
<div></div>
For browsers with no support for #supports query, you can add default value/property to the element. You also need to add !important to values of properties inside of #supports to override the default value.
This should work on all browsers.
#supports(transform: translate3d(100px,100px,10px)){
div{
background: blue !important;
}
}
#supports not (transform: translate3d(100px,100px,10px)){
div{
background: red !important;
}
}
div{
width: 250px;
height: 250px;
background: red; /* default value */
)
<div></div>
Applying this to your snippet, you get this:
#supports(transform: translate3d(100px, 100px, 10px)) {
h1,
h2 {
animation: an 1s ease-out 1 both !important;
}
#keyframes an {
from {
opacity: 0;
transform: perspective(500px) translate3d(-35px, -40px, -150px) rotate3d(1, -1, 0, 35deg);
}
to {
opacity: 1;
transform: perspective(500px) translate3d(0, 0, 0);
}
}
}
#supports not (transform: translate3d(100px, 100px, 10px)) {
h1,
h2 {
animation: an 1s ease-out 1 both !important;
/*you can also set it to efault animation */
}
#keyframes an {
/* some different animation */
}
}
h1,
h2 {
height: 40px;
animation: defaultA 1s ease-out 1 both;
}
#keyframes defaultA {
/* some default animation */
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
<h1 id="h1" class="th">Test Texts</h1>
<h2 id="h2" class="th">Also Test Texts..</h2>
Check with media query:
#media all and (-webkit-transform-3d) {
css animation when supported
};
Check with #supports:
#supports (transform: translate3d) {
}
or
#supports not (transform: translate3d) {
}
or you can check out this javascript solution
https://gist.github.com/lorenzopolidori/3794226

setting intervals with CSS3 animations

I am trying to create a sort of slideshow with CSS. I set several background images which gradually fade in one after another.
What I cannot do, though, is setting an interval of some seconds between an image and the other one, so they do not start fading as soon they are fully rendered.
I do not want to include JQuery otherwise the project would be already complicated since I am already using React. Any ideas?
CSS
.App {
text-align: center;
background-size: initial;
animation: animatedBird 60s infinite;
}
#keyframes animatedBird {
0% { background-image: url('../images/arch1.jpg');}
25% { background-image: url('../images/computer.jpg');}
50% { background-image: url('../images/arch2.jpg');}
75% { background-image: url('../images/computer.jpg');}
100% { background-image: url('../images/arch1.jpg');}
}
An idea is to initially load all the images using multiple background so that you won't have any delay on the animation:
body {
background-image:
url('https://picsum.photos/800/800?image=1040'), /*put the first one on the Top*/
url('https://picsum.photos/800/800?image=1069'),
url('https://picsum.photos/800/800?image=1042');
background-size:cover;
animation: animatedBird 10s infinite;
}
#keyframes animatedBird {
0% {
background-image: url('https://picsum.photos/800/800?image=1040');
}
25% {
background-image: url('https://picsum.photos/800/800?image=1069');
}
50% {
background-image: url('https://picsum.photos/800/800?image=1042');
}
75% {
background-image: url('https://picsum.photos/800/800?image=1069');
}
100% {
background-image: url('https://picsum.photos/800/800?image=1040');
}
}
Here is without intial load to see the difference:
body {
background-size:cover;
animation: animatedBird 10s infinite;
}
#keyframes animatedBird {
0% {
background-image: url('https://picsum.photos/800/800?image=1041');
}
25% {
background-image: url('https://picsum.photos/800/800?image=1068');
}
50% {
background-image: url('https://picsum.photos/800/800?image=1043');
}
75% {
background-image: url('https://picsum.photos/800/800?image=1068');
}
100% {
background-image: url('https://picsum.photos/800/800?image=1041');
}
}
UPDATE
And to keep the image for a period of time you can try this:
body {
background-image:
url('https://picsum.photos/800/800?image=1040'), /*put the first one on the Top*/
url('https://picsum.photos/800/800?image=1069'),
url('https://picsum.photos/800/800?image=1042');
background-size:cover;
animation: animatedBird 10s infinite;
}
#keyframes animatedBird {
0%,20% {
background-image: url('https://picsum.photos/800/800?image=1040');
}
25%,45% {
background-image: url('https://picsum.photos/800/800?image=1069');
}
50%,70% {
background-image: url('https://picsum.photos/800/800?image=1042');
}
75%,95% {
background-image: url('https://picsum.photos/800/800?image=1069');
}
100% {
background-image: url('https://picsum.photos/800/800?image=1040');
}
}
You can try this:
body {
animation: animatedBird 10s infinite;
}
#keyframes animatedBird {
0%, 25% {
background-image: url('https://picsum.photos/800/800?image=1082');
}
50%, 75% {
background-image: url('https://picsum.photos/800/800?image=1083');
}
100% {
background-image: url('https://picsum.photos/800/800?image=1082');
}
}

How do I reverse this CSS rotate animation?

I have this CSS animation which I'm trying to reverse the animation of based on a class being added to a DOM node. I've tried multiple things but with no avail. Here is the code I'm using, see below:
EXAMPLE
// Closed state
#-moz-keyframes spin-close { 100% { -moz-transform: rotate(-0deg); } }
#-webkit-keyframes spin-close { 100% { -webkit-transform: rotate(-0deg); } }
#keyframes spin-close { 100% { transform:rotate(-0deg); } }
// Open state
#-moz-keyframes spin-open { 100% { -moz-transform: rotate(-90deg); } }
#-webkit-keyframes spin-open { 100% { -webkit-transform: rotate(-90deg); } }
#keyframes spin-open { 100% { transform:rotate(-90deg); } }
I don't know whether I'm looking at it all wrong? Please advise(a demo would be awesome).
Don't bother with javascript or animations. Use a CSS transition for this:
.image {
position: absolute;
top: 50%;
left: 50%;
width: 120px;
height: 120px;
margin:-60px 0 0 -60px;
transition:all 1s ease-out;
transform:rotate(0deg);
-webkit-transform:rotate(0deg); /* Safari and Chrome */
}
.image:hover {
transform:rotate(90deg);
-webkit-transform:rotate(90deg); /* Safari and Chrome */
}
http://jsfiddle.net/Ugc5g/892/
To reverse the rotation, you can simply change the degree value to the opposite value. For example, if the element is currently rotated 45 degrees clockwise, you can reverse the rotation by rotating it -45 degrees.
transform: rotate(-45deg);

Animation iteration delay CSS3

Is there a way to add a delay between each iteration?
EX: I want to add a first delay of 2s and an interation delay of 10s
Here is some code:
Code:
/* PROCESSAR AQUI! */
/*...*/
/* KEYFRAMES */
#-webkit-keyframes transitdescription {
15% { margin-left: 45px;}
}
#-webkit-keyframes transitimage {
0% { right: -100%;}
10% { right: -webkit-calc(93% - 350px);}
25% { right: -webkit-calc(90% - 350px);}
90% { right: -webkit-calc(90% - 350px);}
100% { right: -webkit-calc(200%);}
}
#-webkit-keyframes rotateimg {
50% {-webkit-transform: rotate(-10deg);}
}
#-webkit-keyframes pluswidth {
50% { width: 450px;}
}
#-webkit-keyframes leaveimage {
50% { width: 450px;}
}
Thanks.
There isn't such a property, although it has been suggested.
There are workarounds:
#-webkit-keyframes transitimage {
/* animation here */
10%, 100% { /* wait for 10 seconds without doing anything */ }
}
which is far from ideal.
You can see this related question for other workarounds.

Changing Background Image with CSS3 Animations

Why this isn't working? What am I doing wrong?
CSS
#-webkit-keyframes test {
0% {
background-image: url('frame-01.png');
}
20% {
background-image: url('frame-02.png');
}
40% {
background-image: url('frame-03.png');
}
60% {
background-image: url('frame-04.png');
}
80% {
background-image: url('frame-05.png');
}
100% {
background-image: url('frame-06.png');
}
}
div {
float: left;
width: 200px;
height: 200px;
-webkit-animation-name: test;
-webkit-animation-duration: 10s;
-webkit-animation-iteration-count: 2;
-webkit-animation-direction: alternate;
-webkit-animation-timing-function: linear;
}
DEMO
http://jsfiddle.net/hAGKv/
Updated for 2020: Yes, it can be done! Here's how.
Snippet demo:
#mydiv{ animation: changeBg 1s infinite; width:143px; height:100px; }
#keyframes changeBg{
0%,100% {background-image: url("https://i.stack.imgur.com/YdrqG.png");}
25% {background-image: url("https://i.stack.imgur.com/2wKWi.png");}
50% {background-image: url("https://i.stack.imgur.com/HobHO.png");}
75% {background-image: url("https://i.stack.imgur.com/3hiHO.png");}
}
<div id='mydiv'></div>
Background image [isn't a property that can be animated][1] - you can't tween the property.
Original Answer: (still a good alternative)
Instead, try laying out all the images on top of each other using position:absolute, then animate the opacity of all of them to 0 except the one you want repeatedly.
It works in Chrome 19.0.1084.41 beta!
So at some point in the future, keyframes could really be... frames!
You are living in the future ;)
Works for me.
Notice the use of background-image for transition.
#poster-img {
background-repeat: no-repeat;
background-position: center;
position: absolute;
overflow: hidden;
-webkit-transition: background-image 1s ease-in-out;
transition: background-image 1s ease-in-out;
}
This is really fast and dirty, but it gets the job done: jsFiddle
#img1, #img2, #img3, #img4 {
width:100%;
height:100%;
position:fixed;
z-index:-1;
animation-name: test;
animation-duration: 5s;
opacity:0;
}
#img2 {
animation-delay:5s;
-webkit-animation-delay:5s
}
#img3 {
animation-delay:10s;
-webkit-animation-delay:10s
}
#img4 {
animation-delay:15s;
-webkit-animation-delay:15s
}
#-webkit-keyframes test {
0% {
opacity: 0;
}
50% {
opacity: 1;
}
100% {
}
}
#keyframes test {
0% {
opacity: 0;
}
50% {
opacity: 1;
}
100% {
}
}
I'm working on something similar for my site using jQuery, but the transition is triggered when the user scrolls down the page - jsFiddle
I needed to do the same thing as you and landed on your question. I ended up taking finding about the steps function which I read about from here.
JSFiddle of my solution in action (Note it currently works in Firefox, I'll let you add the crossbrowser lines, trying to keep the solution clean of clutter)
First I created a sprite sheet that had two frames. Then I created the div and put that as the background, but my div is only the size of my sprite (100px).
<div id="cyclist"></div>
#cyclist {
animation: cyclist 1s infinite steps(2);
display: block;
width: 100px;
height: 100px;
background-image: url('../images/cyclist-test.png');
background-repeat: no-repeat;
background-position: top left;
}
The animation is set to have 2 steps and have the whole process take 1 second.
#keyframes cyclist {
0% {
background-position: 0 0;
}
100% {
background-position: 0 -202px; //this should be cleaned up, my sprite sheet is 202px by accident, it should be 200px
}
}
Thiago above mentioned the steps function but I thought I'd elaborate more on it. Pretty simple and awesome stuff.
Your code can work well with some adaptations :
div {
background-position: 50% 100%;
background-repeat: no-repeat;
background-size: contain;
animation: animateSectionBackground infinite 240s;
}
#keyframes animateSectionBackground {
00%, 11% { background-image: url(/assets/images/bg-1.jpg); }
12%, 24% { background-image: url(/assets/images/bg-2.jpg); }
25%, 36% { background-image: url(/assets/images/bg-3.jpg); }
37%, 49% { background-image: url(/assets/images/bg-4.jpg); }
50%, 61% { background-image: url(/assets/images/bg-5.jpg); }
62%, 74% { background-image: url(/assets/images/bg-6.jpg); }
75%, 86% { background-image: url(/assets/images/bg-7.jpg); }
87%, 99% { background-image: url(/assets/images/bg-8.jpg); }
}
Here is the explanation of the percentage to suit your situation:
First you need to calculate the "chunks". If you had 8 differents background, you need to do :
100% / 8 = 12.5% (to simplify you can let fall the decimals) => 12%
After that you obtain that :
#keyframes animateSectionBackground {
00% { background-image: url(/assets/images/bg-1.jpg); }
12% { background-image: url(/assets/images/bg-2.jpg); }
25% { background-image: url(/assets/images/bg-3.jpg); }
37% { background-image: url(/assets/images/bg-4.jpg); }
50% { background-image: url(/assets/images/bg-5.jpg); }
62% { background-image: url(/assets/images/bg-6.jpg); }
75% { background-image: url(/assets/images/bg-7.jpg); }
87% { background-image: url(/assets/images/bg-8.jpg); }
}
If you execute this code, you will see the transition will be permanantly. If you want the backgrounds stay fixed while a moment, you can do like this :
#keyframes animateSectionBackground {
00%, 11% { background-image: url(/assets/images/bg-1.jpg); }
12%, 24% { background-image: url(/assets/images/bg-2.jpg); }
25%, 36% { background-image: url(/assets/images/bg-3.jpg); }
37%, 49% { background-image: url(/assets/images/bg-4.jpg); }
50%, 61% { background-image: url(/assets/images/bg-5.jpg); }
62%, 74% { background-image: url(/assets/images/bg-6.jpg); }
75%, 86% { background-image: url(/assets/images/bg-7.jpg); }
87%, 99% { background-image: url(/assets/images/bg-8.jpg); }
}
That mean you want :
bg-1 stay fixed from 00% to 11%
bg-2 stay fixed from 12% to 24%
etc
By putting 11%, the transtion duration will be 1% (12% - 11% = 1%).
1% of 240s (total duration) => 2.4 seconds.
You can adapt according to your needs.
The linear timing function will animate the defined properties linearly. For the background-image it seems to have this fade/resize effect while changing the frames of you animation (not sure if it is standard behavior, I would go with #Chukie B's approach).
If you use the steps function, it will animate discretely. See the timing function documentation on MDN for more detail. For you case, do like this:
-webkit-animation-timing-function: steps(1,end);
animation-timing-function: steps(1,end);
See this jsFiddle.
I'm not sure if it is standard behavior either, but when you say that there will be only one step, it allows you to change the starting point in the #keyframes section. This way you can define each frame of you animation.
Like the above stated, you can't change the background images in the animation. I've found the best solution to be to put your images into one sprite sheet, and then animate by changing the background position, but if you're building for mobile, your sprite sheets are limited to less than 1900x1900 px.
I needed to do the same thing recently. Here's a simple implementation
#wrapper { width:100%; height:100%; position:relative; }
#wrapper img { position:absolute; top:0; left:0; width:100%; height:auto; display:block; }
#wrapper .top { animation:fadeOut 2s ease-in-out; animation-fill-mode:forwards; }
#keyframes fadeOut {
0% { opacity:1; }
100% { opacity:0; }
}
<div id="wrapper">
<img src="img1.jpg" class="top" style="z-index:2;">
<img src="img2.jpg" style="z-index:1;">
</div>
You can use animated background-position property and sprite image.
You can follow by this code:
#cd{
position: relative;
margin: 0 auto;
height: 281px;
width: 450px;
}
#cf img{
left: 0;
position: absolute;
-moz-transition: opacity 1s ease-in-out;
transition: opacity 1s ease-in-out;
}
#cf img.top:hover{
opacity: 0;
}
<div id="cf">
<img class="button" src="Birdman.jpg" />
<img src="Turtle.jpg" class="top" />
</div>
You can use the jquery-backstretch image which allows for animated slideshows as your background-images!
https://github.com/jquery-backstretch/jquery-backstretch
Scroll down to setup and all of the documentation is there.
Well I can change them in chrome. Its simple and works fine in Chrome using -webkit css properties.

Resources