创建充满渐变的半圆图表

Creating half circle chart filled with gradient

我设法创建了带边框的简单图表。我想将简单的 border-color 更改为渐变。我试图使用 border-imagebackground 属性,但似乎不可能将其弯曲以适合拱形一个容器。 有什么方法可以在 css3 中实现这种效果吗?

HTML

<div class="pie">
    <span class="overlay"></span>
</div>

CSS

.pie {
    margin: 0 auto;
    position: relative;
    width: 116px;
    height: 58px;
    overflow: hidden;
}

.pie *,
.pie::before {
    box-sizing: border-box;
}

.pie::before {
    content: '';
    width: inherit;
    height: inherit;
    border: 20px solid grey;
    border-bottom: none;
    border-top-left-radius: 175px;
    border-top-right-radius: 175px;
    position: absolute;
    left:0;
}

.pie .overlay{
    position: absolute;
    top: 100%;
    left: 0;
    width: inherit;
    height: inherit;
    border: 20px solid;
    border-top: none;
    border-bottom-left-radius: 175px;
    border-bottom-right-radius: 175px;
    transform-origin: 50% 0;
    border-color:yellow;/* background: linear-gradient(to right, rgba(228,232,7,1) 0%, rgba(0,218,156,1) 100%); */
    transform: rotate(90deg); 
}

您可以在 .pie(一个 ::after)上添加一个额外的伪元素,将它们定位为在其左上角和右上角重叠,将它们都弯曲,然后使用 background 为渐变。

然后,将 span 定位在 .pie 的中心,并给它一个白色背景(相对于透明)和更高的 z-index 以确保中心电弧保持完好。

div {
  width: 200px;
  height: 200px;
  position: relative;
}
div::before {
  content: "";
  display: block;
  position: absolute;
  top: 0;
  background: linear-gradient(to right, azure, slategray);
  width: 100px;
  height: 100px;
  left: 0;
  border-top-left-radius: 100px;
}
div::after {
  content: "";
  display: block;
  position: absolute;
  top: 0;
  background: linear-gradient(to right, midnightblue, steelblue);
  width: 100px;
  height: 100px;
  right: 0;
  border-top-right-radius: 100px;
}
div span {
  display: block;
  position: absolute;
  left: calc(50% - 50px);
  top: calc(50% - 50px);
  background: white;
  width: 100px;
  height: 100px;
  border-radius: 50%;
  z-index: 1;
}
<div>
  <span></span>
</div>

您可以使用 2 个渐变,内部遮盖外部:

.test {
    width: 200px;
    height: 100px;
    background-image: linear-gradient(white, white), linear-gradient(to left, red, green);
    background-clip: padding-box, border-box;
    background-origin: padding-box, border-box; 
    border: solid 50px transparent;
    border-radius: 200px 200px 0px 0px;
    border-width: 50px 50px 0px 50px;
}
    
<div class="test"></div>

.test {
    width: 200px;
    height: 100px;
    background-image: linear-gradient(white, white);
    background-clip: content-box;
    background-origin: content-box; 
    border: solid 50px transparent;
    border-radius: 200px 200px 0px 0px;
    padding: 50px 50px 0px 50px;
    position: relative;
    overflow: hidden;
}

.test:after {
    content: "";
    position: absolute;
    left: -25%;
    top: -50%;
    right: 0px;
    height: 300%;
    width: 150%;
    background-image: linear-gradient(to left, red, green);
    transform: rotate(0deg);
    transform-origin: center center;
    z-index: -1;
    animation: spin 3s infinite;
}

@keyframes spin {
    from {transform: rotate(0deg);}
    to {transform: rotate(360deg);}
}
<div class="test"></div>

如果你用pie的伪和overlay作为白色中心,你可以这样做

.pie {
    margin: 0 auto;
    position: relative;
    width: 200px;
    height: 100px;
    border-radius: 200px 200px 0 0;
    overflow: hidden;
}
.pie::after {
    transform: rotate(-60deg);      /*  set rotation degree  */
    background: linear-gradient(to right, rgba(228,232,7,1) 0%, rgba(0,218,156,1) 100%);
    transform-origin: center bottom;
}
.pie::before {
    border: 20px solid grey;
}
.pie .overlay{
    top: 20px;                      /*  match border width  */
    left: 20px;                     /*  match border width  */
    width: calc(100% - 40px);       /*  match border width times 2  */
    height: calc(200% - 40px);      /*  match border width times 2  */
    border-radius: 100%;
    background: white;
    z-index: 1;                     /*  move it on top of the pseudo elements  */
}
.pie *,
.pie::before,
.pie::after {
    content: '';
    position: absolute;
    left: 0;
    top: 0;
    height: 100%;
    width: 100%;
    border-radius: inherit;
    box-sizing: border-box;
}
<div class="pie">
    <span class="overlay"></span>
</div>