Why does the following clipPath animate in Chrome but not Firefox?
http://jsfiddle.net/H8S3k/67/
.graph {
transform: translateY(150px);
animation: 2s ease-out 0s normal none infinite popup;
}
#keyframes popup {
0% {
transform: translateY(50px);
}
50% {
transform: translateY(0px);
}
100% {
transform: translateY(50px);
}
}
In SVG 1.1, only certain attributes were deemed to be stylable with CSS. These particular set of attributes were called "properties". You can see the list of designated properties here:
https://www.w3.org/TR/SVG/propidx.html
transform is not one of those, so it cannot be styled with CSS.
However in SVG 2, which is not yet finalised, all SVG attributes will probably be made stylable. Chrome has begun implementing this, however Firefox has not yet. That is why your example works in Chrome but not Firefox.
Related
I made a little CSS animation with a simple svg to transition my hamburger menu to a cross. It works as expected on Chrome and Firefox, but the translation is off in Safari. The animation plays, and even resets correctly so it has nothing to do with prefixes (I tried). The translate of the two lines making the cross is just wrong.
I'm guessing it has something to do with how safari handles the transform when scaling is also applied. Does anyone know if there is a work around / or what I'm doing wrong?
JSFiddle
Safari / Firefox / Chrome
#keyframes showCross {
0% {
transform: scale(1) rotate(0);
}
40% {
transform: scale(0.3) rotate(280deg);
}
100% {
transform: scale(1) rotate(360deg);
}
}
#keyframes showCross_P1 {
0% {
transform: rotate(0);
}
100% {
transform: rotate(-45deg) translate(-42%, -10%);
}
}
I fixed it by doing the following:
First I removed the groups surrounding the paths.
Then I gave all the paths the following values:
transform-origin:center center;
transform-box: fill-box;
Next I edited the animation keyframes to look as follows:
0% {
transform: translate(0rem,0rem) rotate(0);
}
100% {
transform: translate(-10rem,-38rem) rotate(-45deg) ;
}
Safari has problems with percents and also if you put the rotation before the translate it has inconsistency with other browsers, use rem instead!
On loading state I have a #keyframes animation running.
#keyframes graph-line-loading {
0% {
transform: translateY(0%);
}
100% {
transform: translateY(100%);
}
}
When I stop the animation graph__line jumps to translateY() value (set inline).
However the background-color does nicely animate.
I would expect transition property working on transform as well.
.graph__line {
transition-property: transform, background-color;
}
If the background-color is included in #keyframes animation it doesn't get transitioned on state change either.
Seems like whatever property is animated in #keyframes gets ignored by transition property even though #keyframes is added via different class.
Plz check the fiddle.
https://jsfiddle.net/LukaG/m4bzk6e3/
Any ideas?
Question: Why does my CPU register ~30% when blur is applied versus ~6% when no blur is applied to an animated object?
Details:
I have a set of randomly generated items on a page that have a CSS animation assigned (in a CSS file) and randomly generated values for width, height, and importantly, blur, applied inline.
CSS file styles looks like:
animation-name: rise;
animation-fill-mode: forwards;
animation-timing-function: linear;
animation-iteration-count: 1;
-webkit-backface-visibility: hidden;
-webkit-perspective: 1000;
-webkit-transform: translate3d(0,0,0);
transform: translateZ(0);
width, height and blur are applied inline via style attribute.
<div class="foo" style="width:99px;height:99px;
filter:blur(2px);
-webkit-filter:blur(2px) opacity(0.918866247870028);
-moz-filter:blur(2px) opacity(0.918866247870028);
-o-filter:blur(2px) opacity(0.918866247870028);
-ms-filter:blur(2px) opacity(0.918866247870028);"></div>
With the blur enabled my CPU usage is ~30%. When I disable the blur, CPU usage goes down to ~6%.
What's happening here? Is chrome only able to GPU accelerate when no blur is applied? If so, why?
Update 1:
The animation rise looks as follows:
#keyframes rise {
0% {
transform: translateY(0px);
}
100% {
transform: translateY(-1000px);
}
}
I don’t think the blur is actually causing your issues, it just seems to make it more noticeable than before. The problem is that the transform: translateY in your animation is overwriting the transform: translateZ(0) you’re using to force GPU acceleration.
This is a timeline recording for the the code you’re running right now, notice how there’s all this activity on the main and raster threads:
Now compare this to a recording where I applied will-change: transform to the .foo:
No activity on the main and raster whatsoever.
There’s two steps to applying this fix:
Apply will-change: transform to .foo. This will let the browser know you intend to change that property and have it render that element on the GPU to account for this.
No versions of Edge and IE support will-change at the moment. Therefore we’ll use transform: translate3d(0, -1000px, 0); in the animation to force GPU acceleration. Note this is a hack, so we’ll detect support for will-change and use transform: translateY in browsers that support it.
Final code:
#keyframes rise {
0% {
transform: translate3d(0, 0, 0);
}
100% {
transform: translate3d(0, 1000px, 0);
}
}
#supports (will-change: transform) {
#keyframes rise {
0% {
transform: translateY(0px);
}
100% {
transform: translateY(1000px);
}
}
}
div {
width: 100px;
height: 100px;
background: #f00;
animation: rise forwards 2s linear infinite;
will-change: transform;
}
See here for a working version: http://jsbin.com/mosuvikoto/edit?html,css,output
Don't blur it in inline styles. Put your blur in the style file.
The rotate animation won't work with translate. I get, that I have to put translate in the same property with the rotate, but how is this possible when using keyframes? Code is like so:
#-webkit-keyframes rotating {
from{
-webkit-transform: rotate(0deg);
}
to{
-webkit-transform: rotate(360deg);
}
}
#keyframes rotating {
from{
transform: rotate(0deg);
}
to{
transform: rotate(360deg);
}
}
img{
-webkit-transform:translate(-50%,-50%);
transform:translate(-50%,-50%);
-webkit-animation: rotating 2s linear infinite;
animation: rotating 2s linear infinite;
position:absolute;
top:50%;
left:50%;
}
This will make the rotation, but it disables the translate. If I put the translate into the rotating animation, the translate is being animated as well(ofcourse).
The 2022+ answer
You can work around this by using individual property transforms which have pretty good browser support.
In short, use the properties like scale, translate, etc. instead of transform.
Side note: You don't need browser-specific properties for anything related to transforms or animations these days.
The original 2014 answer
The issue is that the transform in the animation is overriding the default transform:translate. In this case, you can combine them in the animation itself but it has to be hard coded.
#keyframes rotating {
from {
transform: translate(-50%,-50%) rotate(0deg);
}
to {
transform: translate(-50%,-50%) rotate(360deg);
}
}
If you need it to be dynamic, you can nest it in an element and animate one while not affecting the other - most likely translate the parent and rotate the child.
If you absolutely cannot have more than one element, you can affect the transform matrix for the element using JavaScript, in which case using an animation library like GSAP would be advantageous.
I'm trying to apply an animation to a group within an SVG element. However, I'm finding that it isn't applied or is being overridden, as it's crossed out in Chrome Developer Tools. That said, I have no idea what could be causing it.
Animation code:
.ghost {
animation: float 3s ease infinite;
}
#keyframes float {
50% {
transform: translate(100px, 100px);
}
}
I'd post the HTML (the problem might be there) but it's incredibly verbose because of all the SVG paths. Link to a Codepen instead: ghost
Thank you so much! I have no idea what could be causing the issue at this point.
You're missing your vendor prefixes. Example:
.ghost {
-webkit-animation: float 3s ease infinite;
}
#-webkit-keyframes float {
50% {
-webkit-transform: translate(100px, 100px);
}
}
For an easy fix, try adding Prefix-free in CodePen's CSS editor. Here it is with Prefix-free enabled:
Codepen