In this tutorial we’ll be looking at how we can transform some semantic and accessible underlying HTML into an attractive and functional news ticker that smoothly scrolls its contents. Some news tickers are horizontal and some are vertical; the one that we’re going to create today will be vertical.
The context of the example is a news scroller so we’ll be working with plain text, but we should be able to put whatever we wanted into the underlying mark-up; images, or links, or whatever. We’ll be using jQuery as the underlying JS library, and a little HTML and CSS. Let’s make a start.
The Underlying HTML
In a new page in your text editor add the following code:
Simple News Ticker
- This is a news title!
- This is a snippet of the news. It could be the whole news item or it could link to another page containing...
- News Heading 2
- Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
- News Heading 3
- Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
- News Heading 4
- Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
- This item is long!
- Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Save this as simpleTicker.html in a directory containing jQuery 1.3.2. As well as the usual page furniture - the DOCTYPE, META content-type, title, etc - we have a custom style sheet that we’ll create in just a moment and we link to jQuery at the end of the body (for performance reasons).
On the page is the content that we’ll progressively enhance into the news ticker; it’s made up of a simple definition-list element, which feels appropriate for our purposes. Although only inline content can be placed in each <dt> element, block-level content can be put in the <dd> elements.
The code is minimal and highly accessible; browsers, mobile devices and screen-readers should all have no difficulty interpreting and rendering it. With no styling however, it does look pretty shocking:
Providing Default Styling
Let’s add some basic styling; even with JavaScript switched off, no one wants to see the list as it is at the moment. In a new file in your text editor add the following code:
#ticker {
width:180px; height:300px; overflow:auto; border:1px solid #aaaaaa;
}
#ticker dt {
font:normal 14px Georgia; padding:0 10px 5px 10px;
background-color:#e5e5e5; padding-top:10px; border:1px solid #ffffff;
border-bottom:none; border-right:none;
}
#ticker dd {
margin-left:0; font:normal 11px Verdana; padding:0 10px 10px 10px;
border-bottom:1px solid #aaaaaa; background-color:#e5e5e5;
border-left:1px solid #ffffff;
}
#ticker dd.last { border-bottom:1px solid #ffffff;
Save this file in the same directory as the page and call it simpleTicker.css. We give the list a set width and height and set the overflow property to auto; the height of the ticker is less than the space required to show all of the news items so the scrollbar will allow visitors with JavaScript disabled to view all of the content.
Some of the styles are purely presentational; anything that sets a background-color, border or font is totally arbitrary and is used to make the example a little more attractive. The widget should now look like this:
However minimal we choose to make it, it’s a big improvement on the default rendering; it would quite happily fit into a sidebar or column now; it’s an acceptable fallback from the finished widget and a great foundation from which to progressively enhance.
Progressively Enhancing the Ticker
Now we can move on to the fun part – adding the JavaScript that will turn this from a simple list into an automatic ticker; in the empty <script> element at the bottom of the page add the following code:
$(function() {
//cache the ticker
var ticker = $("#ticker");
//wrap dt:dd pairs in divs
ticker.children().filter("dt").each(function() {
var dt = $(this),
container = $("");
dt.next().appendTo(container);
dt.prependTo(container);
container.appendTo(ticker);
});
//hide the scrollbar
ticker.css("overflow", "hidden");
//animator function
function animator(currentItem) {
//work out new anim duration
var distance = currentItem.height(),
duration = (distance - Math.abs(parseInt(currentItem.css("marginTop")))) / 0.025;
//animate the first child of the ticker
currentItem.animate({ marginTop: -distance }, duration, "linear", function() {
//move current item to the bottom currentItem.appendTo(currentItem.parent()).css("marginTop", 0);
//recurse
animator(currentItem.parent().children(":first"));
});
};
//start the ticker
animator(ticker.children(":first"));
});
All of our code is encased within the jQuery document.ready short-cut $(function(){ }) which will execute the anonymous function as soon as the page has loaded. The first thing we do is to cache our main selector, which is the outer <dl> element; this will save us from having to repeatedly select the element from the DOM whenever we want to work with it and improves the performance of the page.
The underlying definition list contains both definition term and definition description elements, all of which could potentially be of varying sizes. To make things a little easier in our script we next wrap each <dt> and <dd> pair in a containing <div> element; this allows us to group the different elements logically and smooth out the animations. It also means that we can use whatever margins and padding on the *lt;dt> and
elements without needing to take these into consideration in our animation calculations.
To do this we select all of the children from our cached selector and use the jQuery filter method to discard all of the <dd> elements. Then for each remaining <dt> we create a new container <div> and append both the <dt> and the <dd> to the new container. We have to add the <dd> that follows the current <dt> first, because once the <dt> has been appended to the container it won’t have a <dd> after it. We therefore need to use the prepend method on the <dt> once the <dd> has been appended.
Once all of the <dt> and <dd> pairs have been wrapped in <div> elements we then change the ticker’s overflow CSS property to hidden so that the scrollbar is removed. This is part of the accessibility strategy and ensures that only visitors with JavaScript enabled get to see the enhanced ticker.
Next we define our animator function, which is where we’ll set the animation which causes the ticker to begin scrolling and then keep scrolling indefinitely. This is a regular JavaScript function which accepts a single parameter; when we call this function we’ll pass in the first container element within the ticker.
The first thing we do within this function is work out the distance that the selected element has to travel and the duration of the animation. The distance part is easy; it’s just the height of the current container element.
The duration is a little more complex; it’s the total distance to travel minus the distance already traveled, divided by a baseline speed that I’ve arbitrarily set at 0.025. The height will already be an integer but the css method will return a string representing the margin-top of the element being animated so we need to use JavaScript’s parseInt() function to convert it to a number. It will also be a negative number so we use the Math.abs() JavaScript function to convert it from a negative to an absolute (positive) number.
The baseline speed that we divide the remaining distance to travel by is pretty slow in my opinion; I’ve seen tickers before (built with Java) and they’ve been approximately the same speed and I didn’t get motion sickness or suffer any ill effects. If you feel that the animation is too fast (or even too slow) feel free to change this figure. It needs to be a really small number though; anything in the range of 0.01 to 0.09 is probably going to be ok.
Once we have these figures we can then create the animation using jQuery’s animate method. The first parameter for this method is the actual animation itself; we want the first of the container elements in the ticker to be moved upwards until it is completely hidden in the overflow, but we also want to drag the rest of the container elements up by the same distance as well so we use adjust the marginTop of the element.
The second argument of the animate method is the duration which we worked out a moment ago. The third argument is the easing method; custom jQuery animations automatically get two types of easing – swing and linear. Swing causes the animation to speed up and slow down, while linear makes it sooth and continuous, so this is the option for us in this situation.
The final argument is an anonymous callback function that will be executed when the animation ends. Within this function we move the element that has just been animated to the end of the set of containers, reset its marginTop back to 0, and then recursively call the animator function again, passing in the new first-child of the ticker.
Finally, we need to call the animator function once to start off the whole process. When we view this page in a browser, the ticker should smoothly scroll through each of the elements in the list repeatedly:
Starting and Stopping
Now we need to think about what we want to happen when a visitor mouses-over a news item; personally I think the default behavior should be that it pauses on mouse-over and then restarts again on mouse out. We can easily add this behavior with a couple of jQuery event handlers; add the following code just before the final brace/curly brace combo:
//set mouseenter
ticker.mouseenter(function() {
//stop current animation
ticker.children().stop();
});
//set mouseleave
ticker.mouseleave(function() {
//resume animation
animator(ticker.children(":first"));
});
Both of these functions are really simple; we use mouseenter and mouseleave instead of mouseover and mouseout because it makes these functions nice and small; we don’t need to worry about ignoring mouseouts when the pointer moves from the outer ticker element to one of the child elements. In the mouseenter function we simply stop the animation. In the mouseleave function we just restart the animation once more, passing in the first-child of the ticker.
Fixing IE
We have one problem left to solve, and fortunately it’s an easy one. Running the page as it is in IE (tested in version 8) throws an error as soon as it is loaded. The error is caused because the very first time the animator function runs the first container <div> will have its margin-top set to auto by the browser. Other browsers will interpret the margin-top as 0. Which browser is correct is debatable, although I’ll let you draw your own conclusion about the fact that IE is the only browser that causes the problem. All we need to do to fix it is explicitly set the margin-top of the container elements. We can do this by adding the following line of code to the style sheet:
#ticker div { margin-top:0; }
Now the page should work in IE as well:
Summary
This now brings us to the end of the tutorial, we should now have a simple but effective news ticker that can be put to use in a variety of ways. When using text, like in this example, defining the headings and associated content sections within a definition list makes sense from a semantics perspective, and it’s easy to add any additional elements we may need as we go.
- Follow us on Twitter, or subscribe to the Nettuts+ RSS Feed for more daily web development tuts and articles.
Related Posts
Check out some more great tutorials and articles that you might like
Plus Members
Source Files, Bonus Tutorials and
More for $9 a month for all TUTS+
sites in one subscription.












