为什么<marquee>被弃用了,最佳替代方案是什么?

106

我对HTML标签<marquee>很好奇已经有一段时间了。

你可以在MDN规范中找到相关内容:

已废弃 此功能已经被废弃。虽然它可能仍然在某些浏览器中工作,但是由于它随时可能被删除,因此不建议使用它。请尽量避免使用它。

或者在W3C wiki上查找:

真的,不要使用它。

我搜索了几篇文章,并发现了一些关于CSS替代方案的提及。CSS属性如下:

marquee-play-count
marquee-direction
marquee-speed

但似乎它们不起作用。它们是2008年规范的一部分,但在2014年被排除。

W3联盟提出的一种方法是使用CSS3动画,但对我来说比易于维护的<marquee>要复杂得多。

还有许多JS替代方案,有大量源代码可添加到您的项目中,使其变得更大。

我总是看到这样的话:“永远不要使用跑马灯”,“已经过时”。我不明白为什么。

那么,有人能解释一下,为什么跑马灯已被弃用,为什么使用它会很“危险”,以及最简单的替代方法是什么吗?

我发现了一个示例,它看起来很不错。当你使用所有必需的前缀以获得良好的浏览器支持时,你需要大约20-25行CSS,并硬编码2个值(开始和停止缩进),这取决于文本长度。这种解决方案不太灵活,你无法使用它创建从底部到顶部的效果。

48
最简单的替换方法是不要移动你希望用户阅读的文本 :) - doldt
3
使用跑马灯不会对用户造成影响,但如果浏览器供应商决定在下一个版本中删除它,用户将无法再看到内容。 - Teemu
1
@areim 你应该考虑换一个更好的音乐播放器 :-) - Lucas Trzesniewski
1
@areim,也许歌曲不是一个好的例子,因为当歌曲播放时,没有真正需要阅读滚动标题。此外,你在日常生活中看到的这些跑马灯,在网络上可能并不适用。对我个人而言,当我看到跑马灯时,通常会完全忽略它,因为我不想等待和阅读。使用CSS3动画,设置跑马灯并不那么复杂。 - Huangism
4
是的,我也不喜欢它,并会忽略网页上所有讨厌的动态元素,但为什么它被弃用了呢?它很清晰简单。它是否存在一些真正的问题?它不能仅仅是因为“大多数人不喜欢它”。今天有大量的视差和滑块元素:-D - areim
显示剩余2条评论
6个回答

93

我认为你不应该移动内容,但这并没有回答你的问题……看一下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); }
}

这里是codepen

编辑:

这里是自下而上的codepen


7
非常好,但如果滚动内容中有多个div或多个P时它无法工作 :( - Radon8472
1
回答这个关于过时的问题其实很简单:将整个内容放在一个 div 中,然后将元素放在 span 中。https://codepen.io/scwall/pen/mdemeER - Pascal de Sélys
3
如何使其重复而无需在最后一个<span>和重复的第一个<span>之间添加任何空格(最后一个<span>后面没有空格)? - josh
如果您想要在没有空格的情况下重复,您需要通过JavaScript克隆p节点并将其附加在第一个节点之后。然后,您可以从transform: translate(0, 0)动画到transform: translate(-50%, 0)并且无需任何可见的中断即可重复(前提是两个p节点的宽度大于容器的宽度)。 - Jasper Habicht

17

<marquee>从未作为任何HTML规范的一部分存在,您链接的是一个CSS规范,因此很难废弃从未包含的内容。HTML关注文档的结构,而不是其展示方式。因此,在HTML中拥有自动动画元素并不符合这些目标。动画应该在CSS中实现。


3
@user7892745,你的论点并不能使这个标签不再过时 - honk31
https://html.spec.whatwg.org/multipage/rendering.html#the-marquee-element-2 - BarryCap
1
@BarryCap 已废弃的特性 - 跑马灯 由于该元素从未成为任何HTML规范的一部分,但其使用过于广泛,因此有必要在规范中创建一个条目以将其标记为已废弃。 - Rob

16

你只需要在CSS中定义类和挂载循环动画一次,然后在任何需要的地方使用它。但是,正如许多人所说 - 这是一个有点令人烦恼的做法,而且这个标签正在逐渐过时也有充分的理由。

.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 5s linear infinite;
       -webkit-animation: example1 5s linear infinite;
       animation: example1 5s 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>


7

我知道这个问题几年前就有答案了,但是当我检查这个时,我发现了以下内容。

在检查中,我发现了以下内容。

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

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

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

3
欢迎几个月后回来...你链接的谷歌搜索结果的整个第一页现在都是一些网站资源列表,这些资源解释了 marquee 标签已经被废弃,但没有提供替代方案。当搜索“HTML marquee 替代方案”时,第一个搜索结果是 StackOverflow 的页面,因此无需返回谷歌搜索。 - grek40
@grek40b 我猜是这样,但是你可以尝试用其他搜索引擎或者在 Stack Overflow 上搜索一下吗? - Bryan Zeng
可爱的谷歌彩蛋!..挺有趣的。:) https://www.google.com/search?q=marquee+html - Rowe Morehouse

