进度元素中的伪选择器上的背景位置动画的解决方法

时间:2019-04-29 15:28:37

标签: html css css3

我有一个不确定的进度栏:

<progress max="100"></progress>

我已将其设置为带有45度条纹的绿色背景:

progress {
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  border: none;
}

progress:not([value])::-webkit-progress-bar {
  background-image:
    -webkit-linear-gradient(-45deg, transparent 33%, rgba(0, 0, 0, 0.2) 33%, rgba(0, 0, 0, 0.2) 66%, transparent 66%),
    -webkit-linear-gradient(#b3ee3a, #b3ee3a);
  background-size: 2.5em 1.25em, 100% 100%, 100% 100%;
  background-position: 10%;
  animation-name: stripes;
  animation-duration: 2s;
  animation-iteration-count: infinite;
}

@keyframes stripes {
  from {background-position: 0%}
  to {background-position: 100%}
}

(完整示例:https://jsfiddle.net/w9x7sm6c/4/

不幸的是,动画无法正常工作。该问题似乎源于Chrome的错误/功能:

https://bugs.chromium.org/p/chromium/issues/detail?id=486195

  

将其关闭为WontFix。

     

原因:@keyframes规则名称是作用域,因此指定的名称仅可用   在同一个Treescope中(即在同一个文档或影子根目录中)。   progress ::-webkit-progress-value刺穿文档-UA影子根边界   并设置元素的样式,但在文档树形结构中定义的动画名称   在UA阴影根目录中不可用,因此动画不适用。

     

...

     

一种解决方法是制作您自己的小部件并对其进行动画处理,这应该   所有的浏览器(如果实现了CSS动画)都可以使用。

在我看来,建议的解决方法是不使用<progress>,这对我来说似乎是不好的建议。我宁愿使用正确的语义元素,也不愿发明具有相同功能的东西。

我可以使用任何变通办法来使进度条处于不确定状态吗?

1 个答案:

答案 0 :(得分:1)

您可以考虑使用通用的伪元素来创建它。

body {
  background: #333;
}

progress {
  display: block;
  margin-bottom: 1em;
  position:relative;
}

progress {
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  border: none;
}

progress::-webkit-progress-bar {
  background-color: #777;
  border-radius: 0.3em;  
}

progress[value]::-webkit-progress-bar {
  box-shadow: 0 0.3em 0.3em rgba(0,0,0, 0.3) inset;
}

progress::-webkit-progress-value {
  border-radius: 0.3em;
  background-color: #b3ee3a;
}


progress:not([value])::-webkit-progress-bar {
  /* nothing here*/
}
progress:not([value])::before {
  content:"";
  position:absolute;
  top:0;
  left:0;
  right:0;
  bottom:0;
  border-radius: 0.3em; 
  background:
    linear-gradient(-45deg, transparent 33%, rgba(0, 0, 0, 0.2) 33%, rgba(0, 0, 0, 0.2) 66%, transparent 66%) left/2.5em 1.25em,
    #b3ee3a;
  background-position: 10%;
  animation-name: stripes;
  animation-duration: 2s;
  animation-iteration-count: infinite;
}

@keyframes stripes {
  from {background-position: 0%}
  to {background-position: 100%}
}
<progress max="100" value="33"></progress>
<progress max="100" value="50"></progress>
<progress max="100" value="90"></progress>
<progress max="100"></progress>

或者使用JS结合CSS变量和超时来更新值。

以下是显示值更改的基本示例:

function update() {
  document.querySelector('progress:not([value])').style.setProperty("--c", "100%");
}
progress {
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  border: none;
}

progress:not([value])::-webkit-progress-bar {
  background:
    linear-gradient(-45deg, transparent 33%, rgba(0, 0, 0, 0.2) 33%, rgba(0, 0, 0, 0.2) 66%, transparent 66%),
    #b3ee3a;
  background-size: 2.5em 1.25em;
  background-position: var(--c,10%);
  transition:1s all;
}
<progress max="100"></progress>

<button onClick="update()">change</button>