如何在CSS中绘制圆形扇形?

89

嗯,使用纯CSS绘制圆形很容易。

.circle {
    width: 100px;
    height: 100px;
    border-radius: 100px;
    border: 3px solid black;
    background-color: green;
}
如何绘制一个扇形?给定度数X [0-360],我想要绘制一个X度的扇形。我能用纯CSS做到吗?
例如: 图像描述 感谢Jonathan,我使用了第一种方法。如果对某人有帮助,这里是一个获取百分比并绘制扇形的JQuery函数示例。该扇形位于百分比圆圈后面,此示例显示如何从起始角度绕圆圈绘制弧线。
$(function drawSector() {
  var activeBorder = $("#activeBorder");
  var prec = activeBorder.children().children().text();
  if (prec > 100)
    prec = 100;
  var deg = prec * 3.6;
  if (deg <= 180) {
    activeBorder.css('background-image', 'linear-gradient(' + (90 + deg) + 'deg, transparent 50%, #A2ECFB 50%),linear-gradient(90deg, #A2ECFB 50%, transparent 50%)');
  } else {
    activeBorder.css('background-image', 'linear-gradient(' + (deg - 90) + 'deg, transparent 50%, #39B4CC 50%),linear-gradient(90deg, #A2ECFB 50%, transparent 50%)');
  }

  var startDeg = $("#startDeg").attr("class");
  activeBorder.css('transform', 'rotate(' + startDeg + 'deg)');
  $("#circle").css('transform', 'rotate(' + (-startDeg) + 'deg)');
});
.container {
  width: 110px;
  height: 110px;
  margin: 100px auto;
}

.prec {
  top: 30px;
  position: relative;
  font-size: 30px;
}

.prec:after {
  content: '%';
}

.circle {
  position: relative;
  top: 5px;
  left: 5px;
  text-align: center;
  width: 100px;
  height: 100px;
  border-radius: 100%;
  background-color: #E6F4F7;
}

