Keyframes CSS Animation Issue Latest Chrome Browser - css

In the latest version of Chrome browser (Version 33.0.1750.1170), I have animations that have stopped working all of a sudden.
Site: http://multipurpose.joostrap.com/
There is an area for Testimonials that should transition in some div's.
i.e.
<div class="testimonial-box fadeInLeft animated">
I thought the issue might be #-webkit-keyframes in the CSS file, but it doesn't look to be this.
Is anyone else having this trouble with the latest Chrome browser or maybe have a fix?
EDIT:
I have changed the site to use the un-minifeid css version of the css. The relevant files are 'animations.css' and 'combined.css'. Hope this helps.

Simple answer
I think you are trying to get stuff to fade in from 0 opacity with a bit of a slide, no?
#keyframes fadeInLeft {
0% {
opacity: 0;
transform: translateX(-20px);
}
100% {
opacity: 1;
transform: translateX(0);
}
}
What you need to add is animation-fill-mode: forwards so that it sticks on the last frame of the animation.
You can see an example (webkit only) here on jsFiddle.
Explanation
When you run an animation in CSS, the browser will automatically return the element to the state it was in before the animation. This can be frustrating and not always intuitive.
So what you were seeing wasn't that the animation wasn't running (it was), but that by the time you scroll down it had finished animating and put it back to its original state (with opacity set to 0).
So you have two options:
You can remove the opacity from the CSS. Problem is that it might 'flash' before starting the animation. This wouldn't be a problem in your case since the content is below the fold to begin with. But it's bad practice because that might be an issue with future similar implementations.
The other is to leave the element as it appears in the last frame of its CSS animation. This is why I proposed animation-fill-mode: forwards. This does exactly that! I suppose this isn't the default because it might require more memory consumption but I haven't seen any evidence to prove it (not that I've looked for it).
As An Aside
Regardless, nobody will see your animation as it's below the fold. I suggest you detect how far the user has scrolled, and add that animation property once the user has reach the Testimonials. This way, it will only "fadeInLeft" when the user can see it!
You can use this code to do this: http://jsfiddle.net/R2YD9/2/ (Requires jQuery)

Related

CSS hardware accelerating triggering GPU crash

On the webapp I'm working on me and my team have some users who is experiencing browser crashes when they're using our app. They are then forced to restart the browser. The prolem occurs in all browsers on different OS's. We havent found any plugins in the browsers that could affect this issue. We have been tracking our own logs, windows logs etc. without any findings that could relate to the problem. We also watched the CPU- and Hardrive usage when we succeeded to trigger the problem ourself. But nothing was of the chart. This have made me and my team suspicious that it is GPU were having problem with.
We made some research and found out that animation, transition, opacity, transformation in CSS can trigger CSS crashes. But we don't have the knowledge nor experience to conclude that it's that who is the problem.
We are using hardware accelerating CSS like:
transform: translate3d(0,0,0) translateZ(0);
and some we're also using some CSS rotating keyframe animations:
#keyframes rotate {
0% {
-webkit-transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(359deg);
}
}
On some of the users who are experiencing the browser crashes we've implemented a feature switch. The feature switch removes all transitions, transforms and keyframe animations. They have been telling us that they think the feature switch was a improvement. But we can't tell if it's just placebo or if it really did help.
So before we remove a bunch of transtions and transforms from the app I thought it was worth checking out if there are anyone else experiencing the same problems. All thoughts and ideas are welcome.
It's worth mentioning that our webapp is a one-page-app using knockout.js
I've faced same kind of trouble which was crashing iOS - Safari browser. I wrote some note that time which is pasted in below -
Don't use all in transition property, only use which property you want to animate (avoid transition: all 400ms, try transition: color
400ms, background 400ms)
Use keyframe animation as much as you can
Decrease the size of document
Reduce request and optimize your images
Use translate3D, which will force iOS to use 3D acceleration and better memory allocation.
If you are still out of luck, remove all the transition for iOS and
animate using JS, i know it's expensive when you can't use library
like TweenMax but this is the only solution.
Note: JS animation may affect your animation frame-rate. Using rAF
(request frame animation) may enhance a bit.
*** CSS3 animations are very much in-need for website where animation amount is less and it does output ~60 FPS, but JS does vary based on
device.
Hope you found it useful. I would suggest you to stick with new feature what you've, just try fix it.
Best of luck.

