The Silky Smooth Marquee

As we abused the Internet back in the 90 with tags like <blink> and <marquee> the last 10 years have seen the gradual extinction of these proprietary tags until we did full circle and the marquee effect appears in CSS 3.

There’s actually a very strong business case and requirement for the marquee tag – since the only the alternative is often a hacky solution (I feel) that shifts the CSS left position which, depending on your browser, will begin to eat away at your CPU.

Funnily enough, the marquee tag is pretty well supported amongst the browser, but the actual effect is poorly executed natively (which is kind of odd if it’s built directly in to the browser). So let’s solve this with JavaScript.

Demo

This demonstration shows 3 jQuerified marquees and 3 standard marquees. You can see how the untouched marquees are jumpy to animate, even in the later browsers such as Firefox 3 and Safari – let alone IE6.

Demonstration of jQuery Marquee

Download

Download jQuery marquee plugin

Usage

Include the latest jQuery and the plugin file via the script tag, then:

$('marquee').marquee(optionalClass);

Note that the enhanced marquee doesn’t particularly have to apply to a marquee tag – but it is reading the effect details from the tag – currently it will default to behaviour = scroll, dir = left, speed = 2. There’s no (current) option for setting an overall default – but I’ll add this if people feel it’s required.

How it Works

There’s a few solutions available that create a similar effect, but this plugin does two things differently:

  1. Progressively enhances the marquee tag making this plugin uber easy to use.
  2. The effect is not achieved using CSS. It’s created using the overflow scroll on the element, which massively reduces the work the browser has to do – i.e. there’s no re-rendering due to changes in CSS, it’s scrolling using native functions of the browser.

It’s worth noting that behind the scenes, the marquee tag is being lifted out of the DOM and replaced with divs. However, when it’s chains in jQuery, it returns the new enhanced marquee div, so you can still hook click events, or navigate the DOM element if you wish – i.e. business as usual.

However, be warned – as we are lifting the marquee‘s contents in to a new div, it means and predefined events or data will be lost. To avoid this, make sure the marquee plugin is called before hand.

Events

The following events can be bound to:

  • stop – triggers when a loop is completed
  • start – triggers when a loop is started
  • end – completely finishes the loops if set

The follow events can be triggered by the user:

  • pause/stop (both do the same thing)
  • unpause/start (both do the same thing)

Support

I’ve written the marquee to run on a single timer function rather than one per marquee, the idea being that you could go crazy and add lots of marquees, and this code should scale.

Also, the marquee doesn’t currently support direction="up" or direction="down"…yet. Come back later and I’ll upgrade if there’s any interest.

The marquee plugin now supports all directions.

† I’ve not tested it with more than 3 marquees yet – feel free to test and give feedback

Other Uses

I’ve played around with the implementation of the marquee and I’ve been able to easily create the effect of the user clicking and dragging the marquee back and forth – which is very smooth (note that before I start the drag effect, I need to trigger a stop event):

$('div.demo marquee').marquee('pointer').mouseover(function () {
  $(this).trigger('stop');
}).mouseout(function () {
  $(this).trigger('start');
}).mousemove(function (event) {
  if ($(this).data('drag') == true) {
    this.scrollLeft = $(this).data('scrollX') + ($(this).data('x') - event.clientX);
  }
}).mousedown(function (event) {
  $(this).data('drag', true).data('x', event.clientX).data('scrollX', this.scrollLeft);
}).mouseup(function () {
  $(this).data('drag', false);
});