.active-border {
  position: relative;
  text-align: center;
  width: 110px;
  height: 110px;
  border-radius: 100%;
  background-color: #39B4CC;
  background-image: linear-gradient(91deg, transparent 50%, #A2ECFB 50%), linear-gradient(90deg, #A2ECFB 50%, transparent 50%);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>

<div class="container">
  <div id="activeBorder" class="active-border">
    <div id="circle" class="circle">
      <span class="prec">66</span>
      <span id="startDeg" class="90"></span>
    </div>
  </div>
</div>

JSFiddle演示

$(function drawSector() {
    // Get degrees
    ...
    // Draw a sector
    if (deg <= 180) {
        activeBorder.css('background-image', 'linear-gradient(' + (90+deg) + 'deg, transparent 50%, #A2ECFB 50%), linear-gradient(90deg, #A2ECFB 50%, transparent 50%)');
    }
    else {
        activeBorder.css('background-image', 'linear-gradient(' + (deg-90) + 'deg, transparent 50%, #39B4CC 50%), linear-gradient(90deg, #A2ECFB 50%, transparent 50%)');
    }

    // Rotate to meet the start degree
    activeBorder.css('transform','rotate(' + startDeg + 'deg)');
});
15个回答

191

CSS和多重背景渐变

与其尝试绘制绿色部分,不如绘制白色部分:

pie {
    border-radius: 50%;
    background-color: green;
}

.ten {
    background-image:
        /* 10% = 126deg = 90 + ( 360 * .1 ) */
        linear-gradient(126deg, transparent 50%, white 50%),
        linear-gradient(90deg, white 50%, transparent 50%);
}

pie {
  width: 5em;
  height: 5em;
  display: block;
  border-radius: 50%;
  background-color: green;
  border: 2px solid green;
  float: left;
  margin: 1em;
}

.ten {
  background-image: linear-gradient(126deg, transparent 50%, white 50%), linear-gradient(90deg, white 50%, transparent 50%);
}

.twentyfive {
  background-image: linear-gradient(180deg, transparent 50%, white 50%), linear-gradient(90deg, white 50%, transparent 50%);
}

.fifty {
  background-image: linear-gradient(90deg, white 50%, transparent 50%);
}


/* Slices greater than 50% require first gradient
   to be transparent -> green */

.seventyfive {
  background-image: linear-gradient(180deg, transparent 50%, green 50%), linear-gradient(90deg, white 50%, transparent 50%);
}

.onehundred {
  background-image: none;
}
<pie class="ten"></pie>
<pie class="twentyfive"></pie>
<pie class="fifty"></pie>
<pie class="seventyfive"></pie>
<pie class="onehundred"></pie>

演示: http://jsfiddle.net/jonathansampson/7PtEm/

图片描述在这里

可缩放矢量图形

如果可以的话,您可以使用SVG<circle><path>元素来实现类似的效果。请考虑以下内容:

<svg>
  <circle cx="115" cy="115" r="110"></circle>
  <path d="M115,115 L115,5 A110,110 1 0,1 190,35 z"></path>
</svg>

以上内容相当简单。我们有一个包含圆和路径的元素。圆心位于115x115处(使SVG元素为230x230)。圆的半径为110,总宽度为220(留下10个边框)。

然后,我们添加了一个<path>元素,这是本例中最复杂的部分。该元素有一个属性确定路径的绘制位置和方式。它以以下值开始:

M115,115

这指示了路径从前面提到的圆形中心开始。接下来,我们从这个位置画一条线到下一个位置:

L115,5

这将从圆心向上绘制一条垂直线,直到元素的顶部(距离顶部5个像素)。在这一点上,事情变得有些复杂,但仍然很容易理解。

现在,我们从当前位置(115,5)开始绘制一个弧线:

A110,110 1 0,1 190,35 z

这将创建我们的弧,并使其半径与圆的半径(110)相匹配。这两个值表示x半径和y半径,由于我们处理的是一个圆形,因此两者相等。下一组重要数字是最后的190,35,它告诉弧线在哪里结束。

至于其他信息(1 0,1z),它们控制弧线本身的曲率、方向和终端。您可以通过查阅任何在线SVG路径参考了解更多信息。

要完成不同大小的“切片”,只需更改190,35以反映更大或更小的坐标集。如果您想跨越超过180度,可能需要创建第二个弧线。

如果您想从角度确定x和y坐标,可以使用以下公式:

x = cx + r * cos(a)
y = cy + r * sin(a)

使用上述示例,76度将为:

x = 115 + 110 * cos(76)
y = 115 + 110 * sin(76)

这给我们带来了205.676,177.272

您可以轻松创建以下内容:

circle {
  fill: #f1f1f1;
  stroke: green;
  stroke-width: 5;
}

path {
  fill: green;
}

svg.pie {
  width: 230px;
  height: 230px;
}
<svg class="pie">
  <circle cx="115" cy="115" r="110"></circle>
  <path d="M115,115 L115,5 A110,110 1 0,1 190,35 z"></path>
</svg>

<svg class="pie">
  <circle cx="115" cy="115" r="110"></circle>
  <path d="M115,115 L115,5 A110,110 1 0,1 225,115 z"></path>
</svg>

<svg class="pie">
  <circle cx="115" cy="115" r="110"></circle>
  <path d="M115,115 L115,5 A110,110 1 0,1 115,225 A110,110 1 0,1 35,190 z"></path>
</svg>

演示: http://jsfiddle.net/jonathansampson/tYaVW/

enter image description here


4
很棒的回答!非常详细。需要注意的是,如果您想要饼图未使用部分的背景透明,则必须使用SVG方法。 - Neil Monroe
4
@JonathanSampson,它对我非常有帮助...希望我能再点赞10次。谢谢 :) - codingrose
2
这里有一个提示:添加一些变换 pie { transform: rotate(-90deg) } 可以使计算更容易。 - Endless
CSS的解决方案非常好。我在我的jQuery插件中使用它:https://github.com/jorunkel/jquery.article-progress(请参见实时演示)。 - jor
1
应该是cos(76 * pi / 180)和sin(76 * pi / 180)吧?76度是以下内容,您必须从右侧开始:141.611408516,221.7325298904 https://www.dropbox.com/s/l9450gji5424hp9/Screenshot%202018-02-11%2000.48.49.png?dl=0 - Intellix
显示剩余4条评论

39

使用overflowtransform属性很容易实现,无需进行复杂的计算。

> 旋转变换

对于小于180度的角度

  1. 添加一个具有宽高比为2:1overflow:hidden;的元素。

  2. 添加一个伪元素,其上边框半径与元素的高度相同,下边框半径为0。

  3. 设置transform-origin: 50% 100%;。这会从伪元素的中间底部进行变形。

  4. 用所需角度的补角旋转伪元素,即transform: rotate(180 - rqrd. angle);

看看它是如何工作的:

enter image description here

例如:
使用此方法创建40度扇形:Fiddle

div {
  ...
  overflow: hidden;
  ...
}
div:before {
  ...
  border-radius: 100px 100px 0 0;
  transform-origin: 50% 100%;
  transform: rotate(140deg);
  ...
}

div {
  height: 100px;
  width: 200px;
  overflow: hidden;
  position: relative;
}
div:before {
  height: inherit;
  width: inherit;
  position: absolute;
  content: "";
  border-radius: 100px 100px 0 0;
  background-color: crimson;
  -webkit-transform-origin: 50% 100%;
  -moz-transform-origin: 50% 100%;
  -ms-transform-origin: 50% 100%;
  transform-origin: 50% 100%;
  -webkit-transform: rotate(140deg);
  -moz-transform: rotate(140deg);
  -ms-transform: rotate(140deg);
  transform: rotate(140deg);
}
<div></div>

> 倾斜变换

您也可以在扇形内部放置图像!

这可以通过对父元素进行倾斜变换和对伪元素进行负倾斜来实现:
Fiddle

div {
    ...
    overflow: hidden;
    transform-origin: 0% 100%;
    transform: skew(-50deg);  /*Complement of rqrd angle*/
    ...
}
div:before {
    ...
    transform-origin: 0% 100%;
    transform: skew(50deg);
    ...
}

看看这是如何工作的:

enter image description here

div {
  height: 200px;
  width: 200px;
  overflow: hidden;
  -webkit-transform-origin: 0% 100%;
  -moz-transform-origin: 0% 100%;
  -ms-transform-origin: 0% 100%;
  transform-origin: 0% 100%;
  -webkit-transform: skew(-50deg);
  -moz-transform: skew(-50deg);
  -ms-transform: skew(-50deg);
  transform: skew(-50deg); /*Complement of rqrd angle or (90 - angle)*/
  position: relative;
}
div:before {
  height: inherit;
  width: inherit;
  position: absolute;
  content: "";
  border-radius: 0 200px 0 0;
  background: url('http://www.placekitten.com/g/300/200/');
  -webkit-transform-origin: 0% 100%;
  -moz-transform-origin: 0% 100%;
  -ms-transform-origin: 0% 100%;
  transform-origin: 0% 100%;
  -webkit-transform: skew(50deg);
  -moz-transform: skew(50deg);
  -ms-transform: skew(50deg);
  transform: skew(50deg);
}
<div></div>


致谢:我不想自己把功劳揽到手,所以我使用了之前我在这里这里使用过的思路。


这个GIF非常漂亮,你能告诉我你是如何制作这种GIF的吗? - James
我能够翻转这个半圆,因此现在我可以用它来实现360度饼图视图:https://jsfiddle.net/4kho8q3b/30/ - winwin

21

这是否有帮助?

.circle {
  width: 16em;
  height: 16em;
  border-radius: 50%;
  background: linear-gradient(36deg, #272b66 42.34%, transparent 42.34%) 0 0;
  background-repeat: no-repeat;
  background-size: 50% 50%;
}
<div class="circle"></div>

可运行的示例

实际上,这里需要进行一些几何计算。但是让我简单地解释一下:

考虑圆中的4个象限,可以在每个象限计算线性渐变的角度。而background-position决定了所在的象限:

Q I   =>  100% 0
Q II  =>  100% 100%
Q III =>  0    100%
Q IV  =>  0    0

唯一需要留意的是,使用了color-stop的颜色位置:

考虑一个圆的第1象限内的30度夹角的部分。

如天才的Ana Tudor在她的优秀文章中所解释的那样,如果我们把正方形的宽度长度设为a,则半对角线的长度将是a*sqrt(2)/2

如果我们把渐变角度设为g,渐变和对角线两个角度之间的差值设为d,则可以通过以下公式计算color-stop的长度:

a*sin(g) / (a*sqrt(2)/2 * cos(d))
= sin(g) / (sqrt(2)  /2 * cos(d)) 

因此,在这种情况下我们有 sin(30deg) / (sqrt(2)*cos((45-30)deg)) = 0.3660,并且颜色停止的 % 值为 36.60%

由于我们的形状在第一象限,所以 background-position100% 0

线性渐变将是这样

linear-gradient(-30deg, orange 36.60%, transparent 36.60%) 100% 0;

.circle {
  width: 16em;
  height: 16em;
  border-radius: 50%;
  background: linear-gradient(-30deg, orange 36.60%, transparent 36.60%) 100% 0;
  background-repeat: no-repeat;
  background-size: 50% 50%;
}
<div class="circle"></div>

我建议阅读Ana的文章以获取更多细节。


我不确定我理解这个解决方案。如果我想将度数设置为236怎么办?如果我将36度的值更改为236度,它不会产生预期的结果。 - Itay Gal
@ItayGal 你可能想读一下Ana Tudor的这篇精彩文章 - Lars Beck
当我尝试在120度时使用这个方程式时,它无法工作。你能给我一个在120度下的例子方程式吗? - grvpanchal
虽然我在实际工作中没有用到它,但数学真是太棒了... - James

12
  1. 您需要画一个圆
  2. 使用clip-path剪切扇形(需要进行一些数学计算)

您可以在这里玩弄clip-path

这里有一个演示:

#skills {
  position: relative;
  width: 300px;
  height: 300px;
  margin: 30px auto;
}

.circle {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  position: absolute;
}

.animate {
  -webkit-transition: 0.2s cubic-bezier(.74,1.13,.83,1.2);
  -moz-transition: 0.2s cubic-bezier(.74,1.13,.83,1.2);
  -o-transition: 0.2s cubic-bezier(.74,1.13,.83,1.2);
  transition: 0.2s cubic-bezier(.74,1.13,.83,1.2);
}

.animate:hover {
  transform: scale(1.1);
  transform-origin: center center;
}

#part1 {
  background-color: #E64C65;
  -webkit-clip-path: polygon(50% 0, 50% 50%, 100% 41.2%, 100% 0);
  clip-path: polygon(50% 0, 50% 50%, 100% 41.2%, 100% 0);
}