Flickering back-face visibility when 'flipping' a box using back-face visibility

I'm using a reasonably simple CSS transition to create a box that 'flips around' by transitioning two divs 180deg at the same time. When you're on the 'back' of the box, it should be slightly transparent so you can see the underside.
I've got this working fairly easily in all browers, except the latest Safari 7 and on iOS 7. On Safari 7, the animation flickers and the back card just 'pops' to the front at the end of the animation.
This seems to be a bug in the rendering of the animation on newer Safari. Is there a workaround to get this to behave better?
Check out gifs of the animation on Chrome and Safari
See a demo here http://cssdeck.com/labs/flippable-card
Can not test on safari, but a similar bug happened time ago in Chrome.
The solution in that case would have been to move the back 1px in z
.card__back {
transform: rotateY(180deg) translateZ(1px);
backface-visibility: hidden;
}
.card--flipped .card__back {
transform: rotateY(0deg) translateZ(1px);
}
This happened in Chrome because while animating, the spatial order was calculated (I mean, the position of elements in 3d space), and it overrides other factors.
Once the animation is over, that calculation system is no longer used.
As I said before; cann't test in Safari, so I can be sure that this is a solution.
So I managed to replicate the behaviour in my current Safari and thought it was quite interesting.
Here's what I've come up with:
http://codepen.io/anon/pen/usGCL
Basically the backside is already turned around through a -webkit-transform: scaleX(-1); right from the start.
That way you don't have to rotate it back to 0deg.
Now instead of flipping front and back, You just flip the whole container by 180deg, leaving the backside appearing "normal" again. Also the z-index has to change in the process, which makes backface-visibility: hidden; redundant. I guess if modified a little you could use even less jQuery of course.
EDIT
Guess Aperçu's answer is also pretty much what you were looking for.
Just for fun though: http://codepen.io/BenMann/pen/DmjHv
And I agree the backface-visibility is definitely causing the problem.
As mentioned in the question, there are two things happening:
1. The animation flickers: this is due to the click delay in mobile browsers. Basically, a click event fires 300ms after physically tabbing the element. You'd want to listen for touchstart which fires immediately on tabbing, but doesn't fire at all on non-touch interfaces (Fastclick is a nice polyfill that removes this click delay in mobile browsers, but doesn't affect non-touch UIs.)
For the sake of this answer, I'm simply going to bind my listener to touchstart instead of click (therefore, the demo is to be viewed on a touch device):
$('.card').on("touchstart", function() {
$(this).toggleClass('card--flipped');
});
2. The back card just 'pops' to the front at the end of the animation: after some experimentation, it seems that this happens when transform and backface-visibility are both defined on the same element. To work around that, I've kept the backface-visibily on .card__back, but put the transform: rotateY(180deg) on .card__front.
Therefore, .card__front is going to be flipped initially, which means that .card has to be initially flipped as well to compensate for that.
We must also define transform-style: preserve-3d on .card in order for the transform to render .card__front and .card__back in 3D space (as opposed to being flattened).
/* Relevant CSS */
.card {
transition: all 1s ease-in-out;
transform-style: preserve-3d;
transform: rotateY(-180deg);
}
.card__front {
transform: scaleX(-1);
}
.card__back {
backface-visibility: hidden;
}
.card--flipped {
transform: rotateY(0);
}
Mobile DEMO (to be viewed in mobile Safari or Chrome): http://jsbin.com/aMAwezA/15/
DEMO (for non-touch devices): http://jsbin.com/aMAwezA/16/
EDIT:
After further testing, I found that transform: rotateY(180deg) on .card__front was causing some flickering in Chrome. Replacing it with transform: scaleX(-1) solved the issue. Updated the CSS and demo link above which should work on both mobile Safari and Chrome.
You need to add two transition time, one for the -webkit-backface-visibility and another for -webkit-transform.
If you try to set the transition delay at 0secs, you will see the color change immediatly like you want to.
Try to modify your transition rule like
transition: -webkit-transform 1s ease-in-out, -webkit-backface-visibility 0s ease-in-out;
Or to override the 1sec transition only for the backface-visibility.
EDIT
Without using -webkit-backface-visibility which seems buggy, I think I've got something work playing with the display of the backcard.
See Demo (Tested on Safari 7 iOs 7.0.2 and Mavericks)

CSS Filter on Retina Display: Fuzzy Images

When you apply a -webkit-filter and a -webkit-transition to an Image and change the filter on hover, the image transition does well, but then the image gets really fuzzy.
Note: This only happens on Retina-Displays — no problem at all with 'normal' ppi-displays, but fuzzy on for example a new MacBook Pro with Retina Display.
My CSS (without vendor-prefixes):
img {filter:grayscale(1);filter:saturate(0%);transition:2s ease;width:200px;height:200px}
img:hover {filter:grayscale(0)}​
Note: to see the effect/bug, I've set the transition-duration to 2 Seconds
Check out my Demo: http://jsfiddle.net/dya2t/7/
How can I fix this?
EDIT: If I set the :hover-state to filter:none its sharp! :-) BUT of course the transition does not work anymore :-/
As soon as there is a filter on an image (even if the value is 0 or 0%), the image gets fuzzy on retina displays (with or without transitions … its just blurry, all the time). I guess this is a Filter-Bug.
This is a known Bug in WebKit https://bugs.webkit.org/show_bug.cgi?id=93471
I managed to get around this issue by applying to the img tag:
-webkit-transform: translateZ(0);
http://jsfiddle.net/78qbn/3/
Child elements with -webkit-backface-visibility: hidden; will resolve this.
http://codepen.io/amboy00/pen/Bxbrd
Joined stackoverflow to let others know since I had to find this out myself:
this bug also manifests (but differently) when trying to print images in chrome. They turn super pixelated!
If you throw a -webkit-filter onto a PNG in chrome regardless of printer or print settings, it prints the image/s at the right size, but downsampled to under 70 dpi. It's visible in the print preview too.
-webkit-transform: translateZ(0); fixed it.
Meatspace repro: prints of same stack of PNGs with & without fix