180 Responses to “The Silky Smooth Marquee”

  1. Dear people,

    I am building a site with quite a few animations the main one being the way I load the pages, I am using AJAX to load the new page in to a new DIV and then either fade in/out or slide in/out, the only time I am loading a page the regular way is when the site is being loaded for the first time.

    I am using the ‘marquee’ script in the home page and my problem is that then entering the home page the for first time (the regular way) the marquee works fine, when entering the home page after that (using the AJAX technique) the marquee script does not work (the marquee work as if the script was not loaded). I was able to partially solve the problem by moving the marquee call function from the root of the code in to the AJAX file it self, by partially I mean it works fine in all browsers except for (you guessed right ! ) Explorer!

    Any thoughts?

    Thanks in advance,

    Ury.

  2. It works, but only one thing, I would like to know if it is possible to emulate a cilindric scroll efect, for example, I have ten paragraphs scrolling vertically in a div with the height for only 5 of them, so I would like that after scrolling the 10th, the first paragraph appear as if it were the 11th, without waiting the full markup to end to begin again. I hope you understand, my english is not very good :O thank you anyway, great plugin.

  3. Thanks for a great plugin.

    How come that when i’m running the marquee it start with “height: 18px;” after some time it changes to “height: 54px;” ?

  4. Hi,
    thanks for useful plugin. A question: I need to stop animation marquee if user click on a object, is it possible? how?

    I tried with “stop()”, “end()”,… without success!

    Thank you, Fabio

  5. I am trying to use this with a rss feed not using the marque tag, with only the div, where do I set the speed behavior and direction?
    I dont use marque tag due to validation errors.

    This is what I tried does not work proparly:

    $(function () {
    $(‘div.wrapper’).marquee(
    behaviour = “scroll”, // What other behavior is there?
    dir = “down”, // What other direction is there?
    speed = “4″ // What is the speed defined by?
    );
    });

  6. Hi, I have downloaded the script and the jQuery script. The only issue I have is I’m not sure where to put this piece of code: $(‘marquee’).marquee(optionalClass);

    I tried putting underneath the JavaScript but it didn’t seem to work? Any help would be appreciated.

  7. Hi, first of all thanks for the great script, really makes the marquee smoother!

    However, I’m having a problem that I hope you can help me with. I am using a marquee to scroll quotes up. If the text is longer than the marquee width, instead of dropping to new lines, it overruns the marquee and becomes invisible. Please let me know how to fix this.

    Thanks,
    Tom

  8. Hi, i do have a problem. It seem the pointer couldnt recognize the drag = true when dragging. Right after i release the click, the pointer follow my mousemove. It’ll be better to add a ‘return false’ in the mousedown event, in order for the js to execute the mousemove event. It’ll make the code smoother.

  9. Hi, Thanks, for the plugin!

    I’m using it on this site www-dot-northtorontocatrescue-dot-com.

    It’s working great on: IE, FF, Safari, and mostly on Chrome, minus one little quirk:

    When I click the browser’s back button to go to a page (any page), the box containing the marquee grows to hold the entire content of the marquee, which is not the intended behavior.

    Any thoughts?

  10. Emma, check the source for http://www.sffac.org. Look for the “div.scroll” stuff in “style”, and the “Our Supporters” section in the body.

    I was in the same boat as you, but got this to work. I did modify the jquery.marquee.js script to slow down the looping, but it’s otherwise the latest for both jquery.marquee.js and the jQuery stuff as well.

    Hope it helps.

  11. Update to my comment of May 24th, 2011. I’ve been busy and forgot about this problem, and now that I’ve remember abut it, I checked on it again and I couldn’t reproduce it at first, and the I could, and finally it clicked!

    It only happens in Chrome and only when the link is to a BLOG POST (WordPress.) It does not happen on regular pages. So now maybe I will be able to hunt down the fix, but if anyone else already has an idea, I’d love to hear it..

  12. Update to my comment above: No quick fix unfortunately, but I have managed to curb the behaviour somewhat with css by:

    1. Giving the marquee a height of 20px – this stopped the box from growing to a size that contains all the “spans”, but all the rows of text were still showing.

    2. I then set the marquee’s overflow to “hidden”, and now only One row is scrolling continuously. This will be more complicated to fix, and possibly over my head at this time, so…

    Remy, if you could check this out – maybe it’s a Chrome “bug” that you can fix?

    Thanks

  13. Hi.
    This plugin was really helpful to me, works great and doesn’t use CPU so much.
    Can anyone tell me how I make the whole string visible at the start of the animation?
    Thanks in advance.

  14. Hi,

    Remy, fantastic plugin man, well done!

    I am new to jquery and I am struggling with something, I have a set of buttons which when clicked will the user to increase and decrease the speed of the marquee, also these buttons will allow the user to change the direction of the scroll.

    I have tried so many things but I am not sure how to do this, please can you help me ?

    Thanks in advance!

  15. What is Silky Smooth licensed under?

    I did not see a refernece in the downloaded js?

  16. I have based my implementation of element marquee on the strategy described in this post. I am using CSS3 transitions for the compatible browsers and downgrade to animating scroll for the incompatible browsers. You may check out my implementation at https://github.com/gajus/marquee.

  17. Hi there,

    In answer to a few questions, I also at first glance struggled with setting the speed.

    I realized this plugin must use setTimeout and found the speed setting there. If you change the line:

    setTimeout(animateMarquee, 25);

    If you increase the 25 value you’ll get a slower “marquee”

    Thanks for the plugin. Great work!

  18. Great plugin – I’m looking to get this working without waiting until the last character leaves the left side (when scrolling). Basically want it to give the effect that it wraps around. Similar to this one javascript.about.com/library/blctmarquee1.htm only problem it isn’t a jquery plugin, and I’m not great at creating plugins.

  19. I created a fork of your gist here and modified it to handle ‘resize’ events. Feel free to look at it and use it in your code if you care to (verbatim, cleaned up or modified however you see fit of course).

    I tested it only on right-to-left horizontally scrolling text as that is all I use it for, but it should theoretically work in the other orientations as well.

  20. Hi.
    I read post several times, but don`t understand how to use library functionality!

    I have with fixed width, inside I put with overwlow hidden and some long text.
    How should I implement this in my case?

  21. The corrections of my last message:
    I have *li tag* with fixed width, inside I put *span tag* with overwlow hidden and some long text.
    How should I implement this in my case?

  22. Here is a simple continuous text marquee with pause function: http://jsfiddle.net/jithil89/BNBB6/

  23. hey,

    how can i update the content when the site is running?
    In the moment i have a div with a id in the marquee and i update the content in the div.

    How can i say your plugin to reload th length of the content?

  24. for just start and stop ue:
    jQuery(“marquee”).marquee().mouseover(function(){
    jQuery(this).trigger(‘stop’);
    }).mouseout(function () {
    jQuery(this).trigger(‘start’);
    });

  25. I know its not a big thing, but in HTML 5 using marquee as a child of a div it will break validation. That seems odd to me, as its just a basic effect that people tend to like on news feeds. . . . but might of been a little OVER done a few years back.

  26. Hey,

    I am trying to use the plugin in a responsive site. When the page is scaling down, I start the marquee when the text goes off the screen. However when the user scales the page backup I want to remove the marquee completely and let the text sit normally. trigger(‘stop’) doesn’t work because it stops it mid scroll. I tried trigger(‘end’) but that didn’t seem to do anything. I am not seeing a destroy function. Is there a way to remove the marquee from an element?

  27. Nice work.
    Download link seems to be broken.

  28. this pluggin remove all the classes you have in your marquee object o does not put it in the new div (i have not analyzed yet the pluggin source) and it should keep the classes so it could keep the structure and stiles. Just a suggestion. This plugin is awesome, but if you implement my suggestion it’ll be mere awesome.

  29. Very nice JS code! It works very nice and doesn’t eat CPU!

Leave a Reply
Not required

CODE: Please escape code and wrap in <pre><code>, doing so will automatically syntax highlight