#part2 {
  background-color: #11A8AB;
  -webkit-clip-path: polygon(50% 50%, 100% 41.2%, 100% 100%, 63.4% 100%);
  clip-path: polygon(50% 50%, 100% 41.2%, 100% 100%, 63.4% 100%);
}

#part3 {
  background-color: #4FC4F6;
  -webkit-clip-path: polygon(50% 50%, 36.6% 100%, 63.4% 100%);
  clip-path: polygon(50% 50%, 36.6% 100%, 63.4% 100%);
}

#part4 {
  background-color: #FFED0D;
  -webkit-clip-path: polygon(50% 50%, 0 100%, 36.6% 100%);
  clip-path: polygon(50% 50%, 0 100%, 36.6% 100%);
}

#part5 {
  background-color: #F46FDA;
  -webkit-clip-path: polygon(50% 50%, 0 36.6%, 0 100%);
  clip-path: polygon(50% 50%, 0 36.6%, 0 100%);
}

#part6 {
  background-color: #15BFCC;
  -webkit-clip-path: polygon(50% 50%, 0 36.6%, 0 0, 50% 0);
  clip-path: polygon(50% 50%, 0 36.6%, 0 0, 50% 0);
}
<div id="skills">
  <div id="part1" class="circle animate"></div>
  <div id="part2" class="circle animate"></div>
  <div id="part3" class="circle animate"></div>
  <div id="part4" class="circle animate"></div>
  <div id="part5" class="circle animate"></div>
  <div id="part6" class="circle animate"></div>
