0

0

CSS如何制作环形统计图表?conic-gradient渐变应用

看不見的法師

看不見的法師

发布时间:2025-08-04 17:04:01

|

757人浏览过

|

来源于php中文网

原创

要使用conic-gradient制作环形统计图表,1. 首先创建一个正方形元素并设置border-radius: 50%使其变为圆形;2. 利用conic-gradient的色标(color stops)按百分比或角度定义每个数据段的起止范围,实现扇形分区;3. 通过累加百分比确保扇区连续,可结合css变量提升灵活性;4. 添加中心孔洞的方法包括:使用border属性形成实色孔洞、通过伪元素覆盖中心区域(推荐,灵活且兼容性好)、或使用mask-image配合radial-gradient实现透明孔洞;5. 动态数据可通过javascript计算各段百分比并更新css变量或直接设置background值;6. 可访问性方面需提供role="img"、aria-labelledby、aria-describedby等属性,并辅以隐藏的表格或文本描述数据内容,同时确保图例为可读文本。该方案实现了纯css驱动的环形图,兼具视觉效果与功能完整性。

CSS如何制作环形统计图表?conic-gradient渐变应用

conic-gradient
是CSS中一个非常强大的工具,它能让我们在不依赖SVG或Canvas的情况下,直接用CSS实现环形统计图表。它的核心在于能够创建沿着中心点旋转的颜色渐变,这完美契合了饼图或环形图的扇形结构,使得纯CSS绘制这类图表成为可能,而且通常代码量很小。

解决方案

要用

conic-gradient
制作环形统计图表,核心思路是利用其颜色停止点(color stops)来定义每个数据段的起始和结束角度。想象一下一个圆心,颜色从某个角度开始,沿着圆周顺时针或逆时针扩散,直到遇到下一个颜色停止点。

一个基础的环形图,比如一个饼图,通常需要一个正方形的容器,并将其

border-radius
设置为50%使其变成圆形。然后,关键就在于它的
background
属性:

立即学习前端免费学习笔记(深入)”;

.pie-chart {
    width: 200px;
    height: 200px;
    border-radius: 50%;
    /* 假设数据:A占30%,B占50%,C占20% */
    background: conic-gradient(
        #ff6347 0% 30%,    /* A: 从0%到30%(即0度到108度)是红色 */
        #4682b4 30% 80%,    /* B: 从30%到80%(即108度到288度)是蓝色 */
        #3cb371 80% 100%    /* C: 从80%到100%(即288度到360度)是绿色 */
    );
}

这里,

conic-gradient
的参数是颜色和角度范围。每个颜色后面可以跟两个百分比或角度值。第一个值是该颜色开始的角度,第二个是结束的角度。如果只给一个值,比如
#ff6347 30%
,那么它表示该颜色在30%处达到纯色,然后平滑过渡到下一个颜色。但对于统计图表,我们通常需要颜色之间有明确的界限,所以使用两个百分比(或角度)来定义一个实心的扇形区域。

默认情况下,

conic-gradient
从顶部中心(12点钟方向)开始,并顺时针绘制。如果你想改变起始位置,可以使用
from 
,例如
from 90deg
会从3点钟方向开始。如果你想改变中心点,可以使用
at  
,但对于标准的饼图,通常不需要修改。

如何精确控制
conic-gradient
的扇区比例和颜色?

精确控制扇区比例和颜色,是制作可信统计图的关键。我个人觉得,理解百分比和角度的换算,是玩转

conic-gradient
的第一步。一个完整的圆是360度,或者说是100%。所以,如果你有一个数据点占总量的X%,那么它对应的角度就是
X% * 3.6deg

conic-gradient
中,我们可以直接使用百分比来定义角度,这非常方便,因为数据通常就是以百分比形式存在的。

/* 假设我们有以下数据:
   - 产品A: 25%
   - 产品B: 40%
   - 产品C: 15%
   - 产品D: 20%
*/
.data-chart {
    width: 250px;
    height: 250px;
    border-radius: 50%;
    /* 可以使用CSS变量来动态控制,更灵活 */
    --pA: 25%;
    --pB: 40%;
    --pC: 15%;
    --pD: 20%;

    background: conic-gradient(
        #a8e6cf 0% var(--pA),                               /* A: 从0%到25% */
        #dcedc1 var(--pA) calc(var(--pA) + var(--pB)),      /* B: 从25%到25%+40%=65% */
        #ffd3b6 calc(var(--pA) + var(--pB)) calc(var(--pA) + var(--pB) + var(--pC)), /* C: 从65%到65%+15%=80% */
        #ffaaa5 calc(var(--pA) + var(--pB) + var(--pC)) 100% /* D: 从80%到100% */
    );
}

