The title basically gives it away. I have an animation working just fine in Chrome (80) and Firefox (57), but does not work in Safari (12) at all.
What I expect to happen is a straight line is drawn across the screen diagonally, from left top to right bottom.
I've tried a dozen variations of my code, the following is one:
(all the variations I tried work perfectly fine in Chrome and Firefox)
#move {
top:0;
left:0;
width: 0;
height: 5px;
background: rgb(255, 255, 255);
position: absolute;
-webkit-animation-name: mymove;
-webkit-animation-duration: 3s;
-webkit-animation-timing-function: linear;
-webkit-animation-fill-mode: forwards;
-webkit-transform: rotate(var(--a));
-webkit-transform-origin: top left;
-webkit-animation-delay: 1s;
-moz-animation-name: mymove;
-moz-animation-duration: 3s;
-moz-animation-timing-function: linear;
-moz-animation-fill-mode: forwards;
-moz-transform: rotate(var(--a));
-moz-transform-origin: top left;
-moz-animation-delay: 1s;
-ms-animation-name: mymove;
-ms-animation-duration: 3s;
-ms-animation-timing-function: linear;
-ms-animation-fill-mode: forwards;
-ms-transform: rotate(var(--a));
-ms-transform-origin: top left;
-ms-animation-delay: 1s;
-o-animation-name: mymove;
-o-animation-duration: 3s;
-o-animation-timing-function: linear;
-o-animation-fill-mode: forwards;
-o-transform: rotate(var(--a));
-o-transform-origin: top left;
-o-animation-delay: 1s;
animation-name: mymove;
animation-duration: 3s;
animation-timing-function: linear;
animation-fill-mode: forwards;
transform: rotate(var(--a));
transform-origin: top left;
animation-delay: 1s;
}
#-webkit-keyframes mymove {
to {
width: var(--w);
/*background-color: rgb(67, 67, 92);*/
}
}
#-moz-keyframes mymove {
to {
width: var(--w);
/*background-color: rgb(67, 67, 92);*/
}
}
#-ms-keyframes mymove {
to {
width: var(--w);
/*background-color: rgb(67, 67, 92);*/
}
}
#-o-keyframes mymove {
to {
width: var(--w);
/*background-color: rgb(67, 67, 92);*/
}
}
#keyframes mymove {
to {
width: var(--w);
/*background-color: rgb(67, 67, 92);*/
}
}
a shorter one:
#move {
top:0;
left:0;
width: 0;
height: 5px;
background: rgb(255, 255, 255);
position: absolute;
animation: mymove 3s;
animation-fill-mode: forwards;
transform-origin: top left;
transform: rotate(var(--a));
}
#keyframes mymove {
to {
width: var(--w);
}
}
The HTML:
<div id="move"></div>
I tried to consider:
webkit:
Why is my CSS3 animation not working in Chrome or Safari?
CSS3 animation: Not loading in Safari
Transform: rotate doesn't work in Safari
Splitting up the shorthand notation:
CSS3 animation not working in safari
Delaying the animation:
CSS3 animation not working in safari
None of what I tried seem to work in Safari. What am I missing here? Any help would be very much appreciated!
I had a very similar issue. Like the OP, I was setting up the keyframe using the 'to' property:
#keyframes dash {
to {
dash-offset: 0;
}
}
This seems to be fine with Chrome and Firefox. I discovered that Safari and iOS Safari require the 'from' property to be set as well. This is contrary to MDN's claim that 'If a keyframe rule doesn't specify the start or end states of the animation (that is, 0%/from and 100%/to), browsers will use the element's existing styles for the start/end states.'
I was animating a dynamic element, so I ended up using the Web Animations API to describe an animation that all browsers could understand:
const lineAnimationTiming: EffectTiming = {
duration: 1000,
easing: 'ease-in-out'
};
const length = line.getTotalLength();
line.style.strokeDasharray = `${length} ${length}`;
line.animate(
[
{ strokeDashoffset: length },
{ strokeDashoffset: 0 }
],
lineAnimationTiming
);
EDIT Sep 3, 2021:
Testing Safari using vanilla HTML/Javascript/CSS, this issue does not reproduce. See this Stackblitz.
I happened to be using Angular when I first encountered the issue. This issue does reproduce there. See this Stackblitz. Reported to Angular as this bug.
Related
This question already has answers here:
How to have multiple CSS transitions on an element?
(9 answers)
Play multiple CSS animations at the same time
(6 answers)
Closed 1 year ago.
I'd like to apologise upfront for my code and question. I'm a graphic designer but have been editing some html for online digital banners.
Currently I have a colored bar slide in from the left to the right after 2 secs.
This works well using 'animation-name:barAnim'
Then I want that same bar to fade out after 7.5 secs.
However once I add 'animation-name:fadeOut' the bar breaks and only flashes at the 7.5 second mark.
All of this needs to work automatically without any user input.
Please see current code below.
Any help would be really really appreciated.
.col_bar1 {
left: 0px;
top: 412px;
width: 132px;
height: 11px;
background: #5d7773;
opacity: 0;
}
.col_bar1 {
animation-name: barAnim;
-webkit-animation-name: barAnim;
animation-duration: 0.5s;
-webkit-animation-duration: 0.5s;
animation-timing-function: ease-out;
-webkit-animation-timing-function: ease-out;
animation-delay: 2s;
-webkit-animation-delay: 2s;
animation-fill-mode: forwards;
-webkit-animation-fill-mode: forwards;
}
.col_bar {
animation-name: fadeOut;
-webkit-animation-name: fadeOut;
animation-duration: 0.2s;
-webkit-animation-duration: 0.2s;
animation-timing-function: ease-in-out;
-webkit-animation-timing-function: ease-in-out;
animation-delay: 7.5s;
-webkit-animation-delay: 7.5s;
animation-fill-mode: forwards;
-webkit-animation-fill-mode: forwards;
}
#keyframes barAnim {
0% {
-webkit-transform: translate3d(-130px, 0, 0);
transform: translate3d(-130px, 0, 0);
opacity: 1;
}
100% {
opacity: 1;
-webkit-transform: translate3d(18px, 0, 0);
transform: translate3d(18px, 0, 0);
}
}
#-webkit-keyframes barAnim {
0% {
-webkit-transform: translate3d(-130px, 0, 0);
transform: translate3d(-130px, 0, 0);
opacity: 1;
}
100% {
opacity: 1;
-webkit-transform: translate3d(18px, 0, 0);
transform: translate3d(18px, 0, 0);
/*--start from lhs--*/
}
}
#keyframes fadeOut {
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}
#-webkit-keyframes fadeOut {
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}
<div class="col_bar1"></div>
You can do comma separated animations. I have used the animation shorthand here and split it to multiple lines for readability.
CSS
animation:
barAnim 0.5s ease-out 2s forwards,
fadeOut 0.2s ease-in-out 7.5s forwards;
-webkit-animation:
barAnim 0.5s ease-out 2s forwards,
fadeOut 0.2s ease-in-out 7.5s forwards;
I have two images and I've found css ::after keeps one image on top of the other quite nicely, even when the screen size changes. The thing is I want the image underneath to spin and the image on top to remain stationary. I can't seem to do this and I'm not even sure this is possible using ::after. Is there a way to do it?
Here's my code:
.box {
display: inline-block;
position: fixed;
top: 50%;
left: 30%;
-webkit-animation-name: spinnerRotate;
-webkit-animation-duration: 5s;
-webkit-animation-iteration-count: infinite;
-webkit-animation-timing-function: linear;
-moz-animation-name: spinnerRotate;
-moz-animation-duration: 5s;
-moz-animation-iteration-count: infinite;
-moz-animation-timing-function: linear;
-ms-animation-name: spinnerRotate;
-ms-animation-duration: 5s;
-ms-animation-iteration-count: infinite;
-ms-animation-timing-function: linear;
}
.box:after {
content: '';
position: absolute;
width: 50px;
height: 50px;
top: 25px;
right: 0;
bottom: 0;
left: 25px;
background: url("../Content/images/top.png");
}
<div class="box">
<img src="../Content/images/bottom.png">
</div>
Here's the animation:
#-webkit-keyframes spinnerRotate
{
from{-webkit-transform:rotate(0deg);}
to{-webkit-transform:rotate(720deg);}
}
#-moz-keyframes spinnerRotate
{
from{-moz-transform:rotate(0deg);}
to{-moz-transform:rotate(720deg);}
}
#-ms-keyframes spinnerRotate
{
from{-ms-transform:rotate(0deg);}
to{-ms-transform:rotate(720deg);}
}
Well, you can do it like this:
#keyframes rotate {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.box::after {
animation: rotate 5s infinite;
content:url("http://lorempixel.com/sports/400/200/");
}
<div class="box">
<img src="http://lorempixel.com/g/400/200/">
</div>
I changed your background-image with using the content property. This is not necessary but more comfortable, as you don't need to give the image dimensions.
Here is a nice article about css animations: https://css-tricks.com/almanac/properties/a/animation/
Here is information about compatibility: http://caniuse.com/#search=animation
Is it possible to give an element multiple animations with different durations using CSS3 animations?
What I want to have eventually is have the ball to keep rotating after finishing. I know I could do this with giving multiple classes. But I would like to avoid that to prevent messy amount of classes.
(the Fiddle might not work on other browsers than Chrome, I just rapidly hacked it together)
Fiddle example of what I have currently http://jsfiddle.net/cchsh6om/2/
Here's the CSS
div {
margin: 20px;
width: 100px;
height: 100px;
border-radius: 46px;
position: relative;
background: #ddd;
-webkit-animation-name: spin;
-webkit-animation-duration: 1000ms;
-webkit-animation-iteration-count: 1;
-webkit-animation-timing-function: ease-out;
-moz-animation-name: spin;
-moz-animation-duration: 1000ms;
-moz-animation-iteration-count: 1;
-moz-animation-timing-function: ease-out;
-ms-animation-name: spin;
-ms-animation-duration: 4000ms;
-ms-animation-iteration-count: 1;
-ms-animation-timing-function: ease-out;
animation-name: spin;
animation-duration: 1000ms;
animation-iteration-count: infinite;
animation-timing-function: linear;
}
span{
position: absolute;
line-height: 100px;
left:48%;
}
#-ms-keyframes spin {
from {
opacity: 0;
margin-left: 200px;
-ms-transform: rotate(0deg); }
to {
opacity: 1;
margin-left: 20px;
-ms-transform: rotate(-360deg); }
}
#-moz-keyframes spin {
from {
opacity: 0;
margin-left: 200px;
-moz-transform: rotate(0deg);
}
to {
opacity: 1;
margin-left: 20px; -moz-transform: rotate(-360deg); }
}
#-webkit-keyframes spin {
from {
opacity: 0;
margin-left: 200px;
-webkit-transform: rotate(0deg); }
to {
opacity: 1;
margin-left: 20px;
-webkit-transform: rotate(-360deg); }
}
#keyframes spin {
from {
opacity: 0;
margin-left: 200px;
transform:rotate(0deg);
}
to {
opacity: 1;
margin-left: 20px;
transform:rotate(-360deg);
}
}
And the HTML
<div><span>=</span></div>
Yes, it's possibly, but your syntax is wrong. First of all, use short notation like animation: horizontal linear 8s infinite (for more information read this acticle). Then you you can apply multiple animations separated by comma on the same element:
animation: horizontal linear 8s infinite,
vertical ease-in-out 1.3s infinite alternate,
blink linear .7s infinite alternate,
rotation linear .4s infinite;
and define keyframes for each one of them:
#keyframes horizontal {
from {left: 0;}
to {left: 100%;}
}
#keyframes vertical {
from {top: 0;}
to {top: 200px;}
}
Finally, you can omit to -moz and -ms prefixes. -webkit-animation and animation works on all the modern browsers including mobile.
See my sample of multiple animation at CodePen, i've tested it on many platforms.
the code below works fine on Chrome, but not on Safari:
#-webkit-keyframes jiggle {
0% {
transform: rotate(-.5deg);
-webkit-animation-timing-function: ease-in;
}
50% {
transform: rotate(1deg);
-webkit-animation-timing-function: ease-out;
}
}
.animated_container {
-webkit-animation-name: jiggle1;
-webkit-animation-iteration-count: infinite;
-webkit-transform-origin: 50% 40%;
-webkit-animation-duration: 0.21s;
-webkit-animation-delay: -0.43s;
animation-name: jiggle1;
animation-iteration-count: infinite;
transform-origin: 50% 40%;
}
I created an example in this fiddle:
http://jsfiddle.net/2obx0rvL/
What am I missing here ? Thx!
It's because you're not setting the full range on the transform percentage. Safari requires that you specify the 100% endpoint. See this related answer: CSS3 animation not working in safari
You only use the webkit.prefix. You have to write the code again without the webkit prefix, so that other browsers like Safari, Internet Explorer or Firefox can use it.
#-webkit-keyframes jiggle {
0% {
transform: rotate(-.5deg);
-webkit-animation-timing-function: ease-in; animation-timing-function: ease-in;
}
50% {
transform: rotate(1deg);
-webkit-animation-timing-function: ease-out; animation-timing-function: ease-out;
}
}
.animated_container {
-webkit-animation-name: jiggle1;
-webkit-animation-iteration-count: infinite;
-webkit-transform-origin: 50% 40%;
-webkit-animation-duration: 0.21s;
-webkit-animation-delay: -0.43s;
animation-name: jiggle1;
animation-iteration-count: infinite;
transform-origin: 50% 40%;
animation-duration: 0.21s;
animation-delay: -0.43s;
}
I would like to spin my div when I hover on it and as it spin I want to make it bigger like zoom in.
So far I have this:
[html]
div class="myMsg">
<p id="welly" style="color: #009">Welcome to Y3!<br><br><br>Thanks for stopping by!</p>
</div>
[css]
.myMsg {
background: white;
width: 800px;
height : 500px;
margin: 100px auto;
border: 1px solid black;
opactiy: 0.5;
-webkit-transform: rotate(360deg); /* Safari and Chrome */
-webkit-transform: scale(.1,.1) skew(45deg) translateX(-300px);
box-shadow: 0px 0px 200px grey;
}
.myMsg:hover {
opacity: 1;
-webkit-transform: rotate(360deg); /* Safari and Chrome */
-webkit-transform: scale(1,.1 skew(0deg);
box-shadow: 0px 0px 200px grey;
}
so I want it to spin before scaling to regular size
Any help is appreciated
First, to show that it can be done.
Now that that's out of the way, let's get down to the nitty gritty and show you how to do it.
First, you'll want to use animation to animate the properties and get the rotation effect. Sadly, a transition won't be enough since transitioning between 0 and 360 means you aren't going anywhere. So, animate your properties from one to the other on the hover. Your code will end up looking something like this:
#keyframes spin {
from { transform: scale(.1,.1) skew(0deg) rotate(0deg); }
to { transform: scale(1,1) skew(0deg) rotate(360deg); }
}
.myMsg:hover {
animation: spin 1s forwards;
}
The #keyframes defines the animation that will happen, and you want to transform from one set of properties to the final one. Then, you set your :hover to play that animation. The relevant properties for the animation are animation-name, animation-duration, and animation-fill-mode (which say that it should have the same properties as the last frame when it is done animating. Webkit requires prefixes, so you'll want to put those in too.
In addition to this, I also placed a transition: transform 1s; on the .myMsg class so that it would animate back after the mouse moves away. But do note that Webkit doesn't seem to play nice with the interaction between the two, so it is a bit choppy and less than ideal. But, with experimental properties like this, sometimes you get what you get.
Some side notes:
Your CSS isn't cross browser compatible, you should clean it up a bit
You're defining 1 transform property, and then immediately overriding it. All transforms need to go in the same declaration. They can't be combined like that
Define an infinite css animation with keyframes for spinning and switch to it on the hover. Use transition for the size (height/width) properties and change them on hover in css also.
Example: http://jsfiddle.net/6guCd/
div {
margin: 100px;
width: 100px;
height: 100px;
background: #f00;
-webkit-transition: all 200ms ease;
-moz-transition: all 200ms ease;
-ms-transition: all 200ms ease;
transition: all 200ms ease;
}
div:hover {
margin: 50px;
width: 200px;
height: 200px;
-webkit-animation-name: spin;
-webkit-animation-duration: 4000ms;
-webkit-animation-iteration-count: infinite;
-webkit-animation-timing-function: linear;
-moz-animation-name: spin;
-moz-animation-duration: 4000ms;
-moz-animation-iteration-count: infinite;
-moz-animation-timing-function: linear;
-ms-animation-name: spin;
-ms-animation-duration: 4000ms;
-ms-animation-iteration-count: infinite;
-ms-animation-timing-function: linear;
animation-name: spin;
animation-duration: 4000ms;
animation-iteration-count: infinite;
animation-timing-function: linear;
}
#-ms-keyframes spin {
from { -ms-transform: rotate(0deg); }
to { -ms-transform: rotate(360deg); }
}
#-moz-keyframes spin {
from { -moz-transform: rotate(0deg); }
to { -moz-transform: rotate(360deg); }
}
#-webkit-keyframes spin {
from { -webkit-transform: rotate(0deg); }
to { -webkit-transform: rotate(360deg); }
}
#keyframes spin {
from {
transform:rotate(0deg);
}
to {
transform:rotate(360deg);
}
}