This is a chrome only question. I'm using chrome 56 on OSX, but I also tested this on Windows 8 using chrome 57.
I have an animation that is gpu accelerated, using will-change: transform and a keyframe animation using transform: translateY(...) to move an element around the screen.
.block {
height: 20vh;
width: 20vh;
background-color: black;
animation: move 5s linear infinite;
will-change: transform;
}
#keyframes move {
0% { transform: translateY(0%); }
50% { transform: translateY(400%); }
100% { transform: translateY(0%); }
}
Example on codepen: http://codepen.io/nicokoenig/full/PmYaOZ/
The animation itself is handled on the chromes compositor thread and is therefor not affected if the main thread is blocked.
When I record a timeline, I still see that there is a style calculation for each frame.
Why does chrome need to recalculate styles, even if the animation is handled on the compositor thread?
UPDATE
I reviewed my code and added three types of animations.
the first animtion is using a fixed viewport unit (vh) to translate the box.
the second animation is using a fixed pixel value to translate the box.
the third animation is using a percentage value to translate the box.
I also added button to block the main thread - if I hit the button:
the first and second animation will still move around the screen, the third one freezes.
I think that is the answer - an animatoin using translate with percentage values needs to recalculate styles during the whole animation.
The behavior is a known chrome bug.
https://bugs.chromium.org/p/chromium/issues/detail?id=711645
https://bugs.chromium.org/p/chromium/issues/detail?id=389359
Related
Bit of background: ArtStation's pro subscription gives 3D Artists their own website and allows manual customization of the default themes by injecting CSS rules.
I've (successfully) redesigned my website with CSS in 2 days but I have a problem on the homepage.
Please see the homepage at https://viggopaulman.artstation.com.
It has an image slider with an opacity transition between images. The ArtStation menu settings give me an option to set switching time of images: Screenshot 1. Current switch time is set to 3 seconds from this menu.
I have added a zoom-out keyframe animation effect to these slides:
/* Sliders Transition and Zoom Override */
.slide {
transition: opacity 5s;
}
.showing {
animation-fill-mode: forwards;
animation: slide 3s linear 1;
}
#keyframes slide {
0% {
transform: scale(1.125,1.125);
}
100% {
transform: scale(1,1);
}
My problem is the slides zoom out, stop and wait for the next one to transition in. (There is a very short "snap" at the last frames too if you look carefully.) I'd like to make the transition to the next image start before the zoom reaches 100%. Or to force the image to keep zooming in while the next image transitions in and replaces it. I'm basically trying to achieve an optical effect where the slides are in a constant cinematic zoom-out motion without abrupt stops or breaks in the flow.
From what I understand I have to tweak the 3 second menu switch, the animation: slide 3s and the transition: opacity 5s?
Is there a way to achieve this? Thank you.
I'm experiencing a weird phenomenon using Microsoft Edge (40.15063.674.0) / Microsoft EdgeHTML (15.15063) with the code below. As expected, when you hover over the black box with any browser, it smoothly scales the box to 1.25x its size over 0.5 seconds. The problem happens when a mouse is moving too fast across the box in Edge. What happens is that instead of scaling smoothly, the box jumps/snaps to the desired transformation and then back again. Let’s say a user was moving their mouse fast from one side of the screen to the other and “cutting across the lawn” so to speak across the surface of the box.
In fact, if I move too fast in other browsers, the box doesn't attempt to scale at all. It just stays small unless the mouse movement actually ends up stopping in that area. Even in Internet Explorer this works just fine with as fast as I can move the mouse pointer across it, but only in Edge do I find this behavior. I have to go relatively slow to prevent that jitter-like snap. It doesn't matter what the effect is either. It could be a "scale", a "translateY", etc. If the mouse is moving too fast across the ":hover" it's not smooth in Edge. Is this a known issue? Is there anything I could do to prevent this from happening?
<!DOCTYPE html>
<style>
.box {
background-color: #000;
cursor: pointer;
position: absolute;
left: 200px;
top: 200px;
height: 200px;
width: 200px;
transition: transform 0.5s;
transition-delay: 0.1s; <=== Added this to stop it from jumping
}
.box:hover {
transform: scale(1.25);
}
</style>
<div class="box"></div>
I've even tried replicating the effect using jQuery's ".hover" function to add the CSS attributes when the mouse enters and then take them away when the mouse leaves but to no avail. It behaves exactly the same way. The hover effect jumps/snaps if the mouse is moving too fast in Edge.
This should be a comment, but sub-50 rep here.
You might want to try adding translateZ() or use scale3d() directly, to enable hardware acceleration, and using transition-delay to delay the transition altogether when hovering for less than 100ms.
.box:hover {
transform: scale3d(1.25, 1.25, 1.25);
transition-delay: 0.1s;
}
/* or */
.box:hover {
transform: translateZ(0) scale(1.25);
transition-delay: 0.1s;
}
Having issues making this behave properly on Safari (works fine on Chrome and Firefox): https://jsfiddle.net/my794fyx/4/
In the fiddle, the redbox should move from left to right with a shifting pivot-point. The red box is moved by animating the left property. The pivot-point is shifted by animating translateX().
The importance of having a shifted pivot point comes to play when hovering over the black box: the width of the redbox grows. The direction the red box grows in is determined by the pivot-point -- when the redbox is on the left, it should grow to the right, and when it's on the right, it should grow to the left. This can be seen working properly on Chrome and Firefox.
On Safari, when you hover over the black box and the red box grows in width, it doesn't seem to be taken into account by transform: translateX(-100%). When hovered, the red box exceeds the black box.
Looking for some work-arounds to the browser issue or alternative implementations to the problem.
You might want to try using the -webkit- prefix on the transform and the #keyframes so:
#-webkit-keyframes {
0% {
left: 0%;
-webkit-transform: translateX(0%);
transform: translateX(0%);
}
100% {
left: 100%;
-webkit-transform: translateX(-100%);
transform: translateX(-100%);
}
}
But just remember that the original must be kept as well! And that you have to add -webkit- prefixes to that for safety, in case one does not support #keyframes without the prefix but not the transform, though it's more likely the other way around, as the above code has.
Also see: here
I am trying to delay a CSS transition, but it seems not to be working. Here is what I want to happen:
Start the video
Move the mouse pointer out of the video
The control bar shrinks, but the play-progress gets larger.
Move mouse pointer back in video, the control bar returns to normal.
As you can see in the CodePen pen, the play-progress bar gets larger before I want it to: http://codepen.io/mboles/pen/mJeJOO
Here is the CSS I am currently using:
#myPlayerID.vjs-has-started.vjs-user-inactive .vjs-progress-control {
-webkit-transform: translateY(-25px);
}
#myPlayerID.vjs-has-started.vjs-user-inactive .vjs-play-progress {
-transition-delay: height 3s;
height: 10px;
}
I have tried to change the order of the transition delay and height, but that did not solve the issue.
Many thanks-
Matt
It turns out with transition-delay you cannot put the property with the delay, it must be explicitly stated using transition-property. So the solution is:
#myPlayerID.vjs-has-started.vjs-user-inactive .vjs-play-progress {
height: 10px;
transition-property: height;
-transition-delay: 3s;
-webkit-transition-delay: 3s;
}
I have a very odd problem that I only observe with Safari, on a touchpad.
When scrolling down, my navbar fades in / down via CSS transition. If I happen to scroll back up, thus removing the class responsible for the transition, the navbar gets stuck visually in the wrong place, only on safari. The CSS / styles say the correct values, and even the hover/click handlers are in the right place.
That is, In the image below, my mouse is hovering at the blank white area, while the navbar stuck below gets highlighted.
There are several odd things about this:
The element is the navbar via global styles, yet only happens on this particular page.
I can't seem to trigger the problem via scrolling with the mouse.
I can only trigger it via very subtle trackpad movements, or fast trackpad movements.
Any suggestions on how to fix this?
Relevant CSS
.is-sticky-slide-down {
#include experimental(animation, fadeInDown .3s ease-out 0s);
}
#-webkit-keyframes fadeInDown {
0% {
opacity: 0;
-webkit-transform: translateY(-20px);
transform: translateY(-20px);
}
100% {
opacity: 1;
-webkit-transform: translateY(0);
transform: translateY(0);
}
}
The problem was due to enabling -webkit-backface-visibility: hidden on elements. Removing this "fix" for hover glitches (like twitching opacity fades) fixed the other glitches on Safari.
To be clear, the fix is to remove -webkit-backface-visibility from affected elements.