iPad Safari scrolling causes HTML elements to disappear and reappear with a delay

I'm currently developing a web application using HTML5 and jQuery for iPad Safari. I'm running into a problem wherein large scroll areas cause the elements that are offscreen to appear after a delay when I scroll down to them.
What I mean by that is, if I have a row of images (or even a div with a gradient) that is offscreen, when I scroll down (or up) to it, the expected behavior is for the element to appear on screen as I am scrolling to it.
However, the element does not appear until I lift my finger off the screen and the scroller finishes all its animations.
This is causing a super noticeable problem for me, making the whole thing look choppy, although it is not. I'm guessing the iPad Safari is trying to do something to save memory. Is there a way in which I can prevent this choppy-ness from happening?
Additionally, what is iPad Safari actually trying to do?
You need to trick the browser to use hardware acceleration more effectively. You can do this with an empty three-dimensional transform:
-webkit-transform: translate3d(0, 0, 0)
Particularly, you'll need this on child elements that have a position:relative; declaration (or, just go all out and do it to all child elements).
It is not a guaranteed fix, but it is fairly successful most of the time.
Hat tip: iOS 5 Native Scrolling–Grins & Gotchas
I was using translate3d before. It produced unwanted results. Basically, it would chop off and not render elements that were offscreen, until I interacted with them. So, basically, in landscape orientation, half of my site that was offscreen was not being shown. This is a iPad web application, owing to which I was in a fix.
Applying translate3d to relatively positioned elements solved the problem for those elements, but other elements stopped rendering, once offscreen. The elements that I couldn't interact with (artwork) would never render again, unless I reloaded the page.
The complete solution:
*:not(html) {
-webkit-transform: translate3d(0, 0, 0);
}
Now, although this might not be the most "efficient" solution, it was the only one that works. Mobile Safari does not render the elements that are offscreen, or sometimes renders erratically, when using -webkit-overflow-scrolling: touch. Unless a translate3d is applied to all other elements that might go offscreen owing to that scroll, those elements will be chopped off after scrolling.
(This is the complete answer to my question. I had originally marked Colin Williams' answer as the correct answer, as it helped me get to the complete solution. A community member, #Slipp D. Thompson edited my question, after about 2.5 years of me having asked it, and told me I was abusing SO's Q & A format. He also told me to separately post this as the answer.
#Colin Williams, thank you! The answer and the article you linked out to gave me a lead to try something with CSS. So, thanks again, and hope this helps some other lost soul. This surely helped me big time!)
Targeting all elements but html: *:not(html)
caused problems on other elements in my case. It modified the stacking context, causing some z-index to break.
We should better try to target the right element and apply -webkit-transform: translate3d(0,0,0) to it only.
Sometimes the translate3D(0,0,0) doesn't work. We can use the following method, targeting the right element:
#keyframes redraw{
0% {opacity: 1;}
100% {opacity: .99;}
}
/* iOS redraw fix */
animation: redraw 1s linear infinite;
When the translate3d doesn't work, try to add perspective. It always works for me
transform: translate3d(0, 0, 0);
-webkit-transform: translate3d(0, 0, 0);
perspective: 1000;
-webkit-perspective: 1000;
Increase Your Site’s Performance with Hardware-Accelerated CSS
Adding -webkit-transform: translate3d(0,0,0) to an element statically doesn't work for me.
I apply this property dynamically. For example, when a page is scrolled, I set -webkit-transform: translate3d(0,0,0) on a element. Then after a short delay, I reset this property, that is, -webkit-transform: none
This approach seems to work.
Thank you, Colin Williams for pointing me in the right direction.
I had the same issue with iscroll 4.2.5 on iOS 7. The whole scroll element just disappear.
I've tried to add translate3d(0,0,0) as was suggested here. It has solved the problem, but it disabled the iscroll "snap" effect.
The solution came with giving the "position:relative; z-index:1000;display:block" CSS properties to the whole container that holds the scroll element and there isn't any need to give translate3d to child elements.
I had the same issue using an older version of Fancybox.
Upgrading to v3 will solve your problem or you can just add:
html, body {
-webkit-overflow-scrolling : touch !important;
overflow: auto !important;
height: 100% !important;
}
At time translate3d may not work. In those cases perspective can be used
transform: translate3d(0, 0, 0);
-webkit-transform: translate3d(0, 0, 0);
perspective: 1000;
-webkit-perspective: 1000;
I'm pretty darn sure I just solved this with:
overflow-y: auto;
(Presumably just overflow: auto; would work too depending on your needs.)
There are cases where a rotation is applied and/or a Z index is used.
Rotation: An existing declaration of -webkit-transform to rotate an element might not be enough to tackle the appearance problem as well (like -webkit-transform: rotate(-45deg)). In this case you can use -webkit-transform: translateZ(0px) rotateZ(-45deg) as a trick (mind the rotateZ).
Z index: Together with the rotation you might define a positive z-index property, like z-index: 42. The above steps described under "Rotation" were in my case enough to resolve the issue, even with the empty translateZ(0px). I suspect though that the Z index in this case may have caused the disappearing and reappearing in the first place. In any case the z-index: 42 property needs to be kept -- -webkit-transform: translateZ(42px) only is not enough.
This is a very common problem faced by developers and that is mainly due to Safari's property of not recreating elements defined as position : fixed.
So either change the position property or some hack needs to be applied as mentioned in other answers.
Issues with position fixed & scrolling on iOS
Change to position fixed on iOS Safari while scrolling
In my case (an iOS PhoneGap app), applying translate3d to relative child elements did not resolve the issue. My scrollable element didn't have a set height as it was absolutely positioned and I was defining the top and bottom positions.
Adding a min-height (of 100 pixels) fixed it for me.
I faced this problem in a Framework7 and Cordova project. I tried all the solutions above. They did not solve my problem.
In my case, I was using more than 10 CSS animations on the same page with infinite rotation (transform). I had to remove the animations. It is OK now with the lack of some visual features.
If the solutions in other answers do not help you, you may start eliminating some animations.
The -webkit-transform: translate3d(0, 0, 0); trick didn't work for me. In my case I had set a parent to:
/* Parent */
height: 100vh;
Changing that to
height: auto;
min-height: 100vh;
solved the issue in case someone else is facing the
same situation.
In my case, CSS did not fix the issue. I noticed the problem while using jQuery re-render a button.
$("#myButton").html("text")
Try this:
$("#myButton").html("<span>text</span>")