</div>


它在Chrome浏览器上可以工作,但在Firefox浏览器和其他浏览器上无法工作。有什么想法吗? - karthi
@karthi Firefox仅支持在SVG中定义的路径clip-path。因此,您可以使用SVG作为解决方法。至于IE,除了使用图像外,我不知道有更好的解决方案。 - Guangming Mao
你能给我一个SVG的例子吗?我不知道如何在SVG中更改你的代码。 - karthi
@karthi 我现在手头上没有例子,但你可以查看https://dev59.com/cVsX5IYBdhLWcg3wcPEF 以获取一个例子。 - Guangming Mao
使用clip-path是一个好主意。或者,您可以在相同的位置创建多边形并旋转元素。 - Jp_

8

由于我没有找到任何满意的答案,我不得不跪下来,使用clip-path函数和整个星期天的CSS才终于得到我想要的结果。

您可以选择起始角度和结束角度,然后元素将漂亮地绘制出来,仅此而已。您只需要使用border-radius解决方案来绘制基础圆形。

我的解决方案使用了四个多边形的网格,每个多边形提供了可能的起点或终点,分别为0-90°和0-100%,90-180°和0-100%等,共享中心点,因此有两倍的4个线段。您可以将机械结构想象成一个带有多个部分的望远镜杆,每个部分都从0到N执行其分段作业。由于机械结构的缘故,同时在代码中保持一定的清晰度(0-90,90-180 ..),我不得不手动旋转(-45deg)div,以便0°== 12''。

