以前实现文字滚动经常使用marquee标签,现在随着H5的兴起,鉴于该标签糟糕的体验,这个标签已经被W3C标准废弃了,尽管现在浏览器还支持这个标签,但是寻找文字滚动的新方式才是未来的选择。也有很多人会使用js脚本来实现文字滚动,这是兼容性和可操作性最强的做法。但是这种方式往往会使用定时器,实时操作DOM,除了比marquee能实现更多的滚动效果及功能外,并没有减少性能消耗,并且在一些新兴的MVVM框架中,如Vue,React,它们往往会对DOM视图进行数据绑定,这时候使用js操作DOM来实现文字滚动就有可能会破坏这种绑定,当文字再改变时就触发不了DOM更新了。随着CSS的发展,实现文字滚动有了更好的方式,那就是使用CSS动画。
当然,仅仅使文字滚动使用平移动画就好了:
<style>.scroll{width: 200px;height: 50px;line-height: 50px;white-space: nowrap;overflow: hidden;font-size: 30px;border: 1px solid #FF0000;}.scroll span{display: inline-block;/*inline样式不能使用动画*/animation: scroll 10s linear infinite;}@keyframes scroll {from {transform: translateX(200px)}to {transform: translateX(-100%)}}</style><div class="scroll"><span>我是一个滚动条啊滚动条</span></div>
但是这种滚动方式体验很差,中间有过多空白,接下来我们要实现一个首尾相连的文字滚动。在不使用js改变DOM结构的前提下,要为span里添加重复内容我们可以使用after伪元素,它有个attr函数可以获取所在父元素的属性内容,前提只要我们提前将span里的内容同时设置到属性里比如data-text,我们就可以只使用CSS为span添加尾部内容,这对使用VUE等框架是很方便的。
<style>.scroll{width: 200px;height: 50px;line-height: 50px;font-size: 30px;white-space: nowrap;overflow: hidden;border: 1px solid #ff0000;}.scroll span{display: inline-block;/*inline样式不能使用动画*/animation: scroll 12s linear infinite;}.scroll span:after{content: attr(data-text);margin-left: 4em;}@keyframes scroll {from {transform: translateX(0);}to {transform: translateX(calc(-50% - 2em)); /*总长的一半再加上margin-left的一半*/}}</style><div class="scroll"><span data-text="我是一个滚动条啊滚动条">我是一个滚动条啊滚动条</span></div>
上面已经基本上实现了首尾相连的文字滚动了,但是带有inline性质的元素会继承上层的很多样式影响布局,同时不同浏览器对div.scroll的最终宽度计算会有偏差,导致文字滚动出现错位。为了抹平差异,我们要对after元素使用绝对定位。
<style>.scroll{position: relative;width: 200px;height: 50px;line-height: 50px;font-size: 30px;white-space: nowrap;overflow: hidden;border: 1px solid #ff0000;}.scroll span{display: inline-block;/*inline样式不能使用动画*/animation: scroll 12s linear infinite;}.scroll span:after{position: absolute;left: 100%;content: attr(data-text);margin-left: 4em;}@keyframes scroll {from {transform: translateX(0);}to {transform: translateX(calc(-100% - 4em)); /*总长再加上margin-left*/}}</style><div class="scroll"><span data-text="我是一个滚动条啊滚动条">我是一个滚动条啊滚动条</span></div>
这样一个纯CSS实现的文字滚动的效果就实现了,如果要实现文字超长滚动只需判断div里的span宽度是否超出并为div添加scroll类即可。但是以上实现还是存在一个缺点,就是动画周期是提前定好的,对于不同长度的文字,滚动的速度会有快有慢,如果要追求对任何文字长度均采用固定速度滚动,可以使用js根据span宽度动态指定动画周期。