Create a Semicircle Chart Filled with a Gradient
I was able to create a simple chart with a border. I would like to change the simple border-color to a gradient. I tried to use the border-image or background property , but there seems to be no way to shout it out so that it can fit the arched shape of the container. Is there a way to achieve this effect in 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);
}
source to share
If you are using an alias pie
and overlay
as a white center, you can do it like this:
.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>
source to share
You can play with two gradients, inner masking outer:
.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>
source to share
You can add an extra pseudo element on .pie
(a ::after
), place them as overlapping at the top left and top right corners, align both of them and use background
for the gradient.
Then span
center it .pie
and give it a white background (as opposed to transparent) with a taller z-index
one to make sure the center of the arc stays in beat.
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>
source to share