hauw_s1u
hauw_s1u

Reputation: 11

Circle/Donut shape with a piece cut-off

How can I make an image like the one below with pure CSS or canvas? I need it to have a transparent background; can you help me for this?

Image

Upvotes: 0

Views: 2495

Answers (3)

jbutler483
jbutler483

Reputation: 24549

Something like this would do it for you (after possibly some tinkering):

html,body{background:black;}

.nut{
  height:200px;
  width:200px;
  border-radius:50%;
  position:relative;
  background-color:lightblue;
  }

.nut:before{
  position:absolute;
  content:"";
  height:40%;
  width:40%;
  background-color:black;
  left:30%;
  top:30%;
  border-radius:50%;
  }
.nut:after{
 position:absolute;
  content:"";
  height:40%;
  width:40%;
  background-color:lightblue;
  right:-5%;
  bottom:-5%;
  border-radius: 0 0 100% 0;
  border-left:5px solid black;
  border-top:5px solid black;
}
<div class="nut"></div>


In terms of allowing a transparent background, you could illustrate this with something like:

div {
  border-radius: 50%;
  height: 50px;
  width: 50px;
  border: 50px solid blue;
  position: relative;
  border-bottom-color: transparent;
  transform: rotate(-45deg);
  margin: 20px auto;
}
div:after {
  content: "";
  position: absolute;
  top: -50px;
  left: -50px;
  height: 100%;
  width: 100%;
  border-radius: 50%;
  border: 50px solid transparent;
  border-bottom-color: blue;
  transition: all 0.6s;
}
div:before {
  content: "";
  position: absolute;
  top: -10px;
  left: -10px;
  height: 100%;
  width: 100%;
  border: 10px solid blue;
  border-radius: 50%;
}
div:hover:after {
  top: -30px;
  left: -50px;
  border-bottom-color: tomato;
}
/*DEMO ONLY*/

html {
  text-align: center;
  height: 100%;
  background: radial-gradient(ellipse at center, rgba(79, 79, 79, 1) 0%, rgba(34, 34, 34, 1) 100%);
}
HOVER ME
<div></div>

Upvotes: 6

Persijn
Persijn

Reputation: 14990

SVG

Here is an svg solution.
Used a clip path on a circle element (to exclude a corner of the image)
Then made the pizza slice with a path element with an arc type.

<svg width="100px" height="100px" viewbox="0 0 110 110">
  <defs>
    <clipPath id="myClip">
      <path clip-rule="evenodd" 
            d="M0 0 100 0  100 100 0 100Z 
               M67 67 100 67 100 100 67 100Z"/>
    </clipPath>
  </defs>
  <circle fill="none" stroke="LightBlue" stroke-width="25" cx="50" cy="50" r="35"  clip-path="url(#myClip)"/>
  <path fill="LightBlue" d="M70 70 70 100 A 25 25 0 0 0 100 70Z"/>
</svg>

Upvotes: 2

user784509
user784509

Reputation: 79

Basically , that is at most 3 divs and a little CSS, and likely with a little fidgeting , it could be had for but a single div and some CSS.

The blue donut is simply a div with a thick blue border and the border-radius CSS property set to make the rounded corners form a circle.

The pizza slice is simply in reality a plain square div with a blue background and a thick-ish white border.

Those two elements would be in a third div that also used border-radius to make it a circle but either had the border color set to transparent or had no border actually at all but either way made round. This outer third div would also have the overflow property set to hidden, thus giving the rounded part of the pizza slice as that square would be clipped by the outer circle

The pizza slice could be a child of the donut and have it's position property set to relative, or it could probably also be a child of the outer clipping div as position absolute, and in that latter case the outer clipping div would have a position property set to relative.

Now that would be how you would do it with three divs, but as I mentioned before , it could probably with a bit of fidgeting be boiled down to but a single div if one used CSS pseudo ::before and ::after classes to fake two of the divs , with those likely being the donut and pizza slice, which would leave but the clipping div as the only real element in the page.

That would be the slickest as in the end you would have markup something like...

  <div class="logo"/>

... and nothing more

Well, what the heck , call it christmas in May

<style  type="text/css">
.logo       ,.logo::before  {border-radius  :50%;display:inline-block;padding:0;}
.logo::before   ,.logo::after   {position   :absolute;content:"";}
.logo       {   text-align:center;position:relative;border:none;
        width:11em;height:11em;overflow:hidden;}
.logo::before   {   left:.75em;top:.75em;width:3.5em;height:3.5em;
        margin:0;border:3em solid #00A6E1;}
.logo::after    {   border:.4em solid #fff;top:6.8em;
        left:6.8em;width:5em;height:5em;
        background-color:#0ae;display:block;}
</style>

.logo,
    .logo::before {
      border-radius: 50%;
      display: inline-block;
      padding: 0;
    }
    .logo::before,
    .logo::after {
      position: absolute;
      content: "";
    }
    .logo {
      text-align: center;
      position: relative;
      border: none;
      width: 11em;
      height: 11em;
      overflow: hidden;
    }
    .logo::before {
      left: .75em;
      top: .75em;
      width: 3.5em;
      height: 3.5em;
      margin: 0;
      border: 3em solid #00A6E1;
    }
    .logo::after {
      border: .4em solid #fff;
      top: 6.8em;
      left: 6.8em;
      width: 5em;
      height: 5em;
      background-color: #0ae;
      display: block;
    }
<div class="logo" />

That makes the logo your after , using of course but a single div, plain old CSS , no images or other clap trap. I'm actually a programmer by trade , but to me CSS is just sorta another programming language and with everyone wanting to pull out canvas SVG and the like , I figured it worth showing how about 9 lines of text could send em to the wood shed. :)

Seems to work fine on both Chrome/webkit and Mozilla , can't really speak to how Microsoft exploder will take to it as I boot to a Linux desktop and have not had a M$ machine around for nearly a decade.

NOTE My habits have already adopted some minutia in the new specs relating to pseudo elements in that traditionally the syntax has been .logo:before and .logo:after, but the new rules say I'm supposed to use double "::" instead of the old ":", so if M$ exploder whines, one might try trading the "::" for the older ":" which IE might like better. Newer browsers really don't care.

Upvotes: 0

Related Questions