仅使用 css 的百分比饼图 [英] Percent pie chart with css only

查看:29
本文介绍了仅使用 css 的百分比饼图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现了非常漂亮的百分比饼图",并且只想用 CSS 创建它.不需要动画.只是静态的图片".

我明白如果我想创建这种图表,我需要使用这些元素

问题是

  1. 如何创建元素#2?
  2. 如何为更小 (5%) 或更高百分比 (80%) 的值管理元素 #2 的形状?

解决方案

New answer 2021

通过一些现代技术,我们可以改进代码.您可以有圆角边缘,也可以考虑动画:

@property --p{语法:'<数字>';继承:真实;初始值:1;}.pie {--p:20;/* 百分比 */--b:22px;/* 厚度 */--c:深红色;/* 颜色 */--w:150px;/* 规模*/宽度:变量(--w);纵横比:1/1;位置:相对;显示:内联网格;边距:5px;地点内容:中心;字体大小:25px;字体粗细:粗体;字体系列:无衬线;}.pie:之前,.pie:在{之后内容:"";位置:绝对;边界半径:50%;}.pie:之前{插图:0;背景:径向梯度(最远侧,var(--c)98%,#0000)顶部/var(--b)var(--b)无重复,圆锥梯度(var(--c) calc(var(--p)*1%),#0000 0);-webkit-mask:radial-gradient(farthest-side,#0000 calc(99% - var(--b)),#000 calc(100% - var(--b)));掩码:径向梯度(最远边,#0000 calc(99% - var(--b)),#000 calc(100% - var(--b)));}.pie:在{之后插图:计算(50% - var(--b)/2);背景:var(--c);变换:旋转(calc(var(--p)*3.6deg - 90deg))translate(calc(var(--w)/2 - 50%));}.animate {动画:p 1s .5s 两者;}.no-round:before {背景尺寸:0 0,自动;}.no-round:after {内容:无;}@关键帧p{来自{--p:0;}}身体 {背景:#ddd;}

20%/div<div class="pie" style="--p:40;--c:darkblue;--b:10px">40%/div<div class="pie no-round" style="--p:60;--c:purple;--b:15px">60%/div<div class="pie animate" style="--p:80;--c:orange;">80%/div<div class="pie animate no-round" style="--p:90;--c:lightgreen">90%

旧答案

您可以使用多个背景来执行此操作.

0%50%:

.box {宽度:100px;高度:100px;显示:内联块;边界半径:50%;填充:5px;背景:线性梯度(#ccc,#ccc)内容框,线性梯度(var(--v),#f2f2f2 50%,透明0),线性渐变(向右,#f2f2f2 50%,蓝色 0);}

<div class="box" style="--v:-90deg"></div><!-- 0% --><div class="box" style="--v:-45deg"></div><!-- 12.5% --><div class="box" style="--v: 0deg"></div><!-- 25% --><div class="box" style="--v: 45deg"></div><!-- 37.5% --><div class="box" style="--v: 90deg"></div><!-- 50% --><p>公式为[p=(18/5)*x-90].<small>其中 x 是百分比,p 是度数</small></p><p>对于 x = 5% -->p = -72deg </p><div class="box" style="--v:-72deg"></div>

50%100%:

.box {宽度:100px;高度:100px;显示:内联块;边界半径:50%;填充:5px;背景:线性梯度(#ccc,#ccc)内容框,线性梯度(var(--v),蓝色50%,透明0),线性渐变(向右,#f2f2f2 50%,蓝色 0);}

<div class="box" style="--v:-90deg"></div><!-- 50% --><div class="box" style="--v:-45deg"></div><!-- 62.5% --><div class="box" style="--v: 0deg"></div><!-- 75% --><div class="box" style="--v: 45deg"></div><!-- 87.5% --><div class="box" style="--v: 90deg"></div><!-- 100% --><p>公式为[p = (18/5) * x - 270].<small>其中 x 是百分比,p 是度数</small></p><p>对于 x = 80% -->p = 18deg </p><div class="box" style="--v:18deg"></div>

你可以像这样组合两者:

.box {宽度:100px;高度:100px;显示:内联块;边界半径:50%;填充:5px;背景:线性梯度(#ccc,#ccc)内容框,线性梯度(var(--v), #f2f2f2 50%,transparent 0) 0/calc(var(--s)*100%) ,线性梯度(var(--v),蓝色50%,透明0) 0/calc((1 - var(--s))*100%),线性渐变(向右,#f2f2f2 50%,蓝色 0);}

<div class="box" style="--v:-90deg;--s:1"></div><div class="box" style="--v:0deg;--s:1"></div><div class="box" style="--v:90deg;--s:1"></div><div class="box" style="--v:0deg;--s:0"></div><div class="box" style="--v:90deg;--s:0"></div>

现在我们可以像下面这样优化以考虑百分比值:

.box {--v:calc(((18/5) * var(--p) - 90)*1deg);宽度:100px;高度:100px;显示:内联块;边界半径:50%;填充:10px;背景:线性梯度(#ccc,#ccc)内容框,线性梯度(var(--v), #f2f2f2 50%,transparent 0) 0/min(100%,(50 - var(--p))*100%),线性梯度(var(--v),透明50%,蓝色0) 0/min(100%,(var(--p) - 50)*100%),线性渐变(向右,#f2f2f2 50%,蓝色 0);}

<div class="box" style="--p:5;"></div><div class="box" style="--p:20;"></div><div class="box" style="--p:50;"></div><div class="box" style="--p:60;"></div><div class="box" style="--p:75;"></div><div class="box" style="--p:100;"></div>

获取另一个版本的相关问题:

也像下面这样:

.box {--v:calc(((18/5) * var(--p) - 90)*1deg);宽度:100px;高度:100px;显示:内联块;边界半径:50%;填充:10px;背景:线性梯度(var(--v),透明50%,蓝色0) 0/min(100%,(var(--p) - 50)*100%),线性渐变(向右,透明 50%,蓝色 0);-webkit-掩码:线性梯度(var(--v), #f2f2f2 50%,transparent 0) 0/min(100%,(50 - var(--p))*100%),线性梯度(#fff 0 0)内容框,线性梯度(#fff 0 0);-webkit-mask-composite:destination-out;面具复合:排除;}身体 {背景:线性渐变(向右,红色,黄色);}

<div class="box" style="--p:5;"></div><div class="box" style="--p:20;"></div><div class="box" style="--p:50;"></div><div class="box" style="--p:60;"></div><div class="box" style="--p:75;"></div><div class="box" style="--p:100;"></div>

相关:带边框半径的边框渐变

I've found pretty nice "percent pie chart" and want to create it with CSS only. No animation is required. Just static "picture".

I understand If I wanna create this kind of chart I need to use elements like these

The questions are

  1. How to create element #2 ?
  2. How to manage shape of element #2 for smaller (5%) or higher percent (80%) values ?

解决方案

New answer 2021

With some modern techniques we can improve the code. You can have rounded edges and also consider animation:

@property --p{
  syntax: '<number>';
  inherits: true;
  initial-value: 1;
}

.pie {
  --p:20;      /* the percentage */
  --b:22px;    /* the thickness */
  --c:darkred; /* the color */
  --w:150px;   /* the size*/
  
  width:var(--w);
  aspect-ratio:1/1;
  position:relative;
  display:inline-grid;
  margin:5px;
  place-content:center;
  font-size:25px;
  font-weight:bold;
  font-family:sans-serif;
}
.pie:before,
.pie:after {
  content:"";
  position:absolute;
  border-radius:50%;
}
.pie:before {
  inset:0;
  background:
    radial-gradient(farthest-side,var(--c) 98%,#0000) top/var(--b) var(--b) no-repeat,
    conic-gradient(var(--c) calc(var(--p)*1%),#0000 0);
  -webkit-mask:radial-gradient(farthest-side,#0000 calc(99% - var(--b)),#000 calc(100% - var(--b)));
          mask:radial-gradient(farthest-side,#0000 calc(99% - var(--b)),#000 calc(100% - var(--b)));
}
.pie:after {
  inset:calc(50% - var(--b)/2);
  background:var(--c);
  transform:rotate(calc(var(--p)*3.6deg - 90deg)) translate(calc(var(--w)/2 - 50%));
}
.animate {
  animation:p 1s .5s both;
}
.no-round:before {
  background-size:0 0,auto;
}
.no-round:after {
  content:none;
}
@keyframes p{
  from{--p:0;}
}

body {
  background:#ddd;
}

<div class="pie" style="--p:20"> 20%</div>
<div class="pie" style="--p:40;--c:darkblue;--b:10px"> 40%</div>
<div class="pie no-round" style="--p:60;--c:purple;--b:15px"> 60%</div>
<div class="pie animate" style="--p:80;--c:orange;"> 80%</div>
<div class="pie animate no-round" style="--p:90;--c:lightgreen"> 90%</div>

Old answer

You can do this with multiple background.

From 0% to 50%:

.box {
  width: 100px;
  height: 100px;
  display: inline-block;
  border-radius: 50%;
  padding: 5px;
  background: 
    linear-gradient(#ccc, #ccc) content-box, 
    linear-gradient(var(--v), #f2f2f2 50%, transparent 0),
    linear-gradient(to right, #f2f2f2 50%, blue 0);
}

<div class="box" style="--v:-90deg"></div><!-- 0% -->
<div class="box" style="--v:-45deg"></div><!-- 12.5% -->
<div class="box" style="--v:  0deg"></div><!-- 25% -->
<div class="box" style="--v: 45deg"></div><!-- 37.5% -->
<div class="box" style="--v: 90deg"></div><!-- 50% -->

<p>The formula is [p = (18/5) * x - 90]. <small>Where x is the percentage and p the degree</small></p>
<p>for x = 5% --> p = -72deg </p>
<div class="box" style="--v:-72deg"></div>

From 50% to 100%:

.box {
  width:100px;
  height:100px;
  display:inline-block;
  border-radius:50%;
  padding:5px;
  background:
    linear-gradient(#ccc,#ccc) content-box,
    linear-gradient(var(--v), blue 50%,transparent 0),
    linear-gradient(to right, #f2f2f2 50%,blue 0);
}

<div class="box" style="--v:-90deg"></div><!-- 50% -->
<div class="box" style="--v:-45deg"></div><!-- 62.5% -->
<div class="box" style="--v:  0deg"></div><!-- 75% -->
<div class="box" style="--v: 45deg"></div><!-- 87.5% -->
<div class="box" style="--v: 90deg"></div><!-- 100% -->

<p>The formula is [p = (18/5) * x - 270]. <small>Where x is the percentage and p the degree</small></p>
<p>for x = 80% --> p = 18deg </p>
<div class="box" style="--v:18deg"></div>

You can combine both like this:

.box {
  width:100px;
  height:100px;
  display:inline-block;
  border-radius:50%;
  padding:5px;
  background:
    linear-gradient(#ccc,#ccc) content-box,
    linear-gradient(var(--v), #f2f2f2 50%,transparent 0) 0/calc(var(--s)*100%)      ,
    linear-gradient(var(--v), blue    50%,transparent 0) 0/calc((1 - var(--s))*100%),
    linear-gradient(to right, #f2f2f2 50%,blue 0);
}

<div class="box" style="--v:-90deg;--s:1"></div>
<div class="box" style="--v:0deg;--s:1"></div>
<div class="box" style="--v:90deg;--s:1"></div>
<div class="box" style="--v:0deg;--s:0"></div>
<div class="box" style="--v:90deg;--s:0"></div>

Now we can optimize like below to consider percetange value:

.box {
  
  --v:calc( ((18/5) * var(--p) - 90)*1deg);

  width:100px;
  height:100px;
  display:inline-block;
  border-radius:50%;
  padding:10px;
  background:
    linear-gradient(#ccc,#ccc) content-box,
    linear-gradient(var(--v), #f2f2f2     50%,transparent 0) 0/min(100%,(50 - var(--p))*100%),
    linear-gradient(var(--v), transparent 50%,blue        0) 0/min(100%,(var(--p) - 50)*100%),
    linear-gradient(to right, #f2f2f2 50%,blue 0);
}

<div class="box" style="--p:5;"></div>
<div class="box" style="--p:20;"></div>
<div class="box" style="--p:50;"></div>
<div class="box" style="--p:60;"></div>
<div class="box" style="--p:75;"></div>
<div class="box" style="--p:100;"></div>

Related question to get another version: Creating a static pie chart with CSS


We can also consider mask to add transparency:

.box {
  
  --v:calc( ((18/5) * var(--p) - 90)*1deg);

  width:100px;
  height:100px;
  display:inline-block;
  border-radius:50%;
  padding:10px;
  background:
    linear-gradient(var(--v), #f2f2f2     50%,transparent 0) 0/min(100%,(50 - var(--p))*100%),
    linear-gradient(var(--v), transparent 50%,blue        0) 0/min(100%,(var(--p) - 50)*100%),
    linear-gradient(to right, #f2f2f2 50%,blue 0);
  -webkit-mask:
    linear-gradient(#fff 0 0) content-box,
    linear-gradient(#fff 0 0);
  -webkit-mask-composite:destination-out;
  mask-composite:exclude;
}

body {
  background:linear-gradient(to right,red,yellow);
}

<div class="box" style="--p:5;"></div>
<div class="box" style="--p:20;"></div>
<div class="box" style="--p:50;"></div>
<div class="box" style="--p:60;"></div>
<div class="box" style="--p:75;"></div>
<div class="box" style="--p:100;"></div>

Also like below:

.box {
  
  --v:calc( ((18/5) * var(--p) - 90)*1deg);

  width:100px;
  height:100px;
  display:inline-block;
  border-radius:50%;
  padding:10px;
  background:
    linear-gradient(var(--v), transparent 50%,blue        0) 0/min(100%,(var(--p) - 50)*100%),
    linear-gradient(to right, transparent 50%,blue 0);
  -webkit-mask:
    linear-gradient(var(--v), #f2f2f2     50%,transparent 0) 0/min(100%,(50 - var(--p))*100%),
    linear-gradient(#fff 0 0) content-box,
    linear-gradient(#fff 0 0);
  -webkit-mask-composite:destination-out;
  mask-composite:exclude;
}

body {
  background:linear-gradient(to right,red,yellow);
}

<div class="box" style="--p:5;"></div>
<div class="box" style="--p:20;"></div>
<div class="box" style="--p:50;"></div>
<div class="box" style="--p:60;"></div>
<div class="box" style="--p:75;"></div>
<div class="box" style="--p:100;"></div>

Related: Border Gradient with Border Radius

这篇关于仅使用 css 的百分比饼图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