You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过CSS ::before伪元素实现0-360度旋转渐变覆盖动画?

问题定义

我有一个设置了border-radius: 50%的div标签,用来显示圆形,相关代码如下:

.pie-wrapper {
  height: 2.5em;
  width: 2.5em;
  margin: 15px auto;
  position: relative;
}

.pie-wrapper--solid {
  border-radius: 50%;
  overflow: hidden;
}

.pie-wrapper--solid:before {
  border-radius: 0 100% 100% 0 / 50%;
  content: "";
  display: block;
  height: 100%;
  margin-left: 50%;
  transform-origin: left;
}

.pie-wrapper--solid.progress-88 {
  border: 5px ridge blue;
  background: linear-gradient(to right, springgreen 50%, #ff0000 50%);
}

.pie-wrapper--solid.progress-88:before {
  background: springgreen;
  transform: rotate(0deg);
  animation-name: change-color;
  animation-duration: 5s;
  animation-timing-function: linear;
  animation-fill-mode: forwards;
  animation-iteration-count: 1;
  animation-direction: normal;
}


/* Keyframes */

@keyframes change-color {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(180deg);
  }
}
<div class="pie-wrapper pie-wrapper--solid progress-88">
</div>
已尝试方案

我用linear-gradient创建了双色背景,还试过to left、to bottom、to top等不同的渐变方向,但都没达到预期效果。

期望效果

当前动画可以正常旋转到180度,但旋转角度超过180度时,没法按预期覆盖饼图区域。我的目标是在keyframes里设置rotate(360deg),让红色部分完全覆盖绿色部分,形成完整的红色圆形;同时希望动画可以逆时针旋转(可以通过rotate函数里的负值实现)。

解决方案

当前的实现仅靠单个伪元素旋转无法支持超过180度的完整覆盖,因为伪元素仅占容器右半部分。可以通过调整背景色切换和伪元素的动画逻辑来实现需求:

顺时针实现(最终全红)

修改后的CSS代码如下:

.pie-wrapper {
  height: 2.5em;
  width: 2.5em;
  margin: 15px auto;
  position: relative;
}

.pie-wrapper--solid {
  border-radius: 50%;
  overflow: hidden;
  border: 5px ridge blue;
  /* 初始背景:左绿右红 */
  background: linear-gradient(to right, springgreen 50%, #ff0000 50%);
}

.pie-wrapper--solid:before {
  border-radius: 0 100% 100% 0 / 50%;
  content: "";
  display: block;
  height: 100%;
  margin-left: 50%;
  transform-origin: left;
  background: springgreen;
  transform: rotate(0deg);
  animation-name: fill-red;
  animation-duration: 5s;
  animation-timing-function: linear;
  animation-fill-mode: forwards;
}

@keyframes fill-red {
  0% {
    transform: rotate(0deg);
    background: springgreen;
  }
  /* 旋转180度时,伪元素完全覆盖左半绿色,此时整体全红 */
  50% {
    transform: rotate(180deg);
    background: springgreen;
  }
  /* 切换伪元素颜色为红色,避免后续旋转露出绿色 */
  50.1% {
    background: #ff0000;
  }
  /* 继续旋转到360度,保持全红状态 */
  100% {
    transform: rotate(360deg);
    background: #ff0000;
  }
}

逆时针实现(最终全红)

添加反向动画的CSS代码:

.pie-wrapper--solid.reverse:before {
  animation-name: fill-red-reverse;
}

@keyframes fill-red-reverse {
  0% {
    transform: rotate(0deg);
    background: springgreen;
  }
  50% {
    transform: rotate(-180deg);
    background: springgreen;
  }
  50.1% {
    background: #ff0000;
  }
  100% {
    transform: rotate(-360deg);
    background: #ff0000;
  }
}

对应的HTML使用方式:

<!-- 顺时针版本 -->
<div class="pie-wrapper pie-wrapper--solid progress-88"></div>

<!-- 逆时针版本 -->
<div class="pie-wrapper pie-wrapper--solid progress-88 reverse"></div>

逻辑说明

  • 0-50%动画阶段:伪元素旋转180度(顺时针/逆时针),逐步覆盖容器左半部分的绿色,到50%节点时完全覆盖,整体呈现全红色。
  • 50.1%-100%阶段:将伪元素颜色切换为红色,继续旋转至360度,确保动画结束后保持全红色,不会因伪元素回转而露出绿色。

内容的提问来源于stack exchange,提问作者Tawanda Andrew Msengezi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 12:32:16