Why is <marquee> deprecated and what is the best alternative?

JavascriptHtmlCssMarquee

Javascript Problem Overview


Longer time I'm curious about HTML tag <marquee>.

You can find in MDN specification:

> Obsolete This feature is obsolete. Although it may still work in some browsers, its use is discouraged since it could be removed at any time. Try to avoid using it.

or on W3C wiki:

> No, really. don't use it.

I searched several articles and found some mention about CSS relevant replacement. CSS attributes like:

marquee-play-count
marquee-direction
marquee-speed

but it seems, they don't work. They were a part of specification in year 2008, but they were excluded in year 2014

One way, proposed by W3 Consortium, is using CSS3 animations, but it seems for me much more complicated than easy-to-maintain <marquee>.

There are also plenty of JS alternatives, with lots of source code that you can add to your projects and make them larger.

I'm always reading things as: "don't ever use marquee", "is obsolete". And I don't get why.

So, can anybody explain to me, why is marquee deprecated, why is so "dangerous" using it and what is the easiest substitution?

I found an example, it looks nice. When you use all prefixes needed for good browser support, you have around 20-25 lines of CSS, with 2 values hardcoded (start and stop indent), depending on text length. This solution is not so flexible, and you can't create bottom-to-top effect with this.

Javascript Solutions


Solution 1 - Javascript

I don't think you should move the content but that doesn't answer your question... Take a look at the CSS:

.marquee {
    width: 450px;
	line-height: 50px;
	background-color: red;
	color: white;
    white-space: nowrap;
    overflow: hidden;
    box-sizing: border-box;
}
.marquee p {
    display: inline-block;
    padding-left: 100%;
    animation: marquee 15s linear infinite;
}
@keyframes marquee {
    0%   { transform: translate(0, 0); }
    100% { transform: translate(-100%, 0); }
}

Here is the codepen.

Edit:

Here is the bottom to top codepen.

Solution 2 - Javascript

You just have to define class and attached looping animation once in CSS and use it afterwards everywhere you need. But, as many people said - it's a bit annoying practice, and there is a good reason, why this tag is becoming obsolete.

.example1 {
  height: 50px;	
  overflow: hidden;
  position: relative;
}
.example1 h3 {
    position: absolute;
    width: 100%;
    height: 100%;
    margin: 0;
    line-height: 50px;
    text-align: center;

    /* Starting position */
       -moz-transform:translateX(100%);
       -webkit-transform:translateX(100%);	
       transform:translateX(100%);

 /* Apply animation to this element */	
       -moz-animation: example1 15s linear infinite;
       -webkit-animation: example1 15s linear infinite;
       animation: example1 15s linear infinite;
}

/* Move it (define the animation) */
      @-moz-keyframes example1 {
       0%   { -moz-transform: translateX(100%); }
       100% { -moz-transform: translateX(-100%); }
      }
      @-webkit-keyframes example1 {
       0%   { -webkit-transform: translateX(100%); }
       100% { -webkit-transform: translateX(-100%); }
      }
      @keyframes example1 {
       0%   { 
       -moz-transform: translateX(100%); /* Firefox bug fix */
       -webkit-transform: translateX(100%); /* Firefox bug fix */
       transform: translateX(100%); 		
       }
       100% { 
       -moz-transform: translateX(-100%); /* Firefox bug fix */
       -webkit-transform: translateX(-100%); /* Firefox bug fix */
       transform: translateX(-100%); 
       }
      }
    

<div class="example1">
   <h3>Scrolling text... </h3>
</div>

Solution 3 - Javascript

<marquee> was never part of any HTML specification and what you link to is a CSS spec so it's hard to deprecate something that was never included. HTML is about structure of a document, not its presentation. So having a self-animated element as part of HTML does not abide by those goals. Animation is in CSS.

Solution 4 - Javascript

As stated before: the easiest substitution is CSS animation

To all the critics of the marquee:

It is a very useful tool for UI, I am using it just on hover, to display more information in a limited space.

The example for the mp3-player is excellent, even my car-radio is using the effect to show the current song.

So nothing wrong about that, my opinion ...

Solution 5 - Javascript

I know this was answered a couple years ago, but I found this when inspecting this. When I inspected, I found this.

@keyframes scroll {
    from {
        transform: translate(0,0)
    }

    to {
       transform: translate(-300px,0)
    }
}

.resultMarquee {
    animation: scroll 7s linear 0s infinite;
    position: absolute
}

Solution 6 - Javascript

I have created a jQuery script that will replace the old marquee tag with standard div. The code will also parse the marquee attributes like direction, scrolldelay and scrollamount. Actually the code can skip the jQuery part but I felt too lazy to do so, and the vanilla JS part is actually a solution that I modified from @Stano answere from here

Here is the code:

jQuery(function ($) {

    if ($('marquee').length == 0) {
        return;
    }

    $('marquee').each(function () {
        
        let direction = $(this).attr('direction');
        let scrollamount = $(this).attr('scrollamount');
        let scrolldelay = $(this).attr('scrolldelay');

        let newMarquee = $('<div class="new-marquee"></div>');
        $(newMarquee).html($(this).html());
        $(newMarquee).attr('direction',direction);
        $(newMarquee).attr('scrollamount',scrollamount);
        $(newMarquee).attr('scrolldelay',scrolldelay);
        $(newMarquee).css('white-space', 'nowrap');

        let wrapper = $('<div style="overflow:hidden"></div>').append(newMarquee);
        $(this).replaceWith(wrapper);

    });

    function start_marquee() {

        let marqueeElements = document.getElementsByClassName('new-marquee');
        let marqueLen = marqueeElements.length
        for (let k = 0; k < marqueLen; k++) {

            
            let space = '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
            let marqueeEl = marqueeElements[k];

            let direction = marqueeEl.getAttribute('direction');
            let scrolldelay = marqueeEl.getAttribute('scrolldelay') * 100;
            let scrollamount = marqueeEl.getAttribute('scrollamount');

            let marqueeText = marqueeEl.innerHTML;

            marqueeEl.innerHTML = marqueeText + space;
            marqueeEl.style.position = 'absolute'; 

            let width = (marqueeEl.clientWidth + 1);
            let i = (direction == 'rigth') ? width : 0;
            let step = (scrollamount !== undefined) ? parseInt(scrollamount) : 3;

            marqueeEl.style.position = '';
            marqueeEl.innerHTML = marqueeText + space + marqueeText + space;

            
            
            let x = setInterval( function () {

                if ( direction.toLowerCase() == 'left') {
    
                    i = i < width ? i + step : 1;
                    marqueeEl.style.marginLeft = -i + 'px';

                } else {

                    i = i > -width ? i - step : width;
                    marqueeEl.style.marginLeft = -i + 'px';

                }

            }, scrolldelay);

        }
    }

    start_marquee ();
});

And here is a working codepen

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionareimView Question on Stackoverflow
Solution 1 - JavascriptThomas BormansView Answer on Stackoverflow
Solution 2 - JavascriptArtanisView Answer on Stackoverflow
Solution 3 - JavascriptRobView Answer on Stackoverflow
Solution 4 - JavascriptWolfgang BlessenView Answer on Stackoverflow
Solution 5 - JavascriptBryan ZengView Answer on Stackoverflow
Solution 6 - JavascriptAleView Answer on Stackoverflow