Css-only倒计时不能保持数字一起工作

时间:2017-04-24 06:12:20

标签: css

我正在尝试构建一个只能倒计时的可编程css。几十分之一的工作正常,但有些工作并不像我预期的那样有效。

*:after{
	animation-direction: reverse;
	animation-iteration-count: infinite;
	-webkit-animation-timing-function: linear; /* Safari 4.0 - 8.0 */
  animation-timing-function: linear;
}
.secondsTen:after{
	content:'';
	animation-name: tenBased;
	animation-duration: 10s;
}

.secondsSix:after{
	content:'';
	animation-name: sixBased;
	animation-duration: 60s;
}

@keyframes tenBased {
	0% { content: '0';}
	10% { content: '1';}
	20% { content: '2';}
	30% { content: '3';}
	40% { content: '4';}
	50% { content: '5';}
	60% { content: '6';}
	70% { content: '7';}
	80% { content: '8';}
	90% { content: '9';}
	100% { content: '0';}
}

@keyframes sixBased {
  0% {content: '0';}
  16.66667% {content: '1';}
  33.33333% {content: '2';}
  50% {content: '3';}
  66.66667% {content: '4';}
  83.33333% {content: '5';}
  100% {content: '0';}
}
<span class='secondsSix'></span>
<span class='secondsTen'></span>

正如你所看到的,其中的第二个在5秒后逐渐减少。但它应该在10秒后减少到5。

2 个答案:

答案 0 :(得分:2)

观察到的行为的说明

关键帧动画执行给定状态之间的转换。在您的示例中,您可以设置伪元素的content属性的值的动画,该属性完全有效,但您必须记住,在这种情况下,两个关键帧之间没有可视化的中间步骤。

事实上,从100% {content: '0';}83.33333% {content: '5';}的转换将在10秒后(如预期的那样)结束,但在某个时间点属性的值会发生变化。当设置animation-timing-function: linear;时,它恰好在两个关键帧之间 - 在这个例子中5秒后,它看起来像是以延迟开始。

*:after{
  animation-direction: reverse;
  animation-iteration-count: infinite;
  -webkit-animation-timing-function: linear; /* Safari 4.0 - 8.0 */
  animation-timing-function: linear;
}

.secondsSix:after{
  content:'';
  animation-name: sixBased;
  animation-duration: 60s;
  position: absolute;
}

@keyframes sixBased {
  0% {content: '0'; left: 100%}
  16.66667% {content: '1';}
  33.33333% {content: '2';}
  50% {content: '3';}
  66.66667% {content: '4';}
  83.33333% {content: '5';}
  100% {content: '0'; left: 0%}
}

.timeline {
  border: solid grey;
  border-width: 1px 0;
  background: white;
  position: absolute;
  width: 100%;
  left: 0;
  top: 2em;
}

.timeline span {
  display: inline-block;
  float: left;
  margin-right: 8.33%;
  width: 0;
}
<div class='secondsSix'></div>
<div class='timeline'>
  <span>0</span><span>5</span><span>10</span><span>15</span><span>20</span><span>25</span>
  <span>30</span><span>35</span><span>40</span><span>45</span><span>50</span><span>55</span>
</div>

我已经在上面的代码片段的帮助下分析了行为,并看看如果我删除单个关键帧会发生什么(一次一个,由下表中的间隙表示)。

Content 0   5   4   3   2   1   0
Time    0   5   15  25  35  45  55
Time    0       10  25  35  45  55
Time    0   5       20  35  45  55
Time    0   5   15      30  45  55 // change from '4' to '2' at second 30
Time    0   5   15  25      40  55
Time    0   5   15  25  35      50

正如您所看到的,内容总是在两个给定的关键帧之间完全改变。 在我修改你的tenBase动画的下面的演示中也可以看到同样的结果:

*:after {
  animation-direction: reverse;
  animation-iteration-count: infinite;
  -webkit-animation-timing-function: linear; /* Safari 4.0 - 8.0 */
  animation-timing-function: linear;
  animation-duration: 10s;
}

.secondsTen:after {
  content: '';
  animation-name: tenBased;
}

.secondsTenTwoSteps:after {
  content: '';
  animation-name: tenBasedTwoSteps;
}

@keyframes tenBased {
  0% { content: '0' }
  10% { content: '1'; }
  20% { content: '2'; }
  30% { content: '3'; }
  40% { content: '4'; }
  50% { content: '5'; }
  60% { content: '6'; }
  70% { content: '7'; }
  80% { content: '8'; }
  90% { content: '9'; }
  100% { content: '10' }
}

