使用 CSS 个关键帧创建计数器

Create counter using CSS keyframes

是否可以通过更改元素内容使用关键帧创建动画计数器?

例如:

.loop:before{
    animation: loop 10s linear;
}

@keyframes loop {
    0% {
        content: '0';
    }
    10% {
        content: '10';
    }
    20% {
        content: '20';
    }
    30% {
        content: '30';
    }
    40% {
        content: '40';
    }
    50% {
        content: '50';
    }
    60% {
        content: '60';
    }
    70% {
        content: '70';
    }
    80% {
        content: '80';
    }
    90% {
        content: '90';
    }
}

万一不可能,有没有办法用 HTML/CSS 而不用 javascript?

content 属性 无法通过 @keyframestransition 进行操作,但是您可以使用带有文本的 :pseudo-element 来实现0 10 20 30 40 50 60 70 80 90 并对其 margin-top 属性.

进行动画处理

div {
  position: relative;
  width: 20px;
  height: 20px;
  border: 1px solid black;
  overflow: hidden;
}
div:after {
  content: attr(data-val);
  position: absolute;
  top: 0;
  left: 0;
  line-height: 20px;
  text-align: center;
  -webkit-animation: loop 10s linear;
  animation: loop 10s linear;
}
@-webkit-keyframes loop {
  0% { margin-top: 0px; }
  9% { margin-top: 0px; }
  10% { margin-top: -20px; }
  19% { margin-top: -20px; }
  20% { margin-top: -40px; }
  29% { margin-top: -40px; }
  30% { margin-top: -60px; }
  39% { margin-top: -60px; }
  40% { margin-top: -80px; }
  49% { margin-top: -80px; }
  50% { margin-top: -100px; }
  59% { margin-top: -100px; }
  60% { margin-top: -120px; }
  69% { margin-top: -120px; }
  70% { margin-top: -140px; }
  79% { margin-top: -140px; }
  80% { margin-top: -160px; }
  89% { margin-top: -160px; }
  90% { margin-top: -180px; }
  99% { margin-top: -180px; }
  100% { margin-top: -200px; }
}
@keyframes loop {
  0% { margin-top: 0px; }
  9% { margin-top: 0px; }
  10% { margin-top: -20px; }
  19% { margin-top: -20px; }
  20% { margin-top: -40px; }
  29% { margin-top: -40px; }
  30% { margin-top: -60px; }
  39% { margin-top: -60px; }
  40% { margin-top: -80px; }
  49% { margin-top: -80px; }
  50% { margin-top: -100px; }
  59% { margin-top: -100px; }
  60% { margin-top: -120px; }
  69% { margin-top: -120px; }
  70% { margin-top: -140px; }
  79% { margin-top: -140px; }
  80% { margin-top: -160px; }
  89% { margin-top: -160px; }
  90% { margin-top: -180px; }
  99% { margin-top: -180px; }
  100% { margin-top: -200px; }
}
<div class="loop" data-val="0 10 20 30 40 50 60 70 80 90"></div>

恐怕这是不可能的,根据 w3c content 属性 是不可动画的。但是你可以这样做:

也许这不是最好的解决方案,但它是另一种, 只需在每个元素的动画的第四个参数中指定一个延迟

ul li{
    margin: 0;
    padding: 0;
    list-style: none;
}
.loop{    
    opacity: 0;
    position: absolute;
}
ul li.loop:nth-child(1){
    -webkit-animation: loop 1s linear 0s;
    animation: loop 1s linear 0s;
}
ul li.loop:nth-child(2){
    -webkit-animation: loop 1s linear 1s;
    animation: loop 1s linear 1s;
}
ul li.loop:nth-child(3){
    -webkit-animation: loop 1s linear 2s;
    animation: loop 1s linear 2s;
}
ul li.loop:nth-child(4){
    -webkit-animation: loop 1s linear 3s;
    animation: loop 1s linear 3s;
}
ul li.loop:nth-child(5){
    -webkit-animation: loop 1s linear 4s;
    animation: loop 1s linear 4s;
}
ul li.loop:nth-child(6){
    -webkit-animation: loop 1s linear 5s;
    animation: loop 1s linear 5s;
}
@-webkit-keyframes loop {
    to{opacity:1}
}
@keyframes loop {
    to{opacity:1}
}
<ul>
    <li class="loop">00</li>
    <li class="loop">01</li>
    <li class="loop">02</li>
    <li class="loop">03</li>
    <li class="loop">04</li>
    <li class="loop">05</li>
</ul>

回答晚了,这种情况下有使用计数器的想法:

