首页 > 解决方案 > 仅使用 CSS 滚动消息

问题描述

我正在尝试创建一个滚动的重要消息(我不是特别喜欢它们,但客户有要求!)。理想情况下,我想为此避免使用 JavaScript,但我不确定这是否可行。

到目前为止,我有几个选择,所有这些都有缺陷。

具有“警报”类的 div 中的前 2 个以不同的速度滚动(消息越长滚动越快)。更重要的是,如果消息比容器短,它会从容器中间开始动画。

最后 2 个(使用“alert_x”类)以相同的速度滚动,但逻辑错误,因为动画基于视口宽度而不是消息宽度。

有没有办法确保消息滚动到正确的位置(从容器的右侧到左侧)并以相同的速度滚动,无论消息的大小如何 - 最好不使用 JavaScript?

如果需要 JS,则 jQuery 不是一个选项。

.alert {
  height: 34px;
  overflow: hidden;
  position: relative;
  background: #00B5D9;
  margin-bottom: 20px;
  display: flex;
}

.alert p {
  position: absolute;
  width: auto;
  white-space: nowrap;
  -moz-transform: translateX(100%);
  -webkit-transform: translateX(100%);
  transform: translateX(100%);
  -moz-animation: scroll-left 10s linear infinite;
  -webkit-animation: scroll-left 10s linear infinite;
  animation: scroll-left 10s linear infinite;
}


/* Move it (define the animation) */

@-moz-keyframes scroll-left {
  0% {
    -moz-transform: translateX(100%);
  }
  100% {
    -moz-transform: translateX(-100%);
  }
}

@-webkit-keyframes scroll-left {
  0% {
    -webkit-transform: translateX(100%);
  }
  100% {
    -webkit-transform: translateX(-100%);
  }
}

@keyframes scroll-left {
  0% {
    -moz-transform: translateX(100%);
    /* Browser bug fix */
    -webkit-transform: translateX(100%);
    /* Browser bug fix */
    transform: translateX(100%);
  }
  100% {
    -moz-transform: translateX(-100%);
    /* Browser bug fix */
    -webkit-transform: translateX(-100%);
    /* Browser bug fix */
    transform: translateX(-100%);
  }
}

.alert_x {
  height: 34px;
  overflow: hidden;
  position: relative;
  background: #00B5D9;
  margin-bottom: 20px;
  display: flex;
}

.alert_x p {
  position: absolute;
  width: auto;
  white-space: nowrap;
  -moz-transform: translateX(calc(100vw));
  -webkit-transform: translateX(calc(100vw));
  transform: translateX(calc(100vw));
  -moz-animation: scroll-left-x 10s linear infinite;
  -webkit-animation: scroll-left-x 10s linear infinite;
  animation: scroll-left-x 10s linear infinite;
}


/* Move it (define the animation) */

@-moz-keyframes scroll-left-x {
  0% {
    -moz-transform: translateX(calc(100vw));
  }
  100% {
    -moz-transform: translateX(calc(100vw * -1));
  }
}

@-webkit-keyframes scroll-left-x {
  0% {
    -webkit-transform: translateX(calc(100vw));
  }
  100% {
    -webkit-transform: translateX(calc(100vw * -1));
  }
}

@keyframes scroll-left-x {
  0% {
    -moz-transform: translateX(calc(100vw));
    /* Browser bug fix */
    -webkit-transform: translateX(calc(100vw));
    /* Browser bug fix */
    transform: translateX(calc(100vw));
  }
  100% {
    -moz-transform: translateX(calc(100vw * -1));
    /* Browser bug fix */
    -webkit-transform: translateX(calc(100vw * -1));
    /* Browser bug fix */
    transform: translateX(calc(100vw * -1));
  }
}
<div class="alert">
  <p>
    Short message
  </p>
</div>

<div class="alert">
  <p>
    Long message... Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt. Lorem ipsum dolor sit amet, consectetur adipiscing elit,
    sed do eiusmod tempor incididunt.
  </p>
</div>


<div class="alert_x">
  <p>
    Short message
  </p>
</div>

<div class="alert_x">
  <p>
    Long message... Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt. Lorem ipsum dolor sit amet, consectetur adipiscing elit,
    sed do eiusmod tempor incididunt.
  </p>
</div>

JSFiddle上查看。

编辑!

好的,所以我找到了一个更好的选择,它采用了类似的方法。它解决了所有问题,除了速度因消息长度而异的事实。

