How to make this shape use only css
What I have tried:
In case you prefer your border method more than SVG or gradients, here is an approach using just border-radius, the pseudo element ::after and some positioning:
.shape,
.shape::after {
position: absolute;
border-radius: 100%;
}
.shape {
height: 200px;
width: 200px;
border: 100px solid transparent;
border-top: 100px solid #375c89;
}
.shape::after {
content: '';
height: 190px;
width: 198px;
top: -95px;
left: -89px;
border: 90px solid transparent;
border-top: 90px solid #4f81bc;
}
<div class="shape"></div>
You can create this shape in two steps.
Step 1: Create a doughnut segment using border-radius: 100%
to give it a circle like shape. Then apply a color only to the top border and make the other borders transparent. This way you get a circle segment. Now give your element a width
and a height
greater than 0 to transform the circle into a doughnut.
Step 2: Apply the same styles to the pseudo element ::after
but giving it a slightly less width
,height
and border width. Adjust the values for your needs. Now position both elements with position: absolute
to adjust the position of the overlapping pseudo element to center it properly over the main element.
height
and width
overflow: hidden;
::after
elementYou can as well use both pseudo elements ::before
and ::after
to create the shape and easily adjust the position with sizing and margin (thanks to Temani for pointing this out in the comments):
.shape {
position: relative;
width: 400px;
height: 400px;
}
.shape::before,
.shape::after {
content: '';
position: absolute;
border-radius: 100%;
right: 0;
left: 0;
bottom: 0;
top: 0;
}
.shape:before {
border: 100px solid transparent;
border-top-color: #375c89;
}
.shape::after {
margin: 5px 12px;
border: 90px solid transparent;
border-top-color: #4f81bc;
height: 45%;
}
<div class="shape"></div>
I would go with some linear/radial-gradient
like this:
.box {
width:200px;
height:200px;
border-radius:50%;
background:
linear-gradient(-30deg, white 50%,transparent 50.5%),
linear-gradient(30deg, white 50%,transparent 50.5%),
radial-gradient(farthest-side at center,transparent 40%,blue 41%);
}
<div class="box">
</div>
And with border:
.box {
width:200px;
height:200px;
border-radius:50%;
background:
linear-gradient(to top,white 58.5%,transparent 60%),
linear-gradient(-30deg, white calc(50% - 4px),green calc(50% - 4px) 50%,transparent 0),
linear-gradient(30deg, white calc(50% - 4px),green calc(50% - 4px) 50%,transparent 0),
radial-gradient(farthest-side at center,
transparent calc(42% - 5px),
green calc(42% - 4px) 42%,
blue 42% calc(100% - 4px),green calc(100% - 3px));
}
<div class="box">
</div>
You can also consider SVG which can be easier:
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64' width='300' height='300' fill='blue'>
<path stroke="green" stroke-width=1 d='M24 32 C28 28 37 28 40 32 L52 22 C38 8 26 8 12 22 Z' />
</svg>
Here is another Idea with clip-path
:
.box {
width:200px;
height:200px;
border-radius:50%;
background:
radial-gradient(farthest-side at center,transparent 40%,blue 41%);
clip-path: polygon(0 0,0 10%, 50% 50%, 100% 10%,100% 0);
}
<div class="box">
</div>
Related question: CSS Only Pie Chart - How to add spacing/padding between slices?