5

如之前所述:最简单的替代方法是CSS动画。

对于所有批评跑马灯的人:

它是UI中非常有用的工具, 我只在悬停时使用它, 以在有限的空间中显示更多信息。

mp3播放器的示例非常好, 甚至我的汽车收音机也使用该效果来显示当前歌曲。

所以没有任何问题,这是我的观点...


8
他们的观点是,HTML 是“超文本标记语言”,而动画并不属于文档结构(因此也不是标记)的关注点,它是一种呈现(presentation)的关注点。这就是为什么它现在被归入到 CSS 和/或 JavaScript 中实现的原因。 - Tim Goyer
那么,为什么要有很棒的输入呢?嗯? - user7892745
1
@TimGoyer 我只是在思考一般情况下使用跑马灯效果,作为回答那些说:“不要移动文本!”的人的一个解决方案。在CSS中实现它比使用HTML <marquee> 更好和合理,这是我的看法。 - Wolfgang Blessen
1
@user7892745 - 在表单中添加数据输入是文档结构方面的问题。使它们“棒极了”是样式/脚本方面的问题,这取决于您对“棒极了”的定义。Wolfgang - 我同意动画最好作为CSS/脚本效果实现。我只是指出HTML关注文档结构,这就是为什么<marquee>被弃用的原因。它没有提供基于结构的优势,除了<div>标签已经提供的之外。它只是附加了一个应该通过脚本或样式处理的动画。 - Tim Goyer

1
我已经创建了一个jQuery脚本,它将使用标准的
标签替换旧的标签。该代码还会解析属性,如方向、滚动延迟和滚动速度。实际上,该代码可以跳过jQuery部分,但我感到太懒了,而且vanilla JS部分实际上是我从@Stano答案here中修改的解决方案。
下面是代码:

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;

      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();
});
.wrap {
  width: 50%;
  margin: 0 auto;
  overflow: hidden;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="wrap">
  <marquee direction="left" scrollamount="5" scrolldelay="1"> Timses Jokowi: Apa Urusan Pilpres dengan masuk surga? ---&nbsp;Ma'ruf Amin: Semua orang tahu saya tua, tapi... ---&nbsp;Kata Cak Imin soal pidato Jokowi dan Prabowo yang jadi kontroversi ---&nbsp;2 tahun ditahan, pendeta AS Andrew Brunson dibebaskan
    Turki ---&nbsp;Perkembangan terbaru kasus SPG yang buang bayi dari lantai 3 Mal --- Breaking News --- </marquee>

  <marquee direction="rigth" scrollamount="10" scrolldelay="2"> Timses Jokowi: Apa Urusan Pilpres dengan masuk surga? ---&nbsp;Ma'ruf Amin: Semua orang tahu saya tua, tapi... ---&nbsp;Kata Cak Imin soal pidato Jokowi dan Prabowo yang jadi kontroversi ---&nbsp;2 tahun ditahan, pendeta AS Andrew Brunson dibebaskan
    Turki ---&nbsp;Perkembangan terbaru kasus SPG yang buang bayi dari lantai 3 Mal --- Breaking News --- </marquee>
</div>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接