这里我用了CSS自定义属性(变量),这在处理动态数据时尤其有用。通过JavaScript改变这些变量的值,图表就能立即更新,无需重新渲染整个DOM。注意看,每个扇区的起始点都是前一个扇区的结束点。这种累加的方式确保了扇区之间紧密连接,不会出现缝隙。

颜色选择上,除了常见的十六进制或RGB值,你也可以使用

hsl()
hsla()
,它们在调整颜色饱和度和亮度时更直观,有时能帮助你快速找到和谐的配色方案。

conic-gradient
环形图中添加中心孔洞(甜甜圈效果)有哪些方法?

制作一个甜甜圈(donut)图,也就是在饼图中间挖个洞,有几种常见的CSS技巧。我个人比较喜欢用伪元素或

mask-image
,它们能提供更灵活的控制,但最直接的可能还是
border

  1. 利用

    border
    属性(最简单但限制多): 这是最直接粗暴的方式。给你的圆形容器添加一个足够粗的
    border
    ,并让
    border-color
    与背景色(或你想让孔洞呈现的颜色)相同。
    conic-gradient
    会填充元素的背景区域,而
    border
    则会覆盖在背景之上,形成一个环形。

    .donut-chart-border {
        width: 200px;
        height: 200px;
        border-radius: 50%;
        border: 40px solid #fff; /* 孔洞的颜色和大小 */
        background: conic-gradient(#ff6347 0% 30%, #4682b4 30% 80%, #3cb371 80% 100%);
        /* background-clip: padding-box; /* 确保渐变只在内容区域显示,但这里不加也行 */
    }

    缺点是孔洞的颜色必须是实色,且不能是透明的,因为它是边框色。

  2. 利用伪元素(常用且灵活): 这是我比较推荐的方法。在饼图容器内部创建一个伪元素(

    ::before
    ::after
    ),让它也成为一个圆形,并将其定位在容器的中心,颜色设置为你想要的孔洞色。

    .donut-chart-pseudo {
        position: relative; /* 为伪元素定位提供参考 */
        width: 200px;
        height: 200px;
        border-radius: 50%;
        background: conic-gradient(#ff6347 0% 30%, #4682b4 30% 80%, #3cb371 80% 100%);
    }
    
    .donut-chart-pseudo::before {
        content: '';
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%); /* 居中 */
        width: 100px; /* 孔洞大小 */
        height: 100px; /* 孔洞大小 */
        border-radius: 50%;
        background-color: #fff; /* 孔洞的颜色 */
        z-index: 1; /* 确保在渐变之上 */
    }

    这种方法的好处是孔洞颜色可以独立控制,甚至可以是透明的(如果背景是其他元素)。

    ONLYOFFICE
    ONLYOFFICE

    用ONLYOFFICE管理你的网络私人办公室

    下载
  3. 利用

    mask-image
    (最强大但兼容性略差):
    mask-image
    属性允许你用一个图像(可以是渐变)来遮罩元素。我们可以创建一个
    radial-gradient
    来作为遮罩,中心是透明的,外部是不透明的。

    .donut-chart-mask {
        width: 200px;
        height: 200px;
        border-radius: 50%;
        background: conic-gradient(#ff6347 0% 30%, #4682b4 30% 80%, #3cb371 80% 100%);
        /* 遮罩:中心透明,外部不透明 */
        mask-image: radial-gradient(circle at center, transparent 0 30%, black 30% 100%);
        -webkit-mask-image: radial-gradient(circle at center, transparent 0 30%, black 30% 100%); /* 兼容性 */
    }

    这里的

    transparent 0 30%
    表示从中心到半径30%的地方是透明的,
    black 30% 100%
    表示从半径30%到100%的地方是黑色的(黑色表示显示,透明表示隐藏)。这种方法非常灵活,可以制作各种异形孔洞,但需要注意浏览器兼容性。

综合来看,伪元素的方法在灵活性和兼容性之间找到了一个很好的平衡点。

如何处理
conic-gradient
环形图的动态数据和可访问性?

用CSS制作的图表,最大的挑战之一就是如何处理动态数据和确保可访问性。毕竟,CSS只是负责渲染,数据逻辑和语义化需要额外处理。

动态数据处理:

对于动态数据,我通常会倾向于使用JavaScript来计算和更新CSS自定义属性。这样,我们就能在不直接操作样式表规则的情况下,灵活地改变图表的呈现。

  1. 数据计算: 假设你从后端获取了一组数据,比如

    [{ label: '销售', value: 30 }, { label: '市场', value: 50 }, { label: '研发', value: 20 }]
    。 首先,你需要计算总和,然后计算每个部分的百分比,并累加得到每个扇区的结束百分比。

    const data = [
        { label: '销售', value: 30, color: '#ff6347' },
        { label: '市场', value: 50, color: '#4682b4' },
        { label: '研发', value: 20, color: '#3cb371' }
    ];
    
    const total = data.reduce((sum, item) => sum + item.value, 0);
    let currentPercentage = 0;
    const gradientSegments = data.map(item => {
        const percentage = (item.value / total) * 100;
        const start = currentPercentage;
        const end = currentPercentage + percentage;
        currentPercentage = end;
        return `${item.color} ${start}% ${end}%`;
    }).join(', ');
    
    const chartElement = document.querySelector('.dynamic-chart');
    chartElement.style.background = `conic-gradient(${gradientSegments})`;
  2. 更新CSS自定义属性: 如果你的图表结构比较固定,只是数据比例变化,用CSS变量会更优雅。

    // HTML: 
    // CSS: background: conic-gradient(var(--c1) 0% var(--p1), var(--c2) var(--p1) var(--p2), var(--c3) var(--p2) var(--p3)); const data = [ /* 同上 */ ]; const total = data.reduce((sum, item) => sum + item.value, 0); let accumulatedPercentage = 0; const chartElement = document.querySelector('.dynamic-chart'); let gradientString = ''; data.forEach((item, index) => { const percentage = (item.value / total) * 100; const start = accumulatedPercentage; const end = accumulatedPercentage + percentage; gradientString += `${item.color} ${start}% ${end}%${index < data.length - 1 ? ',' : ''}`; accumulatedPercentage = end; }); chartElement.style.background = `conic-gradient(${gradientString})`;

    这种方式避免了直接操作复杂的

    conic-gradient
    字符串,而是通过变量间接控制。当然,直接拼接字符串也是完全可行的,取决于你的偏好和项目的复杂性。

可访问性处理:

纯CSS的图表对屏幕阅读器来说是“不可见”的。它只是视觉上的呈现。为了确保所有用户都能理解图表传达的信息,可访问性是不可或缺的。

  1. 提供文本替代方案: 最基本也最重要的是,为图表提供清晰的文本描述或数据表格。屏幕阅读器用户可以通过这些文本内容来理解图表的含义和具体数据。

    
    

    2023年销售额构成

    销售额数据详情
    类别 占比
    产品A 30%
    产品B 50%
    产品C 20%

    这里,我使用了

    role="img"
    来告诉辅助技术这是一个图像,
    aria-labelledby
    aria-describedby
    分别指向图表的标题和详细数据表格。那个
    table
    的样式是经典的“visually hidden”模式,让它在视觉上不可见,但对屏幕阅读器依然可用。

  2. 使用

    aria-label
    aria-valuetext
    (如果每个扇区可交互):
    如果你的图表每个扇区是可点击或有交互的,可以考虑为每个扇区(或其对应的容器)添加
    aria-label
    来描述其数据点。但这对于一个纯CSS绘制的
    conic-gradient
    来说,每个扇区本身没有独立的DOM元素,实现起来会比较复杂。通常,我们会把整个图表视为一个整体,然后提供整体的描述。

  3. 图例和标签: 无论如何,图例(legend)是必不可少的。它将颜色与数据类别关联起来。这些图例本身应该是可访问的文本。

    • 产品A: 30%
    • 产品B: 50%
    • 产品C: 20%

    确保图例中的文本是实际可读的,而不是图片。

总的来说,

conic-gradient
在视觉上提供了极大的便利和创意空间,但作为开发者,我们不能止步于此。动态数据和可访问性是任何前端组件的基石,特别是在数据可视化领域,这需要我们结合JavaScript和语义化的HTML来共同完成。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

298

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

212

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1502

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

624

2023.11.24

java读取文件转成字符串的方法
java读取文件转成字符串的方法

Java8引入了新的文件I/O API,使用java.nio.file.Files类读取文件内容更加方便。对于较旧版本的Java,可以使用java.io.FileReader和java.io.BufferedReader来读取文件。在这些方法中,你需要将文件路径替换为你的实际文件路径,并且可能需要处理可能的IOException异常。想了解更多java的相关内容,可以阅读本专题下面的文章。

633

2024.03.22

php中定义字符串的方式
php中定义字符串的方式

php中定义字符串的方式:单引号;双引号;heredoc语法等等。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

589

2024.04.29

go语言字符串相关教程
go语言字符串相关教程

本专题整合了go语言字符串相关教程,阅读专题下面的文章了解更多详细内容。

172

2025.07.29

c++字符串相关教程
c++字符串相关教程

本专题整合了c++字符串相关教程,阅读专题下面的文章了解更多详细内容。

83

2025.08.07

java入门学习合集
java入门学习合集

本专题整合了java入门学习指南、初学者项目实战、入门到精通等等内容,阅读专题下面的文章了解更多详细学习方法。

1

2026.01.29

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Sass 教程
Sass 教程

共14课时 | 0.8万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 3.1万人学习

CSS教程
CSS教程

共754课时 | 24.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号