如何创建具有线性渐变的动画圆形进度条?

How to create an animated rounded progress bar with linear gradient?

我只想使用 CSS 创建这样的东西。

更具体地说,我需要一个具有 x% 黄色背景和圆边的 div。这个黄色部分可以在开头、结尾或中间的任何位置,如上图所示。 div 的其余部分应为黑色。

我知道我可以通过将 div 放在另一个内部并设置内部 div 的长度、位置和背景颜色来实现。但我想知道它是否可以通过设置它的背景颜色或背景图像或其他东西只使用一个 div 来完成。使用线性渐变,除了黄色部分的圆边外,我能够实现我想要的所有效果。这是 CSS:

/* this will make the background-color 40% black, 20% yellow, 40% black */
div{
    background-image: linear-gradient(
        90deg,
        black 40%,
        yellow 20%,
        yellow 60,
        black 60%
    );
    background-size: 100% 100%;
    background-repeat: no-repeat;
}

这是代码片段:

#mydiv{
  width: 400px;
  height: 50px;
  background-image: linear-gradient(
        90deg,
        rgb(20, 20, 20) 40%,
        rgb(255, 174, 0) 20%,
        rgb(255, 174, 0) 60%,
        rgb(20, 20, 20) 60%
   );
   background-size: 100% 100%;
   background-repeat: no-repeat;
   border-radius: 25px;
}
<div id="mydiv"></div>

是否可以仅使用一个 div 和 CSS 来实现此目的?

我需要能够控制黄色部分的长度和位置,以便我可以在 CSS 动画中更改它的位置和长度。

动画看起来像这样:

#outer{
  width: 400px;
  height: 20px;
  border-radius: 10px;
  position: relative;
  overflow: hidden;
  background-color: rgb(20, 20, 20);
}

#inner{
  width: 20%;
  height: 100%;
  border-radius: 10px;
  position: absolute;
  left: -20%;
  background-color: rgb(255, 174, 0);
  animation: loading 2s infinite;
}

@keyframes loading{
  0%{
    left: -20%;
  }
  100%{
    left: 100%;
  }
}
<div id="outer">
  <div id="inner"></div>
</div>

为此,需要将 yellow 栏作为一个独立的选择器。

并且使用 css,您可以在 #mydiv 标签内使用 :before 选择器,并将黄色条放置在那里,如下所示。

#mydiv {
  width: 400px;
  height: 50px;
  background-color: black;
  border-radius: 25px;
  position: relative;
}

#mydiv:before {
  content: " ";
  position: absolute;
  top: 0;
  left: 20%;
  width: 40%;
  height: 100%;
  border-radius: 25px;
  background-color: yellow;
}
<div id="mydiv"></div>

可能的梯度解

只需使用 radial-gradient

在线性渐变的开始和结束处添加圆帽

#mydiv{
  width: 400px;
  height: 50px;
  background-color: rgba(20, 20, 20);
  background-image: linear-gradient(
        90deg,
        transparent 25px,
        rgb(255, 174, 0) 25px,
        rgb(255, 174, 0) calc(100% - 25px),
        transparent calc(100% - 25px)
   ), 
    radial-gradient(circle at 25px, rgb(255, 174, 0) 25px, transparent 25px),
    radial-gradient(circle at calc(100% - 25px), rgb(255, 174, 0) 25px, transparent 25px);
   background-size: 50% 100%;
   background-repeat: no-repeat;
   border-radius: 25px;
   
   animation: moving 3s infinite alternate linear;
}

@keyframes moving {
  100% { 
    background-position: 100% 0;
  }
}
<div id="mydiv"></div>

这是一个只有渐变的解决方案:

.mydiv{
  --w:100px; /* width of progress*/
  --h:50px; /* height of the element*/

  height: var(--h);
  box-sizing:border-box;
  margin:5px;
  background: 
    radial-gradient(farthest-side,orange 98%,transparent 100%) 0/var(--h) 100%,
    radial-gradient(farthest-side,orange 98%,transparent 100%) 0/var(--h) 100%,
    linear-gradient(orange,orange) 0/ var(--w) 100%
    black;
  background-repeat: no-repeat;
  border-radius: var(--h);
  animation: a 2s linear infinite;
}
@keyframes a{
  from {
    background-position:
      left calc(-1*var(--w) - var(--h)) top 0,
      left calc(-1*var(--h)) top 0,
      left calc(-1*var(--h)/2 - var(--w)) top 0;
  }
  to {
    background-position:
      right calc(-1*var(--h)) top 0,
      right calc(-1*var(--w) - var(--h)) top 0,
      right calc(-1*var(--h)/2 - var(--w)) top 0;
  }
}
<div class="mydiv"></div>

<div class="mydiv" style="--w:200px;--h:40px;"></div>

<div class="mydiv" style="--w:250px;--h:20px;"></div>

或使用伪元素:

.mydiv {
  --w:100px; /* width of progress*/
  --h:50px; /* height of the element*/
  
  height: var(--h);
  background: black;
  border-radius: var(--h);
  overflow: hidden;
  margin:5px;
}

.mydiv::before {
  content: "";
  display: block;
  position: relative;
  width: var(--w);
  border-radius: inherit;
  height: 100%;
  background: orange;
  animation: a 2s linear infinite;
}

@keyframes a {
  from {
    left: 0;
    transform: translateX(-100%);
  }
  to {
    left: 100%;
    transform: translateX(0);
  }
}
<div class="mydiv"></div>

<div class="mydiv" style="--w:200px;--h:40px;"></div>

<div class="mydiv" style="--w:250px;--h:20px;"></div>