Blog (my web musings)

Find out what's interesting me, get tips, advice, and code gems that don't fit elsewhere.


Search Blog


While I've been rolling out my Sweep-in News Scroller with Controls on a school website (cutting out jQuery for performance gains), I was handed an older Android device that didn't display it. In place of the news scroller was... well, nothing at all! zilch! Just empty nothingness with no sign of what should be there. I was perplexed and annoyed. What was going on?!

Identifying the problem

Day-to-day I use newer Android devices for general testing, which have Chrome installed as the default browser, and the scroller works fine there. This old device (an Asus tablet) used a different default browser altogether - the old Android stock browser, also known as ASOP. I did some quick settings checks and discovered that the tablet was in fact running the KitKat version of the Android operating system, and couldn't upgrade any higher than 4.4.2 (it came with a much older version when originally purchased). The Android stock browser was phased out in new devices purchased with KitKat 4.4+ as a base install, but evidently, it is still in use by those with older devices, who haven't learned about the benefits of the Chrome app. The user didn't want to install Chrome, or any other browser, and why should they? It's their device and I, as a (usually) conscientious web developer, should accommodate them.

While I kicked myself over being so thoughtless, and while I pondered over what was causing the news scroller to vanish in that particular browser, I decided to check how many web-users still use it. Turns out its still quite a significant number - the market share for Android browser in July 2016 is 8.55%.

I thought it best to work on finding a fix.

Finding a solution

I noted that while the scroller didn't kick in to life automatically when the page first loaded, the individual entries did reveal themselves when the next and previous control buttons were tapped. I surmised that the problem must be linked to CSS animations.

What perplexed me most was that I've had access to this old Asus tablet in the past and my previous animated scripts have worked properly. Why would CSS animations work in this browser in some circumstances and not others? I had already checked if I could use them and Android browser 4+ supports CSS animations with the -webkit- prefix. Even 2.1+ and 3 supported them partially, but with buggy behaviour. Surely that should mean my news scroller would work this time too?

Frustration mounted. I dug around for a while longer and landed on the "Dispelling the Android CSS animation myths" article by Dan Eden. I found my answer in this sentence here;

CSS animations are supported by Android devices - but only if a single property is changed. As soon as you try to animate more than one property at once, the entire element disappears.

The penny dropped. My previous CSS keyframe animations (the ones that worked) were simpler, whereas my latest one looked like this;

@-webkit-keyframes sweepUp { 
    0% { opacity:0; -webkit-transform:translate3d(0,100%,0) }
    15% { opacity:1; -webkit-transform:none }
    80% { opacity:1; -webkit-transform:none }
    100% { opacity:0; -webkit-transform:translate3d(0,-200%,0) }
    }

I had 2 properties animating; opacity and position.

I followed the advice in the article and broke my properties down in to animations of their own (well, I already had the fadeIn animation further down the stylesheet so I just stripped out the opacity definitions from the sweepUp, sweepLeft and sweepDown animations);

@-webkit-keyframes sweepUp { 
    0% { transform:translate3d(0,100%,0) }
    15% { transform:none }
    80% { transform:none }
    100% { transform:translate3d(0,-200%,0) }
    }
@-webkit-keyframes fadeIn {
    0% { opacity:0 }
    20% { opacity:1 }
    80% { opacity:1 }
    100% { opacity:0 }
    }

I also chained my animations together using comma-separated declarations;

.newsscroller .sweep-up { z-index:1; -webkit-animation:sweepUp 5s both, fadeIn 5s both; animation:sweepUp 5s both, fadeIn 5s both }

Then I tested again, but bizarrely, it still didn't fix the problem... and I fully expected it to!

The final piece of the puzzle

I felt like I was banging my head against a brick wall, but I persevered. I tried a few more things, such as using wrapper elements and applying one animation to the wrapper and one to the element (didn't help), but then I hit on something purely by chance. During my copying and pasting, and general fudging about with the CSS, I happened to place the block of @-webkit-keyframes animations underneath the un-prefixed @keyframes animations... and lo and behold, the blasted thing worked!

So through trial and error, and a bit of chance, I finally got the news scroller working in the Android stock browser!

Sweep-in News Scroller with Controls (+ Android support):

Demo

And while I was at it, I updated the earlier version that doesn't have controls.

Simple Sweep-in News Scroller (+ Android support):

Demo

Summary

To summarise, the takeaway tips for getting CSS3 Animations to work in the older Android stock browser are;

  1. Separate multiple properties out into their own keyframe animations
  2. Comma-separate the animation declarations
  3. Put the @-webkit-keyframes animations last, after unprefixed @keyframes animations

Maybe they'll help another frustrated sole if they land on this blog :)