User Comments
( ADD YOURS )Kevin August 19th
Amazing
( )John August 19th
That’s great! I’d really like to implement this into Wordpress. I think it wuld make a great replacement area for my community feed section.
( )readymixx August 19th
Cool-I’m going to try it out now-what if the user wants to scroll back up to look at a news item that scrolled by already?
( )Dan Wellman August 22nd
they need to wait unfortunately
I can look at extending it to add draggability maybe
( )Stefan August 30th
Please do!
Merijn August 19th
Nice article! Like to see more of these tutorials with quality. Especially since you think about page performance and storing certain DOM elements ini variables to make the page load faster. Most tutorials here don`t really pay attention to this, so it`s nice to see people take time to do this.
Anyway, thanks for sharing!
With kind regards,
( )Merijn
Fynn August 19th
Seems like a nice article but I really don’t like how the next news heading kicks in (after seeing the white background)..
Is this your intention or is it just my browser (FF3) giving me hell
( )Shaun August 19th
Think it might be your browser. I just went back and previewed the demo again in FF3 and see nothing wrong.
( )Shaun August 19th
Great tut. I’ve been using jQuery for a long while and I actually learned a new technique from this.
( )Dan Wellman August 19th
thanks for reading, glad it’s helped/been useful
( )G deep August 19th
Solved my purpose buddy
( )DMorello August 19th
When I use this in IE7 I can see all of the text that is above and below the 300px container.
( )Kartik August 19th
What happened to the PHP/JS competition nettuts ? the results were supposed to be in 3 days ago !
( )Moksha Solutions August 19th
thanks was looking for something like this,
( )David Moreen August 19th
Your sure right when you say simple, I liked the tutorial for the most part. Defiantly for someone who would not know any javascript. However i’d prefer more complicated things.
( )Dan Wellman August 19th
I figured the animation stuff, calculating the speed etc, was a step up from just basic animation
( )Aaron August 19th
Um…I just got a flash back from the early 90s when scrolling text was popular…I’m not a big fan of this and will never be. This is a horrible user experience. You can’t control anything with the the ticker…and the only way to pause is by mouseovering the ticker.
PEOPLE, if you call yourself a web designer you will not use this…especially for news headlines.
( )Mujtaba August 19th
I dont see anything wrong in using this???
( )This is just a basic example, u can add more functionality to it like stop/start buttons etc easily…
Dan Wellman August 20th
Yes, it would be exceptionally easy to add some buttons that also controlled starting/stopping the text, and it doesn’t have to be text, it could be images or anything really.
Can I just point out that the BBC news website (arguably the biggest news site in the UK) has a scolling news ticker right at the top of its home page.
At the end of the day, people that call themselves web designers will use what their clients want them to use (within reason); we had a client a couple of months ago that wanted a news ticker, so one was duly designed and added to their site.
Also, the article is kind of a case study for the animations, stopping and starting with consistent times etc…
( )Michael Irwin August 19th
Great idea! I can use this on a few sites I’m working on!
Thanks!
( )Mario World August 19th
Cool
( )MoHaMmEd ZaHrAn August 20th
This is really pretty news ticker, i guess i will use it soon
( )thanks for this post.
Arnold August 20th
nice tuts again…
( )really love this jquery tuts …
keep it up! ^L^
Rata August 20th
Hey Dan,
just what I was looking for and just in time
Thank you!
Kind regards
( )Rata
Dmitry August 20th
Nice tut!!!!!!!!!!!!!!!!!!!!!!
( )Raymond August 20th
Very nice example. I think I’ll try to create a reusable plugin for Raxan: http:://raxanpdi.com
( )dreake August 21st
There is something wrong in you script. Check this.
( )philips August 21st
cool marquee animation…
thank you Dan, that is very useful.
( )Hjortur Scheving August 24th
is it just me or does this not work in IE7}
( )Ifect August 27th
Figured out a fix for IE7….
In the CSS code for the ticker styling, remove the “position:relative; ” property from the #ticker dt div & the #ticker dd div respectively..like so:
#ticker dt {
font:normal 14px Georgia;
padding:0 10px 5px 10px;
background-color:#e5e5e5;
padding-top:10px;
border:1px solid #ffffff;
border-bottom:none;
border-right:none;
}
#ticker dd {
margin-left:0;
font:normal 11px Verdana;
padding:0 10px 10px 10px;
border-bottom:1px solid #aaaaaa;
background-color:#e5e5e5;
border-left:1px solid #ffffff;
}
There you go, it should work properlyin IE7 now…
( )Hjörtur Scheving August 28th
Great thanks, this works now.
Houston Graham September 14th
That worked for me as well. Thanks.
Miami Mike October 28th
Thanks for posting your fix! It saved me a lot of heart ache. Extra geek points for you!
john briggs August 25th
great tut how would u implement it to pull information from another URL instead of static text set in the html code
( )SuiG August 27th
Doesnt work properly on IE 7 for me either…
( )danny August 27th
Looks pretty easy
. Now I Just need to put it together with WordPress
( )josue August 29th
cool
( )Sam August 30th
Hi Dan,
Quick question, I was playing around with this … but it doesn’t seem to work on Firefox 3.0.13 . The issue I am having is all the News titles come first and then the news. I narrowed it down to the missing … but no matter where I put it, it stops the animation. Any suggestions?
Thanks!
( )Jenn August 31st
Can I use two separate instances of scrolling text on the same page? I tried it and the second one does not scroll.
( )Daniel September 3rd
Pretty cool
( )Aleko September 6th
it’s great but it dose not works in IE 6
( )aleko September 6th
it does not works also in IE 7 why i saw your advace for Hjortur Scheving
( )but anyway it dose not works i think if do samething you shoul do it as a unique
Merrick Christensen September 7th
Not sure if someone has mentioned this but in your demo code the one that makes it wrap. “currentItem.appendTo” needs a line break in the code displayed on this post. As of right now it is being commented out. Took me a bit to figure out how you were making it just go and go and go. Pretty simple but cool idea. Anyways thanks. Again sorry if you were already aware of this.
( )Wayne September 7th
Ausome
( )Chris September 10th
How do you make it delay at the start before it starts moving? that would be really great thank YOU
( )mtsandeep September 21st
Thanks, it is very useful.
How can i reverse the direction of the movement, i need it to be from top to bottom ??
And also i am having problems in alignment with ie6.
( )ATREAU September 23rd
THIS DOES NOT WORK IN IE6. PLEASE AMEND.
( )Bodillo September 23rd
I get the message “out of memory at line so and so…, what am I doing wrong?
( )Johnny September 23rd
THIS DOES NOT WORK IN IE7. Please Help.
( )Bodillo September 25th
I found out why it stopped, it was because I had not put the aroud the whole and part of the HTML.
And for it to start over again and go and go there is some of the javascript code that is marked as a comment and this is not active.
( )Make a linebreak before the part of the comment where it says currentItem.appendTo.
Bodillo September 25th
some of my comment did not show, I ment to say that I had not put the div tags aroud the whole part with the dt and dd area, and thats why it stopped
( )David October 6th
Hey how can i add a Username to each post?
( )will October 8th
I’m having trouble getting this to work with Lightbox. Any ideas?
( )Phillip Swindall October 10th
Is there any way to pull that information from an RSS feed and include it in the scrolling information???
( )Websurfeur October 13th
Hello,
I have some problème with validator.w3.org :
Line 272, column 26: document type does not allow element “div” here
container = $(”");
Have you a solution? (my english is bad , I’m french, sorry !)
( )Lokesh October 20th
Great tutorial…
The “height” property is not supported by IE6. When i am trying to reduce the height of the ticker DIV, it is not getting reduced in IE6.
( )Jonathan October 27th
Hi,
Is it possible to scroll up and down?
( )