Please consider donating: a local project in memory of my daughter

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);
});

164 Responses to “The Silky Smooth Marquee”

  1. How would you get a vertical marquee to pause when the text reaches the center?

  2. To change the speed of the marque, just change the scrollamount attribute in the marquee tag itself. for example, here is my vertical marquee:

    
        <marquee behavior="scroll" direction="down" scrollamount="1" height="100" width="350">
    		<div id="result" ></div>
        </marquee>
    

    To support vertical dragging, I modified the horizontal marquee event positioning as follows:

    
    $('marquee').marquee('pointer').mouseover(function () {
      $(this).trigger('stop');
    }).mouseout(function () {
      $(this).trigger('start');
    }).mousemove(function (event) {
      if ($(this).data('drag') == true) {
    	this.scrollTop = $(this).data('scrollY')   ($(this).data('y') - event.clientY);
      }
    }).mousedown(function (event) {
      $(this).data('drag', true).data('y', event.clientY).data('scrollY', this.scrollTop);
    }).mouseup(function () {
      $(this).data('drag', false);
    })
    
  3. in an "up direction" marquee, is there a way to have the the text start at the top? i.e. not have the initial gap?

    also, between cycles of the marquee text - can the gap be removed somehow?

    THANKS!

  4. Has anyone gotten vertical dragging to work?

  5. Doesn't anyone validate there code anymore? http://twurl.nl/gforfk 15 errors! Mostly all down to the marquee tag.

  6. @Danny - don't you think you missing the point a bit? The marquee tag is depreciated, which of course the errors flag up when validating (there was one additional where I was missing the xmlns attribute in the head element which I've fixed).

    If you want perfectly validating code AND you want to use a marquee, then clearly this isn't the route you want to take.

    The idea of this code is that it progressively enhances the marquee tag (which is no longer valid, but supported in major desktop browsers) and makes it a smoother implementation than the native ones.

  7. nice job, you saved me a headache ;]

  8. Patrick Collins April 21st, 2009 at 9:49 am

    Hi, how can I update the text displayed inside the marquee later on? Before I would call $("div.ticker marquee").html("some new text...") however this no longer works because I assume you change the structure of the elements somewhat? Thanks, Pat

  9. i update the text doing this:
    zzzzzz

    so i must call:
    $('#item3_text').text('lol');

    i hopes works for you

  10. another issue is recover the id, so i did this:
    $('#item3').marquee('pointer').mouseover(function() {
    $(this).trigger('stop');
    }).mouseout(function() {
    $(this).trigger('start');
    }).css({ color: 'red', border: 'solid 1px black' }).attr("id", 'item3');

    note that i must re-add the "id"

  11. Marquee works great. Although, I'm trying to have it randomly throw in a new/different line of text at the end of each loop and before the next iteration begins and I'm having difficulty getting it to do so. I'm still relatively new to jQuery, but do any gurus have a suggestion?

    Any help would be greatly appreciated :)

  12. Hi

    Frequently if the scroll text would stop for a few seconds and then continue scrolling again. Is this something that can be tweaked or something that we really can't do anything about it?

    I use this to show 2 big scrolling text - one along the top scrolling horizontally and one scrolling vertically just below.

  13. Great bit of code took me a few hours to wrap my head around it...... THANKS

  14. Patrick Collins: I tried this, it seems to work. I put an ID on the marquee...


    <marquee id="myContents" behavior="scroll">Good morning!!!</marquee>
    <button onclick="$('#myContents').html('Good night');">Go to bed</button>

  15. Hey there, I read that you were busy with pressing projects. It seems there are a lot of people seeking a way to have a "gapless" endless marquee. Has ANYONE found a solution to this yet? It would be a an absolute God-send if someone could share.

    Of course, none of this would be possible without your fine work Remy. I will be forever in your debt for this amazing little plug-in. Hopefully, you'll find time to either post a fix or at least point us in the right direction. (I'm not smart enough to understand what 'destroy the element in the viewer' means).

    Thanks again!

  16. This really is a slick piece of code here!!! Thanks a lot for writing this for everyone.

    I am kind of desperate because I've been looking for an ajax friendly marquee. Is there a way to modify this code to execute an ajax command after each cycle?

    thanks
    bq

  17. Hi, thanks for this! Really helpful piece of code.

    I was just wondering if there's any way to restart the marquee after it has finished (for example by finishing the loop=1)? Triggering 'start' again does not seem to work as well as setting data 'loops' or 'last'..

  18. Gary McAllister June 3rd, 2009 at 1:30 pm

    Nice implementation, although the marquee doesn't resize for 100% widths.

  19. Hi. I´m implementing this marquee and it work properly in Opera. But this morning i notice that not in IE. Because when the content touchs the top, the cycle starts ones again.

    IE is saying 'the object doesnt recognize this property or method' when writing:
    $('#header #logo marquee').marquee('pointer'); or just
    $('marquee').marquee();

    So if this method is not working i have the bug i said on top. Please guide me.

  20. Solved loading the 1.3.2 version of Jquery. Why is not working with 1.2.6? It does in your demo page.

  21. I Could not use your plugin within joomla. Could you show me how to do it?

  22. I have a marquee inside a table cell. Before using this plugin, I had the marquee width of 100% and it would be as wide as the table cell. Now the 100% takes the width of the text used in the marquee.

    Is there a quick fix to all my marquee width to be the width of the table cell again? The cell width varies based upon how wide the browser is currently set to.

    
    <td style="padding: 0px;" width="90%"><font color="#ff8f69" size="3" style="vertical-align: top; padding-top: 0px; margin-top: 0px;">
         <div class="demo">
         <marquee direction="left" behavior="scroll" scrollamount="2" width="100%"><strong><center>
           PROTOTYPE   PROTOTYPE   PROTOTYPE </center></strong>
         </marquee></div></font>
       </td>
    

    Any help is much appreciated. Thanks!

  23. I found a fix, if anyone else has this issue. Just take out the width="100%" from the marquee. Then in your styles, place width: 100%; there. Mine was div.demo marquee { width: 100%; }

  24. Hey there, I read that you were busy with pressing projects. It seems there are a lot of people seeking a way to have a "gapless" endless marquee. Has ANYONE found a solution to this yet? It would be a an absolute God-send if someone could share.

    I did a little hack to achieve this effect.

    The gap between each cycle comes from the padding in the second generated div:

    <div class="jqmarquee" style="overflow: hidden; width: 728px; height: 69px;">
    <div style="padding: 0pt 728px; float: left; white-space: nowrap;">

    Remove this padding with javascript:

    $('marquee').marquee('jqmarquee');

    $('.jqmarquee div').css("padding","0");

    Your scrolling content must be at least 2 times the width of the marquee to prevent it from just jerking around wildly. What i did was just to clone my content a few times:

    $(".jqmarquee div a").clone().prependTo(".jqmarquee div").clone().prependTo(".jqmarquee div");

    There will still be a small jerk once it gets to the end but it's not too bad.

    See it in action here: http://www.steffigra.com/matt/test/video_marquee/index.html

  25. How can I pause the slide when I mouseover it?

  26. Does not work in FF3.5. It work well in previous versions of FF. Anyone?

  27. Hello.
    I´m getting a dirty display on IE8 when setting the scrollamount to 1.

    If i set it on 2 it works well, but the text goes too fast.

    Thanks a lot anyway for the script. And I wish help.
    Cheers.

  28. the code $("#marqueeId").html("text"); do not work...
    I've tryed all the above example!!!
    any idea?

  29. Hi,

    As mentioned above, having the marquee tag will cause your page to fail validation. I have a client who really wanted a scrolling "ticker" but would like the pages to validate too.

    So, I replaced the marquee with a div, gave it an id of marquee and removed all the marquee specific stuff like height, scrollamount etc. I then changed the jQuery call to be $('div#newsticker div#marquee').marquee (newsticker is just a containing div).

    Finally, I used some CSS styles to set a width and height for my marquee div. I also set it to display inline and float left but that was specific to what I was doing.

    The downside is that you may need to edit default values for things like scroll speed directly in the jquery.marquee.js file but it seems to work properly in Firefox 3.5, Opera 9.63, Chrome 2.0.172.37, IE7 and IE6 (through IETester).

    Hope this helps someone.

    Thanks for the great plugin.

  30. Hi,

    Thanks for the wonderful plugin. I found it very easy to use.

    I have a question though. Is it possible to set the initial display position? I don't like my div being empty at the start. Also when there remains quite a large white space between the last text and the first text. Is it possible to just show the content of my div and then keep scrolling without any gaps whatsoever?

    Thanks in advance.

  31. Thanks for this remy, I have used your marquee script before and I'm now using it again on another project. Thought I might aswell comment and say a big thanks!

  32. Thanks for this! It was used on http://www.habitatdane.org/

  33. thankyou but put a clear tutorial for beginner people too

  34. Hi !
    I am currently trying to use your plugin on a list where each li element get the property
    float:left;
    The plugin works fine but my elements are now unfloatable.
    How can i fix this ? Any idea ??

    Thanks

  35. Fixed thanks to Matt Cook :)

  36. I love this code! Thank you so much. One quick bug fix... or at least I think its a bug. If your using scroll="up" or "down" any text thats greater then the width of the marquee will be hidden in the overflow. It has been manually set in the code not to wrap. I can see how this makes sence for "right" and "left", but proves to be an issue on "up" and "down."

    I added (($marquee.attr('direction') == 'up') ? '' : ' white-space: nowrap;') into this line of code $marqueeRedux = $marquee.after('<div ' (klass ? 'class="' klass '" ' : '') 'style="display: block-inline; width: ' width 'px; height: ' height 'px; overflow: hidden;"><div style="float: left;' (($marquee.attr('direction') == 'up') ? '' : ' white-space: nowrap;') '">' $marquee.html() '</div></div>').next() to fix this.

    I hope this is the best solution... If its not let me know, thanks again!!!

  37. Can you help me, what is wrong with this example?

    If my text is shorter than the marque width, it is work fine. But if my text is longer than marque width the all is blinking.
    You can see in this page: http://weszil.hu/jQuery/index.php

    Thanks

  38. Hi, thanks for the marquee! Works great.

    But just one question. I'm trying to make the marquee fit when the window is being resized. It doesn't have a fixed width. When the resize event is fired the marquee should be redrawn. Does anyone have any idea on how to do this?


    <script type="text/javascript">
    <!--
    $(function(){
    $(window).resize(function(){
    //reset the marquee here and recalculate size
    });
    });
    //-->
    </script>

  39. How can you get the text to repeat before the previous loop has completed.

  40. Nobody meet this problem, when your text width is bigger, than marquee width and the marquee behaviour set to alternate, the moving is wrong?

  41. Awsome job Remy!! This has helped me a lot. I almost resorted to Flash to resolve my CPU utilization issues but this saved the day.

    I'm using it on a very dynamic page and I like to use the "destroy()" functionality, mentioned in a previous post, to remove the scroller when not needed anymore.

    Have you had a chance to look into adding this functionality?

  42. When you drag and "mouseout", the scroll continues but as soon as you "mouseover" the text starts dragging without a mousedown event.

  43. for width problem
    change tags in jquery.marquee.js
    line 100

  44. hi guys, great piece of code!
    but I’ve got a question about customizing it, as I’ve never worked with js beforehand (just html,php,css..).
    I’d like two things to happen, the first being that whatever was scrolling from right to left would already start on the left (instead of coming out of the right end),
    and the other thing being – making the text scroll in a circle, instead of it waiting for it all to disappear on the left – and only then appearing on the right, i’d want the beginning to appear straight away when the end comes out of the right hand side (that is, as long as there is enough writing there).
    thanks, and if you don’t feel like writing those things, could you at least direct me to a relevant tutorial? (taking notice of my lack of js knowledge)
    thank you very much, tom

  45. This is very useful - one issue for me though is the lack of support of the scrolldelay attribute of the marquee tag.. This means that there isn't a lot of control over the speed of scrolling. I have manually set the timeout on the animation to slow it down for my purposes but it would be good if the scrolldelay attribute could be used to set this value somehow..

  46. Hi! Nice plugin you made here.
    I think you should really consider adding option for setting an overall default. It would allow people to use your plugin on other tags than MARQUEE, as marquee tag does not pass xhtml validation.
    It's too bad valid xhtml pages have to avoid your script because of that.

  47. It would be really cool if the white space at the end of the marquee can be removed and it constantly rotates, has anyone got this to work?

  48. If the initial text in a marquee is empty, the marquee does not work. I think it generates some JavaScript errors. It will be useful to have a function for setting marquee text after it is initialized.

  49. Thanks for the tutorial. Just have one question. How can you make the marquee go around only once or twice? Cheers!

  50. Thanks for the script.
    Would'nt it be nice to have a "seamless scroll" option for longer texts...
    So one doesn't have to wait - and the texts starts again at its end

Leave a Reply
Not required

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