我找到了非常漂亮的“百分比饼图”,并希望仅使用 CSS 创建它。无需动画。只需静态“图片”。我明白如果我想创建这种图表,我需要使用元素...
我找到了非常漂亮的“百分比饼图”,并想仅使用 CSS 创建它。无需动画。只需静态“图片”。
我明白如果我想创建这种图表,我需要使用类似这样的元素
问题是
由于您没有提到这一点:除了 CSS,这应该仅限于 HTML 还是 SVG 也是一个选项?
利用现代技术,我们可以改进代码。你可以使用圆边,也可以考虑动画:
@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>
您还可以在我的网站上找到渐变色的版本: https://css-shape.com/arc/
@property --p{
syntax: '<number>';
inherits: true;
initial-value: 1;
}
.pie {
--p:20; /* the percentage */
--b:22px; /* the thickness */
--c:linear-gradient(darkred,blue); /* the color */
--w:150px; /* the size*/
width: var(--w);
aspect-ratio: 1;
position: relative;
display: inline-grid;
margin: 5px;
place-content:center;
font-size:25px;
font-weight:bold;
font-family:sans-serif;
}
.pie:before {
content:"";
position: absolute;
inset:0;
background:red;
padding: var(--b);
box-sizing: border-box;
border-radius: 50%;
background: var(--c);
mask:
linear-gradient(#0000 0 0) content-box intersect,
conic-gradient(#000 calc(var(--p)*1%),#0000 0);
}
.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:#eee;
}
<div class="pie" style="--p:20"> 20%</div>
<div class="pie" style="--p:40;--c:linear-gradient(45deg,red,yellow);--b:10px"> 40%</div>
<div class="pie" style="--p:60;--c:purple;--b:15px"> 60%</div>
<div class="pie animate" style="--p:80;--c:linear-gradient(45deg,orange,pink);"> 80%</div>
<div class="pie animate" style="--p:90;--c:conic-gradient(lightgreen,green)"> 90%</div>
旧答案
您可以使用多个背景来完成此操作。
从 0%
至 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>
从 50%
至 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>
您可以像这样将两者结合起来:
.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>
现在我们可以像下面这样进行优化来考虑百分比值:
.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>
获取另一个版本的相关问题: 使用 CSS 创建静态饼图
我们还可以考虑 mask
增加透明度:
.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>
也像下面这样:
.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>
相关: 带边框半径的边框渐变
谢谢,看起来不错。但是如何使用两种颜色?例如,如第一张图片所示,蓝色表示已使用,灰色表示未使用?
使用新的 圆锥渐变 ,可以通过一个刚刚作为实验属性登陆 Chrome 的 div 来进行管理。
结果图片
:root {
--size: 100px;
--bord: 10px;
}
.chart {
width: var(--size);
height: var(--size);
margin: 1em auto;
border-radius: 50%;
background-image: conic-gradient(lightseagreen var(--value), lightgrey var(--value));
position: relative;
display: flex;
justify-content: center;
align-items: center;
}
.chart::after {
content: "";
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: calc(100% - var(--bord));
height: calc(100% - var(--bord));
background: white;
border-radius: inherit;
}
p {
position: relative;
z-index: 1;
font-size: 2em;
}
.x-60 {
--value: 60%;
}
.x-20 {
--value: 20%;
}
<div class="chart x-60">
<p>60%</p>
</div>
<div class="chart x-20">
<p>20%</p>
</div>
感谢 Temani Afif,我们可以不使用伪元素、使用边框并利用 background-clip
...
background:
linear-gradient(white,white) padding-box,
conic-gradient(lightseagreen var(--value), lightgrey var(--value)) border-box;
:root {
--size: 100px;
--bord: 10px;
}
.chart {
width: var(--size);
height: var(--size);
margin: 1em auto;
border: var(--bord) solid transparent;
border-radius: 50%;
background: linear-gradient(white, white) padding-box, conic-gradient(lightseagreen var(--value), lightgrey var(--value)) border-box;
position: relative;
display: flex;
justify-content: center;
align-items: center;
font-size: 2em;
}
.x-60 {
--value: 60%;
}
.x-20 {
--value: 20%;
}
<div class="chart x-60">
<p>60%</p>
</div>
<div class="chart x-20">
<p>20%</p>
</div>
嘿,gus,你可以添加一些小的 CSS 样式
.circle {
position: relative;
top: 5px;
left: 5px;
text-align: center;
width: 100px;
height: 100px;
border-radius: 100%;
background-color: #ffffff;
}
.circle-border {
position: relative;
text-align: center;
width: 110px;
height: 110px;
margin-left: 30%;
border-radius: 100%;
background-color: #E53B3B;
background: linear-gradient(0deg, lightgray 100%, black 0%)
}
HTML
<div class="circle-border" id="circleElement">
<div class="circle" id="circleElementValue">
aaa
</div>
</div>
JS : 自动显示填充百分比
// let i = 75;
// let deg=Math.round(1.8*i);
// let completed=0;
// let remaining=100-i;
// // completed = (remaining>50)? 50 : completed;
// let backgroundStlye = 'linear-gradient('+deg+'deg, lightgray '+remaining +'%, black '+completed + '%)';
// setTimeout(function(){
// console.log(backgroundStlye);
// document.getElementById("circleElement").style.background =backgroundStlye;
// },i*100);
for(let i=1;i<=100;i++){
let deg=Math.round(1.8*i);
let completed=i;
let remaining=100-i;
completed = (remaining<50)? 0 : completed;
let backgroundStlye = 'linear-gradient('+deg+'deg, lightgray '+remaining +'%, black '+completed + '%)';
setTimeout(function(){
console.log(backgroundStlye);
document.getElementById("circleElement").style.background =backgroundStlye;
document.getElementById("circleElementValue").innerHTML = i+'%';
},i*100);
}
我创建了示例 https://codepen.io/arun-b-shet/pen/mdVVWXo
希望你喜欢