Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS circle with inlay border

Tags:

css

css-shapes

I'm trying to create a circle in CSS with an inlay border as per the below sample:

inlay circle

I have the following HTML and CSS, but it's not producing the effect that I need:

.inlay-circle {
  width: 15rem;
  height: 15rem;
  border: solid #a7a9ac 2px;
  border-radius: 50%;
}
.inlay-circle:before {
  top: 0.7rem;
  left: 0.5rem;
  position: absolute;
  content: '';
  width: 15rem;
  height: 15rem;
  border-right: solid #658d1b 0.6rem;
  border-radius: 50%;
  transform: rotate(45deg);
}
<div class="inlay-circle"></div>

Any help on getting the inlay squared and adding the spacing between the inlay and the main circle would be highly appreciated.

like image 265
Jacques Snyman Avatar asked Aug 14 '19 07:08

Jacques Snyman


4 Answers

First off, I've changed dimensions to pixels as it was easier to work with just one unit, but you can of course change this back. So I made the green border 10px thick.

You need 3 circle sections to achieve this. One for the gray circle, one for the green quarter and one to achieve the gap between the two visible parts. The gap may be achievable using other methods that I can't think of right away.

First, I moved the green border to the ::after pseudo-selector, so I could put something underneath it to create the gap (the ::before pseudo-selector)

Secondly, to avoid the growing/shrinking effect your green border has, you need to give the whole green circle the same size (at least the parts that are next to the border-right, i.e. border-top and border-bottom). This can be done by adding a 10px transparent border:

border: solid transparent 10px;

To compensate for the whole box with the green border growing as a result of this, I added negative margins on the left/top.

For the gap, a second circle is created. This one has a white border. This means it won't work against any other background (but you can change the color of this border to match the background). It's a bit bigger and moved further left/top so that it's positioned appropriately.

.inlay-circle {
  width: 15rem;
  height: 15rem;
  border: solid #a7a9ac 2px;
  border-radius: 50%;
}
.inlay-circle::after {
  margin-left: -15px;
  margin-top: -15px;
  position: absolute;
  content: '';
  width: 15rem;
  height: 15rem;
  border: solid transparent 10px;
  border-right: solid #658d1b 10px;
  border-radius: 50%;
  transform: rotate(45deg);

}
.inlay-circle::before {
  margin-left: -30px;
  margin-top: -30px;
  position: absolute;
  content: '';
  width: 15rem;
  height: 15rem;
  border: solid transparent 20px;
  border-right: solid white 20px;
  border-radius: 50%;
  transform: rotate(45deg);
}
<div class="inlay-circle"></div>
like image 78
Mathias-S Avatar answered Sep 19 '22 22:09

Mathias-S


this is a css method but better to do it as svg !

.inlay-circle {
  width: 15rem;
  height: 15rem;
  border: solid #a7a9ac 2px;
  border-radius: 50%;
}
.border-cut {
  top: 0;
  left: 3px;
  position: absolute;
  width: 15rem;
  height: 15rem;
  z-index:1;
  border-right: solid #658d1b 0.6rem;
    border-top: solid transparent 0.6rem;
    border-bottom: solid transparent 0.6rem;
  border-radius: 50%;
  transform: rotate(20deg);
}
.border-cut-white{
    top: -11px;
    left: -15px;
  position: absolute;
  width:  16rem;
  height:  16rem;
  z-index:0;
  border-right: solid white 0.6rem;
    border-top: solid transparent 0.6rem;
    border-bottom: solid transparent 0.6rem;
  border-radius: 50%;
  transform: rotate(20deg);
}
<div class="inlay-circle">
  <div class="border-cut"></div>
  <div class="border-cut-white"></div>
</div>
like image 20
adel Avatar answered Sep 18 '22 22:09

adel


Try this :)

 .outter-circle {
    width: 200px;
    height: 200px;
    border:5px solid lightgrey;
    border-radius: 50%;
  }
  
  .inner-box {
    width: 55%;
    height: 55%;
    border: 5px solid transparent;
    position: relative;
    top: 48%;
    left: 48%;
    background: white;
    overflow: hidden;
  }

  .inner-circle {
    width: 200px;
    height: 200px;
    border: 8px solid green;
    border-radius: 50%;
    transform: translate(-51%, -51%);
  }
<div class="outter-circle">
  <div class="inner-box">
    <div class="inner-circle"></div>
  </div>
</div>
like image 26
UtkarshPramodGupta Avatar answered Sep 20 '22 22:09

UtkarshPramodGupta


Based on my previous answer I would consider the same trick with clip-path. The idea is to use two opposite clip-path to show/hide different part while considering some gaps.