这里是一个小草图,可能会说明我是如何做到的:

schema

请注意,您不能将其用于任何商业目的,因为我没有在网上找到任何解决方案,因此需要一些价值。请尊重这一点。


使用CSS绘制圆形段由C.Schaefer根据Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License许可。

            <script src="http://code.jquery.com/jquery-latest.js"></script>

<style type="text/css">
    .circle{
        position: absolute;
        top: 100px;

        width: 600px;
        height: 600px;
        border-radius: 50%;
        background-color: #FFFF00;
        opacity: .9;

        -webkit-transform: rotate(45deg);

}

<script type="text/javaScript">

    var obj;
    var start, end;
    function rangeStart(val) {
        obj =  $("body").find(".circle");
        start = val;
        setAngle(obj, start, end);
    }

    function rangeEnd(val) {
        obj =  $("body").find(".circle");
        end = val;
        setAngle(obj, start, end);
    }

    function applyMasking(obj) {
        obj.css("-webkit-clip-path", ptsToString());
    }

    // not working for degree start to be lower than end, hence, we set the interface to automatically adapt to that exception:
    /*
    function checkForRangeExceptions() {
        if(end < start) {
            $("body").find("input[name='rangeLower']").val($("body").find("input[name='rangeUpper']").val());
            $("body").find("input[name='rangeLower']").slider('refresh');
        }
    }
    */

    // setInterval(doit, 200);

    var angie = 0;
    function doit() {
        obj =  $("body").find(".circle");
        if(angie < 360)
            angie+=15;
        else angie = 0;
        setAngle(obj, 0, angie);
    }


    function ptsToString() {
        var str = "";
        str+="polygon(";
        for(var i=0; i < pts.length; i++) {
            str+=pts[i].x+"% ";
            if(i != pts.length-1)
                str+=pts[i].y+"% ,";
            else str+=pts[i].y+"%";
        }
        str+=")";
        return str;
    }

    /*
    gets passed an html element and sets its clip-path according to the passed angle,
    starting at 0°; note that from a clock perspective, we start at +45° and hence have 
    to add that value to passed angles later on:
    */
    var pts = 
    [
     {x: 50, y: 50}, {x: 0, y: 0}, {x: 0, y: 0},
     {x: 0, y: 0}, {x: 0, y: 0}, {x: 0, y: 0},
     {x: 0, y: 0}, {x: 0, y: 0}, {x: 0, y: 0}
    ];
    var lb, ub;
    var sa, ea;
    function setAngle(obj, start, end) {
        // if no start, set 0° as default:
        start = (start == undefined ? start = 0 : start);

        // find out upper and lower sector bounds: 
        lb = (angleToSector(start) * 2) - 1;
        ub = angleToSector(end) * 2;

        // find start end end angles:
        sa = mapAngleToPoint(start);
        ea = mapAngleToPoint(end); 

        // now set points except start point which is 0:
        for(var i=1; i < pts.length; i++) {

            // set all below lb to lb:
            if(i <= lb) { pts[i].x = sa.x; pts[i].y = sa.y; }

            // set all in between to max values:
            else if(i > lb && i < ub) {
                pts[i] = setMax(i);
            }

            // set all above ub to ub:
            else if(i >= ub) { pts[i].x = ea.x; pts[i].y = ea.y; }

        }

        // apply masking:
        applyMasking(obj);

    }

    // assuming that 100 need to map 90°:
    function angleToPerc(angle) {
        return angle * (100/90);
    }

    function lowerBound(angle) {
        return (mapAngleToSector(angle));
    }

    function uppperBound(angle){
        return (mapAngleToSector(angle));           
    }

    // sectors 1-4
    function angleToSector(angle) {
            if      (angle >= 0   && angle < 90)  return 1;
            else if (angle >= 90  && angle < 180) return 2;
            else if (angle >= 180 && angle < 270) return 3;
            else if (angle >= 270 && angle <= 360) return 4;
    }

    // this maps the passed angle to a coordinate value:
    var as;
    function mapAngleToPoint(angle) {
            var pt = {x: 0, y: 0};
            as = angleToSector(angle);
            if(as == 1)       {pt.x = angleToPerc(angle); pt.y = 0; }
            else if(as == 2)  {pt.x = 100; pt.y = angleToPerc(angle-90)}
            else if(as == 3)  {pt.x = 100-angleToPerc(angle-180); pt.y = 100; }
            else if(as == 4)  {pt.x = 0; pt.y = 100-angleToPerc(angle-270); }
            return pt;
    }

    // set a point to its max by index:
    function setMax(index) {
        var pt = {x: 0, y: 0};
        if      (index == 1 || index == 2) { pt.x = 100; pt.y = 0; }
        else if (index == 3 || index == 4) { pt.x = 100; pt.y = 100; }
        else if (index == 5 || index == 6) { pt.x = 0; pt.y = 100; }
        else if (index == 7 || index == 8) { pt.x = 0; pt.y = 0; }
        return pt;
    }