.test {
  position: relative;
  height: 20px;
  overflow: hidden;
}
.test::before {
  position: absolute;
  top: 100%;
  content: counter(before);
  animation: beforeCount 10s linear infinite, move 2s linear infinite;
}
.test::after {
  position: absolute;
  top: 100%;
  content: counter(after);
  animation: afterCount 10s -0.1s linear infinite, move 2s 1s linear infinite;
}
@-moz-keyframes beforeCount {
  0% {
    counter-increment: before 0;
  }
  10% {
    counter-increment: before 10;
  }
  20% {
    counter-increment: before 20;
  }
  30% {
    counter-increment: before 30;
  }
  40% {
    counter-increment: before 40;
  }
  50% {
    counter-increment: before 50;
  }
  60% {
    counter-increment: before 60;
  }
  70% {
    counter-increment: before 70;
  }
  80% {
    counter-increment: before 80;
  }
  90% {
    counter-increment: before 90;
  }
}
@-webkit-keyframes beforeCount {
  0% {
    counter-increment: before 0;
  }
  10% {
    counter-increment: before 10;
  }
  20% {
    counter-increment: before 20;
  }
  30% {
    counter-increment: before 30;
  }
  40% {
    counter-increment: before 40;
  }
  50% {
    counter-increment: before 50;
  }
  60% {
    counter-increment: before 60;
  }
  70% {
    counter-increment: before 70;
  }
  80% {
    counter-increment: before 80;
  }
  90% {
    counter-increment: before 90;
  }
}
@-o-keyframes beforeCount {
  0% {
    counter-increment: before 0;
  }
  10% {
    counter-increment: before 10;
  }
  20% {
    counter-increment: before 20;
  }
  30% {
    counter-increment: before 30;
  }
  40% {
    counter-increment: before 40;
  }
  50% {
    counter-increment: before 50;
  }
  60% {
    counter-increment: before 60;
  }
  70% {
    counter-increment: before 70;
  }
  80% {
    counter-increment: before 80;
  }
  90% {
    counter-increment: before 90;
  }
}
@keyframes beforeCount {
  0% {
    counter-increment: before 0;
  }
  10% {
    counter-increment: before 10;
  }
  20% {
    counter-increment: before 20;
  }
  30% {
    counter-increment: before 30;
  }
  40% {
    counter-increment: before 40;
  }
  50% {
    counter-increment: before 50;
  }
  60% {
    counter-increment: before 60;
  }
  70% {
    counter-increment: before 70;
  }
  80% {
    counter-increment: before 80;
  }
  90% {
    counter-increment: before 90;
  }
}
@-moz-keyframes afterCount {
  0% {
    counter-increment: after 0;
  }
  10% {
    counter-increment: after 10;
  }
  20% {
    counter-increment: after 20;
  }
  30% {
    counter-increment: after 30;
  }
  40% {
    counter-increment: after 40;
  }
  50% {
    counter-increment: after 50;
  }
  60% {
    counter-increment: after 60;
  }
  70% {
    counter-increment: after 70;
  }
  80% {
    counter-increment: after 80;
  }
  90% {
    counter-increment: after 90;
  }
}
@-webkit-keyframes afterCount {
  0% {
    counter-increment: after 0;
  }
  10% {
    counter-increment: after 10;
  }
  20% {
    counter-increment: after 20;
  }
  30% {
    counter-increment: after 30;
  }
  40% {
    counter-increment: after 40;
  }
  50% {
    counter-increment: after 50;
  }
  60% {
    counter-increment: after 60;
  }
  70% {
    counter-increment: after 70;
  }
  80% {
    counter-increment: after 80;
  }
  90% {
    counter-increment: after 90;
  }
}
@-o-keyframes afterCount {
  0% {
    counter-increment: after 0;
  }
  10% {
    counter-increment: after 10;
  }
  20% {
    counter-increment: after 20;
  }
  30% {
    counter-increment: after 30;
  }
  40% {
    counter-increment: after 40;
  }
  50% {
    counter-increment: after 50;
  }
  60% {
    counter-increment: after 60;
  }
  70% {
    counter-increment: after 70;
  }
  80% {
    counter-increment: after 80;
  }
  90% {
    counter-increment: after 90;
  }
}
@keyframes afterCount {
  0% {
    counter-increment: after 0;
  }
  10% {
    counter-increment: after 10;
  }
  20% {
    counter-increment: after 20;
  }
  30% {
    counter-increment: after 30;
  }
  40% {
    counter-increment: after 40;
  }
  50% {
    counter-increment: after 50;
  }
  60% {
    counter-increment: after 60;
  }
  70% {
    counter-increment: after 70;
  }
  80% {
    counter-increment: after 80;
  }
  90% {
    counter-increment: after 90;
  }
}
@-moz-keyframes move {
  0% {
    top: 120%;
  }
  100% {
    top: -120%;
  }
}
@-webkit-keyframes move {
  0% {
    top: 120%;
  }
  100% {
    top: -120%;
  }
}
@-o-keyframes move {
  0% {
    top: 120%;
  }
  100% {
    top: -120%;
  }
}
@keyframes move {
  0% {
    top: 120%;
  }
  100% {
    top: -120%;
  }
}
<div class="test"></div>

手写笔来源如下

.test
  position relative
  height 20px
  overflow hidden
.test::before
  position absolute
  top 100%
  content counter(before)
  animation beforeCount 10s linear infinite, move 2s  linear infinite
.test::after
  position absolute
  top 100%
  content counter(after)
  animation afterCount 10s -0.1s linear infinite, move 2s 1s  linear infinite

@keyframes beforeCount
  for i in (0..9)
    {10% * i}
      counter-increment before (i * 10)

@keyframes afterCount
  for i in (0..9)
    {10% * i}
      counter-increment after (i * 10)
@keyframes move
      0%
        top 120%
      100%
        top -120%