I am using CSS variables to easily control the size, the gaps and the colors:

.palette {
  --g:5px; /* The gap between shapes*/
  --s:10px; /* the size*/

  height: 200px;
  width: 200px;
  position:relative;
  display:inline-block;
  overflow:hidden;
}
.palette:before,
.palette:after{
  content:"";
  position:absolute;
  top:0;
  left:0;
  right:0;
  bottom:0;
  border:var(--s) solid var(--c,blue);
  border-radius:50%;
  clip-path:polygon(
    calc(50% + var(--g)/2) 50%, 
    calc(50% + var(--g)/2) 0%, 
    100% 0%,
    100% calc(33.745% - var(--g)/2),
    50% calc(50% - var(--g)/2)); 
}
.palette:after {
 clip-path:polygon(
    calc(50% - var(--g)/2) 50%, 
    calc(50% - var(--g)/2) 0%, 
    0% 0%,0% 100%,100% 100%,
    100% calc(33.745% + var(--g)/2),
    50% calc(50% + var(--g)/2)); 
  --c:orange;
  border-width:calc(var(--s)/2);  
  top:calc(var(--s)/4);
  left:calc(var(--s)/4);
  right:calc(var(--s)/4);
  bottom:calc(var(--s)/4);
}

body {
 background:#f2f2f2;
}
<div class="palette">
</div>

<div class="palette" style="--s:40px;--g:20px">
</div>

<div class="palette" style="--s:8px;--g:10px">
</div>

enter image description here

You can apply a rotation to control where the position of the inlay border start

.palette {
  --g:5px; /* The gap between shapes*/
  --s:10px; /* the size*/

  height: 200px;
  width: 200px;
  position:relative;
  display:inline-block;
  overflow:hidden;
}
.palette:before,
.palette:after{
  content:"";
  position:absolute;
  top:0;
  left:0;
  right:0;
  bottom:0;
  border:var(--s) solid var(--c,blue);
  border-radius:50%;
  clip-path:polygon(
    calc(50% + var(--g)/2) 50%, 
    calc(50% + var(--g)/2) 0%, 
    100% 0%,
    100% calc(33.745% - var(--g)/2),
    50% calc(50% - var(--g)/2)); 
}
.palette:after {
 clip-path:polygon(
    calc(50% - var(--g)/2) 50%, 
    calc(50% - var(--g)/2) 0%, 
    0% 0%,0% 100%,100% 100%,
    100% calc(33.745% + var(--g)/2),
    50% calc(50% + var(--g)/2)); 
  --c:orange;
  border-width:calc(var(--s)/2);  
  top:calc(var(--s)/4);
  left:calc(var(--s)/4);
  right:calc(var(--s)/4);
  bottom:calc(var(--s)/4);
}

body {
 background:#f2f2f2;
}
<div class="palette">
</div>

<div class="palette" style="--s:40px;--g:20px;transform:rotate(45deg)">
</div>

<div class="palette" style="--s:8px;--g:10px;transform:rotate(90deg)">
</div>

enter image description here

And use a different clip-path to control the size

.palette {
  --g:5px; /* The gap between shapes*/
  --s:10px; /* the size*/

  height: 200px;
  width: 200px;
  position:relative;
  display:inline-block;
  overflow:hidden;
}
.palette:before,
.palette:after{
  content:"";
  position:absolute;
  top:0;
  left:0;
  right:0;
  bottom:0;
  border:var(--s) solid var(--c,blue);
  border-radius:50%;
  clip-path:polygon(
    calc(50% + var(--g)/2) 50%, 
    calc(50% + var(--g)/2) 0%, 
    100% 0%,100% 50%,
    100% calc(70% - var(--g)/2),
    50% calc(50% - var(--g)/2)); 
}

.palette:after {
 clip-path:polygon(
    calc(50% - var(--g)/2) 50%, 
    calc(50% - var(--g)/2) 0%, 
    0% 0%,0% 100%,100% 100%,
    100% calc(70% + var(--g)/2),
    50% calc(50% + var(--g)/2)); 
  --c:orange;
  border-width:calc(var(--s)/2);  
  top:calc(var(--s)/4);
  left:calc(var(--s)/4);
  right:calc(var(--s)/4);
  bottom:calc(var(--s)/4);
}

body {
 background:#f2f2f2;
}
<div class="palette">
</div>

<div class="palette" style="--s:40px;--g:20px;transform:rotate(45deg)">
</div>

<div class="palette" style="--s:8px;--g:10px;transform:rotate(90deg)">
</div>

enter image description here

like image 35
Temani Afif Avatar answered Sep 20 '22 22:09

Temani Afif