@-webkit-keyframes ticker {
  0% {
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
visibility: visible;
  }
  
  100% {
-webkit-transform: translate3d(-100%, 0, 0);
transform: translate3d(-100%, 0, 0);
  }
}

@keyframes ticker {
  0% {
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
visibility: visible;
  }
  
  100% {
-webkit-transform: translate3d(-100%, 0, 0);
transform: translate3d(-100%, 0, 0);
  }
}

.alert-wrap {
  width: 100%;
  overflow: hidden;
  background-color: teal;
  padding-left: 100%;
}

.alert {
  display: inline-block;
  white-space: nowrap;
  padding-right: 100%;
  -webkit-animation-iteration-count: infinite;
  animation-iteration-count: infinite;
  -webkit-animation-timing-function: linear;
  animation-timing-function: linear;
  -webkit-animation-name: ticker;
  animation-name: ticker;
  -webkit-animation-duration: 30s;
  animation-duration: 30s;
}

body {
  margin: 0;
}
<div class="alert-wrap">
<div class="alert">
    <div>Long message... Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt. Long message... Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt. Long message... Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt.
    </div>
</div>
</div>

标签: htmlcss

解决方案


我不确定我是否正确理解了这个问题,但如果我理解了,这是您正在寻找的那种东西:

工作示例:

body {
overflow-x: hidden;
}

p {
transform: translateX(100vw);
white-space: nowrap;
animation: scrollLeft 15s linear infinite; 
}

@keyframes scrollLeft {
0% {transform: translateX(100vw);}
100% {transform: translateX(-375vw);}
}
<p>Tiny message.</p>
<p>This is a short message.</p>
<p>This is something which at least approaches a medium length message.</p>
<p>This is, as you can see, a rather longer message which takes up a lot more space and is certainly visually longer than the preceding three messages.</p>
<p>This is an absolutely enormous message which seems to go on and on forever and never really looks like it's going to end and you start to wonder if it might actually go on infinitely but then, eventually, almost unexpectedly it does, finally... wait for it... suggest that it might stop... before it actually continues a little more and then, reluctantly does indeed, finally come to an end.</p>


第二次尝试

现在我已经更好地掌握了预期的效果,我已经采用了 javascript 方法(使用CSSOM)。我已经完成了大部分工作,但我一直坚持试图让所有消息以相同的速度滚动。

因为它是:

  • 消息都在同一时间从同一个地方开始
  • 消息同时在同一个地方结束(然后重新启动)

但是,可以预见的是,这意味着消息并非都以相同的速度移动 - 较长的消息比较短的消息移动得更快,以便同时完成它们的滚动动画。

工作示例:

const paragraphs = [... document.getElementsByTagName('p')];

paragraphs.forEach(function(paragraph){
paragraph.dataset.width = parseInt(window.getComputedStyle(paragraph).getPropertyValue('width')) + 12;

const stylesheet = document.styleSheets[(document.styleSheets.length - 1)];
stylesheet.insertRule('[data-width="' + paragraph.dataset.width + '"]{animation: scrollLeft_' + paragraph.dataset.width + ' ' + ((paragraph.dataset.width + window.innerWidth) / ((paragraph.dataset.width + window.innerWidth) / 20)) + 's linear infinite;}', stylesheet.cssRules.length);
stylesheet.insertRule('@keyframes scrollLeft_' + paragraph.dataset.width + '{0%{transform: translateX(100vw);} 100%{transform: translateX(calc(0vw - ' + paragraph.dataset.width + 'px));}}', stylesheet.cssRules.length);

});
body {
overflow-x: hidden;
}

p {
display: inline-block;
float: left;
clear: left;
padding: 6px;
color: rgb(255, 255, 255);
background-color: rgb(255, 0, 0);
border-radius: 3px;
transform: translateX(100vw);
white-space: nowrap;
}
<p>Tiny message.</p>
<p>This is a short message.</p>
<p>This is something which at least approaches a medium length message.</p>
<p>This is, as you can see, a rather longer message which takes up a lot more space and is certainly visually longer than the preceding three messages.</p>
<p>This is an absolutely enormous message which seems to go on and on forever and never really looks like it's going to end and you start to wonder if it might actually go on infinitely but then, eventually, almost unexpectedly it does, finally... wait for it... suggest that it might stop... before it actually continues a little more and then, reluctantly does indeed, finally come to an end.</p>


推荐阅读