【问题标题】:Pure CSS countdown animation纯 CSS 倒计时动画
【发布时间】:2023-08-19 07:37:01
【问题描述】:

我正在尝试制作纯 HTML/CSS 倒计时动画,但我正在努力使其顺利运行。现在我只介绍分钟和秒。请注意,我使用animation-delay 属性将倒计时重置为某个初始时间。

目前一切正常,除了与 x10 分钟对应的数字未与其余数字同步变化。 接下来我将粘贴我的代码和两个代码笔,第一个正常版本具有正常行为的正确时间,另一个快 10 倍,以便您快速了解问题。

@keyframes tick6 {
        0%      { margin-top: 0; }
        16%     { margin-top: -2rem;  }
        33%     { margin-top: -4rem;  }
        50%     { margin-top: -6rem;  }
        66%     { margin-top: -8rem;  }
        83%     { margin-top: -10rem;  }
        100%    { margin-top: -12rem;  }
    }

    @keyframes tick10 {
        0%      { margin-top: 0; }
        10%     { margin-top: -2rem;  }
        20%     { margin-top: -4rem;  }
        30%     { margin-top: -6rem;  }
        40%     { margin-top: -8rem;  }
        50%     { margin-top: -10rem;  }
        60%     { margin-top: -12rem;  }
        70%     { margin-top: -14rem;  }
        80%     { margin-top: -16rem;  }
        90%     { margin-top: -18rem;  }
        100%    { margin-top: -20rem;  }
    }
    
body {
  background-color: black;
}

.container {
  background-color: white;
}

.digit {
  display: inline-block;
  height: 2rem;
  overflow: hidden;
  width: 1ch;
}

.digit span {
  display: block;
  height: 2rem;
  width: 100%;
}

.minutes-digit-one {
  animation: tick6 3600s step-end;
  animation-iteration-count: infinite;
  animation-delay: -540s;
}

.minutes-digit-two {
  animation: tick10 600s step-end;
  animation-iteration-count: infinite;
  animation-delay: -540s;
}

.seconds-digit-one {
  animation: tick6 60s step-end;
  animation-iteration-count: infinite;
  animation-delay: -540s;
}

.seconds-digit-two {
  animation: tick10 10s;
  animation-iteration-count: infinite;
  animation-delay: -540s;
}
<div class="container">
  <div class="digit">
    <span class="minutes-digit-one">5</span>
    <span>4</span>
    <span>3</span>
    <span>2</span>
    <span>1</span>
    <span>0</span>
    <span>5</span>
  </div>
  <div class="digit">
    <span class="minutes-digit-two">9</span>
    <span>8</span>
    <span>7</span>
    <span>6</span>
    <span>5</span>
    <span>4</span>
    <span>3</span>
    <span>2</span>
    <span>1</span>
    <span>0</span>
    <span>9</span>
  </div>
  <div class="digit">
    <span>:</span>
  </div>
  <div class="digit">
    <span class="seconds-digit-one">5</span>
    <span>4</span>
    <span>3</span>
    <span>2</span>
    <span>1</span>
    <span>0</span>
    <span>5</span>
  </div>
  <div class="digit">
    <span class="seconds-digit-two">9</span>
    <span>8</span>
    <span>7</span>
    <span>6</span>
    <span>5</span>
    <span>4</span>
    <span>3</span>
    <span>2</span>
    <span>1</span>
    <span>0</span>
    <span>9</span>
  </div>
</div>

【问题讨论】:

    标签: html css css-animations keyframe


    【解决方案1】:

    这是由于关键帧的百分比值。您使用的是16%,而应该是16.6667% (100/6) 更准确和准确,与其他值相同。

    当使用360s3600s 作为持续时间时,16%16.6667% 之间会有明显的区别,因此状态会更早发生变化,您将遇到同步问题。使用6s 作为秒数时,您可能不会注意到这一点。

    @keyframes tick6 {  
        0%          { margin-top: 0; }      /* 0*(100/6) */
        16.6667%    { margin-top: -2rem;  } /* 1*(100/6) */
        33.3333%    { margin-top: -4rem;  } /* 2*(100/6) */
        50%         { margin-top: -6rem;  } /* 3*(100/6) */
        66.6667%    { margin-top: -8rem;  } /* 4*(100/6) */
        83.3333%    { margin-top: -10rem; } /* 5*(100/6) */
        100%        { margin-top: -12rem; } /* 6*(100/6) */
    }
    
    @keyframes tick10 {
        0%      { margin-top: 0; }
        10%     { margin-top: -2rem;  }
        20%     { margin-top: -4rem;  }
        30%     { margin-top: -6rem;  }
        40%     { margin-top: -8rem;  }
        50%     { margin-top: -10rem;  }
        60%     { margin-top: -12rem;  }
        70%     { margin-top: -14rem;  }
        80%     { margin-top: -16rem;  }
        90%     { margin-top: -18rem;  }
        100%    { margin-top: -20rem;  }
    }
    
    body {
      background-color: black;
    }
    
    .container {
      background-color: white;
    }
    
    .digit {
      display: inline-block;
      height: 2rem;
      overflow: hidden;
      width: 1ch;
    }
    
    .digit span {
      display: block;
      height: 2rem;
      width: 100%;
    }
    
    .minutes-digit-one {
      animation: tick6 360s infinite step-end;
      /*animation-delay: -54s;*/
    }
    
    .minutes-digit-two {
      animation: tick10 60s infinite step-end;
      /*animation-delay: -54s;*/
    }
    
    .seconds-digit-one {
      animation: tick6 6s infinite step-end;
      /*animation-delay: -54s;*/
    }
    
    .seconds-digit-two {
      animation: tick10 1s infinite step-end;
    }
    <div class="container">
      <div class="digit">
        <span class="minutes-digit-one">5</span>
        <span>4</span>
        <span>3</span>
        <span>2</span>
        <span>1</span>
        <span>0</span>
        <span>5</span>
      </div>
      <div class="digit">
        <span class="minutes-digit-two">9</span>
        <span>8</span>
        <span>7</span>
        <span>6</span>
        <span>5</span>
        <span>4</span>
        <span>3</span>
        <span>2</span>
        <span>1</span>
        <span>0</span>
        <span>9</span>
      </div>
      <div class="digit">
        <span>:</span>
      </div>
      <div class="digit">
        <span class="seconds-digit-one">5</span>
        <span>4</span>
        <span>3</span>
        <span>2</span>
        <span>1</span>
        <span>0</span>
        <span>5</span>
      </div>
      <div class="digit">
        <span class="seconds-digit-two">9</span>
        <span>8</span>
        <span>7</span>
        <span>6</span>
        <span>5</span>
        <span>4</span>
        <span>3</span>
        <span>2</span>
        <span>1</span>
        <span>0</span>
        <span>9</span>
      </div>
    </div>

    【讨论】:

    • 而且,完全清楚的是,16.6667 在技术上是关闭的。 技术上它是 16.6666(无限重复),但我不确定这种差异会导致长期差异
    • @cale_b 在数学上是 16.6666(重复),更准确地说是 100/6,就像我在答案中描述的那样,但在现实世界中 16.666...% 与 16.6667% 相同,一切都是近似的; ) 除非我们处理涉及更多计算的非常特殊的情况,否则我们的感知不会计算出那么小的差异
    • @cale_b 对于这种情况,我们不会有长期差异,因为持续时间固定为 360 秒,因此循环将每 360 秒重复一次。如果对第一个有利,那么对第二个有利,依此类推...如果持续时间不准确,我们可能会遇到问题,这可能会产生差异