Smooth CSS3 ticker jQuery plugin

This post was originally made on the Assanka blog. Assanka was acquired by the Financial Times in January 2012, and became what is now FT Labs. Learn more.

I’ve recently been building a status display for the Assanka office, which shows us information like current Zabbix monitoring triggers, support requests from clients, Pingdom status alerts, and even naming and shaming Assankans who’ve failed to file their time-sheets on time.

In the process, I was pointed at the gorgeous Panic status board. Our objectives were similar and I was attracted to the idea of adding the scrolling tickers (at least, we assume they are scrolling from Panic’s photograph), which run along the bottom of their board. I was reminded of the kind of tickers you get on 24 hour news channels (here’s one from BBC World):

BBC World screen capture showing scrolling ticker

Tickers in web browsers are difficult for a number of reasons. First, continuously animating the left or margin-left properties of an element in JavaScript is computationally expensive, particularly if you want to reposition the element often enough to create a properly smooth animation. Sites that use Javascript for tickers in this manner tend to hog your computer’s CPU and feel slow and laggy as a result. Many sites give up on the traditional ticker and go for something that’s easier for the browser to animate, like a ‘type in’ reveal (eg the BBC News homepage ticker), or a vertical ‘scroll up’ ticker.

BBC News online ticker

Another issue with continuous tickers is making them loop properly. When your animation reaches the end of the text, you have to scroll it all the way off the left edge of the screen before it can be repositioned and re-enter the frame from the right. This leaves an ugly gap in your ticker.

Finally, if your ticker is updating with new information in real time, making changes that are noticeable in the visible portion of the ticker is amateur hour stuff.  You rarely see TV tickers suddenly change mid-scroll, and yet stories are seamlessly added and removed as necessary, outside of the visible frame.

Since Panic didn’t release any code (boo), I set out to produce a jQuery plugin that would enable news tickers to be easily added to a page, using CSS3 animation effects.  If it’s working for you, you should see a couple of tickers scrolling away right here:

If it’s not working, you’re probably not using a browser that supports CSS3 transitions.  Try it in Chrome, or Safari.  Support should be added to Firefox pretty soon.  But the objective here is not to get universal compatibility, since I can easily dictate which browser our status board will use.

With CSS3 transitions, we substantially improve the performance issue of tickers.  And this will improve further with browsers implementing these effects at an increasingly lower level.  This leaves the looping and updating issues to resolve before we can claim a properly news-grade ticker.

Looping

There are two possible solutions to the looping problem.  The first is to target segments of the ticker just after they have left the frame on the left, and move them to the end of the ticker on the right.  The second is to make several copies of your ticker content, and when you get to the end of the second copy, reposition the entire ticker element so that the first copy lines up with where the second copy had got to, then scroll on into the second copy again and repeat.

I chose the second approach, because you need several copies of the ticker anyway if it’s too short to fill the width of the frame with enough left over to sort the looping out.

Updates

In order to enable the ticker to be updated dynamically, and yet not suffer any noticeable changes in the visible portion, I added some public methods – addMessage() and removeMessage(), which allow you to pass a list element and have it queued for addition or removal at an appropriate moment.

This does require breaking a rather holy tenet of jQuery, namely returning a reference to the ticker rather than returning the jQuery chain, so you have an object on which you can call the public methods.

Every time the ticker hits the end of the text, it is repositioned with the penultimate copy in view, all copies of the ticker text are updated to match the copy to their right, and the final copy (the original set of elements) is updated with the queued additions and removals (out of view).   As a result, when you call the add or remove methods, you may have to wait some time before you see the effect, but the ticker will never judder or change while it is visible to the user.

How to use

Your ticker must be a block element containing a UL. This is because the ticker needs a frame to mask the content as it slides through.

<div id='ticker1'>
  <ul>
    <li>Headline one</li>
    <li>Headline two</li>
  </ul>
</div>
<script type="text/javascript">
  var ticker = $('#ticker1').ticker();
  var newid = ticker.addMsg('Headline three');
  setTimeout(function() {
    ticker.removeMsg(newid);
  }, 60000);
</script>

Settings and methods

The following settings are available, which can be passed to the ticker() function in a standard json object:

  • pxpersec: Speed of the ticker in pixels per second (optional; default is 30)

Calls to the ticker() function return a reference to the ticker, not the jQuery chain. The ticker reference exposes the following methods:

  • string addMsg(msg): Add a new message to the ticker. Can be a jQuery object or raw list item element (which will be moved from its current location in the DOM), or a plain text string. Returns a string identifier for the message (to enable you to remove it later). If you pass an element that already has an ID attribute, that ID is used (and returned).
  • void removeMsg(msg): Remove a message from the ticker. Can be a jQuery object or raw list item element (which must be in the ticker already), or a string identifier returned from the addMsg call that added the message to the ticker. Returns nothing.

Get the code