@keyframes tenBasedTwoSteps {
  0% { content: '0' }
  100% { content: '10' }
}
<div class='secondsTen'></div>
<div class='secondsTenTwoSteps'></div>

解决方案#1

解决问题的第一种方法很简单,但不是很漂亮。您想要的是change a property in a CSS animation abruptly without animating以及OP在链接问题中描述为 hacky way 的内容如下所示:

*:after{
  animation-direction: reverse;
  animation-iteration-count: infinite;
  -webkit-animation-timing-function: linear; /* Safari 4.0 - 8.0 */
  animation-timing-function: linear;
}

.secondsSix:after{
  content:'';
  animation-name: sixBased;
  animation-duration: 60s;
  position: absolute;
}

@keyframes sixBased {
  0% {content: '0'; left: 100%}
  0.1% {content: '0';}
  16.66667% {content: '1';}
  16.7% {content: '1';}
  33.3% {content: '2';}
  33.33333% {content: '2';}
  33.4% {content: '3';}
  50% {content: '3';}
  50.1% {content: '4';}
  66.66667% {content: '4';}
  66.7% {content: '5';}
  83.33333% {content: '5';}
  83.4% {content: '0';}
  100% {content: '0'; left: 0%}
}

.timeline {
  border: solid grey;
  border-width: 1px 0;
  background: white;
  position: absolute;
  width: 100%;
  left: 0;
  top: 2em;
}

.timeline span {
  display: inline-block;
  float: left;
  margin-right: 8.33%;
  width: 0;
}
<div class='secondsSix'></div>
<div class='timeline'>
  <span>0</span><span>5</span><span>10</span><span>15</span><span>20</span><span>25</span>
  <span>30</span><span>35</span><span>40</span><span>45</span><span>50</span><span>55</span>
</div>

解决方案#2

还有另一种解决方案。您会看到将animation-timing-function: linear;更改为animation-timing-function: ease-out;等其他内容会更改内容实际更改的时间点。我们观察到当使用线性计时功能时,内容在中间完全改变,因此我假设它将在两个关键帧之间的50%进度上发生变化。

由于允许定义cubic-bezier,我们可以将这个时间点转移到接近结束的50%的进度。请记住,您的动画方向是相反的,因此您必须镜像曲线(请参阅cubic-bezier.com/#0,1,0,1)。

*:after{
  animation-direction: reverse;
  animation-iteration-count: infinite;
  -webkit-animation-timing-function: linear; /* Safari 4.0 - 8.0 */
}

.secondsSix:after{
  content:'';
  animation-name: sixBased;
  animation-duration: 60s;
  position: absolute;
}

@keyframes sixBased {
  0% {content: '0'; left: 100%}
  16.66667% {content: '1'; animation-timing-function: cubic-bezier(0,1,0,1);}
  33.33333% {content: '2'; animation-timing-function: cubic-bezier(0,1,0,1);}
  50% {content: '3'; animation-timing-function: cubic-bezier(0,1,0,1);}
  66.66667% {content: '4'; animation-timing-function: cubic-bezier(0,1,0,1);}
  83.33333% {content: '5'; animation-timing-function: cubic-bezier(0,1,0,1);}
  100% {content: '0'; left: 0%}
}

.timeline {
  border: solid grey;
  border-width: 1px 0;
  background: white;
  position: absolute;
  width: 100%;
  left: 0;
  top: 2em;
}

.timeline span {
  display: inline-block;
  float: left;
  margin-right: 8.33%;
  width: 0;
}
<div class='secondsSix'></div>
<div class='timeline'>
  <span>0</span><span>5</span><span>10</span><span>15</span><span>20</span><span>25</span>
  <span>30</span><span>35</span><span>40</span><span>45</span><span>50</span><span>55</span>
</div>

答案 1 :(得分:0)

你想试试吗

.secondsTen:before {
    content: '9876543210';
    width:1ch;
    overflow:hidden;
    animation:tenBased 10s steps(10) infinite;
    float:left;
}
.secondsSix:before{
    content: '543210';
    width:1ch;
    overflow:hidden;
    float:left;
    animation:sixBased 60s steps(6) infinite;
}
@keyframes tenBased {
    0% {text-indent:0}
    100% {text-indent:-10ch;}
}
@keyframes sixBased {
    0% {text-indent:0}
    100% {text-indent:-6ch;}
}
<span class='secondsSix'></span>
<span class='secondsTen'></span>