</script>

</head>

<body>

    <div class="circle">

    </div>

    <input type="range" name="rangeLower" value="0" min="0" max="360" onchange="rangeStart(this.value);">
    <input type="range" name="rangeUpper" value="66"min="0" max="360" onchange="rangeEnd(this.value);">


</body>


8

2022更新:我正在编写纯CSS和最简单的解决方案Conic Gradient

尝试以下简短代码:

 .piechart {
            display: block;
            width: 100px;
            height: 100px;
            border-radius: 50%;

            /* add sector degree here,
               multiple colors for muptiple sectors */

            background-image: conic-gradient(
                pink 135deg, 
                transparent 0); 
}
<div class="piechart"></div>

注意:如果您想使用百分比值进行支持,则在 135 度的位置,可以简单地使用 x * 360/100 或简写为 (x * 3.6) 度,其中 x 是百分比。


3
很好,看起来已经得到广泛支持了。 - Itay Gal
1
@ItayGal 是的,它很简单。我有一个%加载器的用例,所以只需要将百分比乘以3.6即可得到度数。 - minigeek
很遗憾,它没有抗锯齿效果。 - jeyko

7
我有另一种解决方案。

#pie {
  position: relative;
  width: 100px;
  height: 100px;
  background-color: #76dd76;
  border-radius: 50%;
  border: 1px solid #76dd76;
}

#pie:before,
#pie:after {
  position: absolute;
  content: "";
  display: block;
  width: 50%;
  height: 50%;
  -webkit-transform-origin: right bottom;
  -moz-transform-origin: right bottom;
  -ms-transform-origin: right bottom;
  transform-origin: right bottom;
  background-color: white;
  border-top-left-radius: 100%;
}

