前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
首页程序员面试题库CSS conic-gradient 圆环进度条
CSS动画与视觉

怎么用 conic-gradient 做一个圆环进度条?

conic-gradient 沿角度方向铺色,把色标写在同一个角度就能画出硬边扇形。给容器加 border-radius: 50% 裁成圆,再用伪元素或 mask 挖掉中心,就是一个纯 CSS 的圆环进度条。

前端进阶之旅 · 一题精讲更新于 2026.09.29
CSS#动画与视觉#动画
先看核心答案读代码示例
理解线索

圆环进度条的三层结构

  1. 扇形底色conic-gradient 用硬边色标画出已完成和未完成两段扇形
  2. 圆形裁切border-radius: 50% 把正方形容器裁成圆
  3. 中心镂空伪元素盖一个小圆,或用 radial-gradient 做 mask,露出圆环

conic-gradient 的起始角度默认是 12 点方向(from 0deg),和钟表一致,进度条通常不需要改。

核心回答

先记住这个答案

conic-gradient 是沿着圆心角方向铺颜色的渐变。把两个色标写在同一个角度,比如 green 0deg 120deg, #eee 120deg 360deg,就能画出一块绿色扇形和一块灰色扇形,中间是硬边。给容器设 border-radius: 50% 裁成圆形,再用伪元素或 mask 把中心挖空,就得到了圆环进度条。进度值通过 CSS 自定义属性控制,JavaScript 只需要改一个变量。

  • conic-gradient 沿圆心角方向做颜色插值
  • 色标同角度产生硬边,天然适合画扇形和饼图
  • 圆角裁圆,伪元素或 mask 可挖空
  • 自定义属性配合 @property 可驱动动画

最简单的圆环写法

先做一个正方形容器,用 conic-gradient 画扇形,再用伪元素盖一个白色小圆在中心。这是最容易理解的方案,不依赖 mask。

伪元素挖空中心CSS
.ring {
  width: 120px;
  height: 120px;
  border-radius: 50%;
  /* --p 是进度角度,由 JS 设置 */
  background: conic-gradient(#4caf50 0deg var(--p, 90deg), #eee var(--p, 90deg) 360deg);
  position: relative;
}
.ring::after {
  content: '';
  position: absolute;
  inset: 15px;            /* 控制圆环粗细 */
  border-radius: 50%;
  background: #fff;       /* 和页面背景同色 */
}

inset: 15px 决定了圆环的粗细。伪元素的背景色必须和页面背景一致,否则看起来不像镂空。如果背景不是纯色,就得换成 mask 方案。

用 mask 做真正的透明镂空

当页面背景是图片或渐变时,伪元素盖白色就穿帮了。这时用 radial-gradient 做 mask,中心透明、外圈不透明,就能真正镂空。

mask 的写法是 mask: radial-gradient(closest-side, transparent calc(100% - 15px), #000 calc(100% - 15px))。15px 就是圆环宽度。这种方案不需要伪元素,也不依赖背景色,更通用。

不过 Safari 还需要加 -webkit-mask 前缀。如果项目不需要兼容旧版 Safari,直接用无前缀写法就行。

让进度条动起来

conic-gradient 本身不是可插值类型,直接写 transition: background 0.3s 不会有过渡效果。解决办法是把角度值放到 CSS 自定义属性里,然后用 @property 告诉浏览器它是 <angle> 类型。

注册之后,改变 --p 的值就能触发平滑过渡。JavaScript 里只要 element.style.setProperty('--p', '216deg') 就行,CSS 会自动补间。

回答前,多想一步

容易答错的地方

忘了容器必须是正方形
border-radius: 50% 只有在宽高相等时才能裁出正圆。如果容器是长方形,裁出来是椭圆,进度条就变形了。实际项目里用 aspect-ratio: 1 约束一下最稳妥。
伪元素镂空在非纯色背景上穿帮
伪元素方案本质是「盖一个同色圆」,不是真的透明。换了背景就露馅。面试时直接说清楚这个局限性,再提 mask 方案,比只说一种写法要好。
试着用自己的话回答

面试官还会怎么问?

怎么在圆环上加一个圆头端点?

在进度条末端叠一个小圆点。小圆点用绝对定位,通过 transform: rotate(var(--p)) translateY(-半径) 把它放到圆环的边缘上。注意 rotate 要写在 translateY 前面,否则位移方向会错。

不用 conic-gradient 还能怎么做圆环进度条?

用两个半圆 clip 拼接的老方案:左右各一个半圆,通过 rotate 控制露出的角度。写法比 conic-gradient 复杂得多,但兼容性覆盖到 IE。SVG 的 stroke-dasharray 加 stroke-dashoffset 也是常见方案,语义更好,动画也更方便。

conic-gradient 能画饼图吗?

能。多段硬边色标就是多个扇形,每段的角度占比就是数据占比。比如三段数据分别占 40%、35%、25%,色标写 red 0deg 144deg, blue 144deg 270deg, green 270deg 360deg。再加 border-radius: 50% 就是饼图。不过数据动态变化时建议用 SVG 或 Chart 库,纯 CSS 拼接容易出错。

从一道题,走向一组知识

把知识连起来

动画与视觉

关键帧动画里写了 display 这种不可插值的属性,浏览器会怎么处理?

进度条想加动画时会碰到不可插值问题,需要用 @property 注册自定义属性才能让浏览器做过渡。

动画与视觉

transform 里同时写 translate、rotate、scale,顺序不同结果为什么不一样?

圆环上如果要加旋转指示器,transform 函数的书写顺序会直接影响指示器的位置。

参考资料

  • CSS:动画与视觉参考资料

示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。

本题目录
  1. 先记住这个答案
  2. 最简单的圆环写法
  3. 用 mask 做真正的透明镂空
  4. 让进度条动起来
  5. 容易答错的地方
  6. 面试官还会怎么问
  7. 把知识连起来
读懂,再试着讲出来

先看核心答案,再读代码。最后展开追问,检查自己有没有遗漏边界。

试着回答追问
浏览全部面试题理解原理,也关注真实的使用场景。回到顶部 ↑