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); 
}

      

+3


source to share


3 answers


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>
      

Run codeHide result


+3


source


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>
      

Run codeHide result




.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>
      

Run codeHide result


+1


source


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>
      

Run codeHide result


0


source







All Articles