Considerations for CSS3 Transition Performance

As part of a project that needs to support mobile devices, I have been working on mimicking the iPhone toggle control using CSS3. I have the look and feel of the element pretty much there, and am using CSS3 transitions to animate its state change.
When I have the element itself on a page with nothing else, the transition is relatively smooth on iOS. However, when I combine it with other CSS elements on a page, the result in iOS is laggy as anything. It's slightly better than a raw jQuery animation, but not much.
I've set up two test pages to demonstrate what I mean (the difference is hardly noticeable in a regular browser):
Toggle Control on its own > http://ben-major.co.uk/labs/iPhone%20UI/ios_toggle.html
Combined with other elements > http://ben-major.co.uk/labs/iPhone%20UI/
I am looking for any advice on speeding up the transition in mobile devices. What could be the factors that are slowing down its performance on the full page test?
Any advice and comments welcome.
You have to be careful with this, as it can alter the z-index of the element it's applied to, but adding:
-webkit-transform-style: preserve-3d;
To the element you're applying the transition to, can speed animation up considerably, as it forces the hardware to use hardware acceleration for the animation.
If you do encounter layout bugs, you can just switch your 2d transitions to 3d values, so:
-webkit-transform: translate(100px, 100px)
becomes:
-webkit-transform: translate3d(100px, 100px, 0px)
You can see a demo of how this helps speed things up, at http://stickmanventures.com/labs/demo/spinning-gears-Chrome-preserve-3d/#
If after applying this to the element, you see it or elements around it blink upon use, then use:
-webkit-backface-visibility: hidden;
To the element, and that should correct the problem.
These tips have helped me to produce fast, efficient CSS transitions, hope they help. :)
Chrome has recently improved the 2D transition performance, and now this trick is no longer needed. The best thing is that if removed the translate3d you'll no longer have those z-index problems! Use the test to prove. http://stickmanventures.com/labs/demo/spinning-gears-Chrome-preserve-3d/
also you can try will-change: transform; , read more about it here:
https://developer.mozilla.org/en-US/docs/Web/CSS/will-change#Browser_compatibility
I think it quite old already but for anyone who still needs tricks to improve the transition performance on mobile device, you can apply :
-webkit-transform: translateZ(0);
to the element you are animating.
This trick is according to this blog : http://chrissilich.com/blog/fix-css-animation-slow-or-choppy-in-mobile-browsers/.
I have tried and it works quite well.

Resources