#pie:after {
  -webkit-transform: rotate(45deg);
  -moz-transform: rotate(45deg);
  -ms-transform: rotate(45deg);
  transform: rotate(45deg);
}
<div id="pie"></div>

演示: http://jsfiddle.net/F6qz9/


这个方法可以用于半个饼图。如果您需要完整的范围,可以将此技术添加到饼图元素中以获取另外两个伪元素样式。 - Neil Monroe

6

这里的所有答案都非常有创意。人们如何以许多方式解决同一个问题,真是令人惊叹。Sampson所提供的被接受的答案确实很棒,但我不知道他为什么决定绘制白色部分而不是绿色部分,因此我想分享一个修改后可以绘制绿色部分的版本。我认为这样更加直观,所以如果其他人也发现这个修改版本有用,我就分享出来。

pie {
    width: 5em;
    height: 5em;
    display: block;
    border-radius: 50%;
    border: 2px solid green;
    float: left;
    margin: 1em;
}

.ten {
    background-image:
      linear-gradient(-54deg, white 50%, transparent 50%),
      linear-gradient(-90deg, green 50%, transparent 50%);
}

.twentyfive {
    background-image:
      linear-gradient(0deg, white 50%, transparent 50%),
      linear-gradient(-90deg, green 50%, transparent 50%);
}

.fifty {
    background-image:
      linear-gradient(-90deg, green 50%, transparent 50%);
}

/* Slices greater than 50% require first gradient to be green -> transparent */

.seventyfive {
    background-image:
      linear-gradient(0deg, green 50%, transparent 50%),
      linear-gradient(-90deg, green 50%, transparent 50%);
}

.onehundred {
    background-color: green;
}
<pie class="ten"></pie>
<pie class="twentyfive"></pie>
<pie class="fifty"></pie>
<pie class="seventyfive"></pie>
<pie class="onehundred"></pie>


5

看这个,可以得到解决问题的想法。

<div class="circle"></div>

.circle{
    width: 100px;
    height: 100px;
    background-color: green;
    border-radius: 100px;
    position: relative;
}

.circle:before,
.circle:after {
    border: 50px solid white;
    border-color: transparent transparent white white;
    border-radius: 100px;
    content: '';
    height: 0;
    position: absolute;
    top: 0;
    left: 0;
    width: 0;
    /* this is to have it white from 180 to 360 degrees on the left side */
    transform:rotate(45deg);
    -ms-transform:rotate(45deg); /* IE 9 */
    -webkit-transform:rotate(45deg); /* Safari and Chrome */
}

/* the green sector is now 180 minus 45 plus 0 degree */
.circle:after {
    transform:rotate(0deg);
    -ms-transform:rotate(0deg); /* IE 9 */
    -webkit-transform:rotate(0deg); /* Safari and Chrome */
}

/* the green sector is now 180 minus 45 plus -75 degree */
/*.circle:after {
    transform:rotate(-75deg);
    -ms-transform:rotate(-75deg);
    -webkit-transform:rotate(-75deg);
}*/

Demo


1
不错的技巧伙计!但是有一点 - 你不能创建角度小于45度的透明扇区;) 你肯定可以创建隐藏扇区。 - The Pragmatick

5
您可以使用带虚线的圆圈。
<svg viewBox="-8 -8 16 16">
  <circle
    cx="0"
    cy="0"
    r="4"
    transform="rotate(270)"
    stroke-width="8"
    stroke-dasharray="4, 26"
    stroke="green"
    fill="none"
  />
</svg>
  • 将线条的粗细设置为圆的半径的两倍,这样它就可以延伸到圆心。
  • 通过调整stroke-dasharray的值来确定所需的饼图大小。

额外加分:使用圆而不是路径的优点在于,当更改饼图大小时,您可以轻松地对其进行动画处理:只需将类似transition: stroke-dasharray .5s;的内容添加到圆的css中即可。


1
这个实际上可以节省很多麻烦 :) - Andreas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接