Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to create this shape (two partial circles joined together) with CSS?

I was trying to accomplish this border for two divs with CSS:

Desired result

I tried just using border-radius, but the two partial circles aren't pressed together: http://jsfiddle.net/uwz6L79w/

 .left {     position: absolute;     left: 0;     top: 0;     width: 100px;     height: 100px;     border-width: 4px;     border-color: black white black black;     border-style: solid;     border-radius: 60px   }   .right {     position: absolute;     left: 104px;     top: 0;     width: 100px;     height: 100px;     border-width: 4px;     border-color: black black black white;     border-style: solid;     border-radius: 60px;   }
<div class="left"></div>  <div class="right"></div>

I could just press them together further, but I'd have to have one div overlap the other, like this: http://jsfiddle.net/uwz6L79w/1/.

.left {    position: absolute;    left: 0;    top: 0;    width: 100px;    height: 100px;    border-width: 4px;    border-color: black white black black;    border-style: solid;    border-radius: 60px  }  .right {    position: absolute;    left: 70px;    top: 0;    width: 100px;    height: 100px;    border-width: 4px;    border-color: black black black white;    border-style: solid;    border-radius: 60px;    background: #f2f2f2;  }
<div class="left"></div>  <div class="right"></div>

Does anyone know how I could accomplish this without having the divs overlap?

like image 493
Joe Morano Avatar asked Nov 24 '15 08:11

Joe Morano


People also ask

How do I make a partial circle in CSS?

You can just take a pseudo element ::after to create the open part, with just overlapping the circle element. Advantage is, that the open part can be as long as wished (not limited to a 3/4 full circle).

Can you create a circle using CSS?

To create a circle we can set the border-radius on the element. This will create curved corners on the element. If we set it to 50% it will create a circle. If you set a different width and height we will get an oval instead.

How to create a circle in CSS?

To create a circle in CSS, first we need a div and give it an ID name of the shape. So for this example, set circle as the ID name. CSS. For the CSS, simply put a width and height and then give it a border radius half of the width and the height.

How to create a square shape in CSS?

To create a square shape in CSS, just like the circle shape, we need a div and give it an ID name of the shape. So, for this example, set square as the ID name. CSS. For the CSS of square, simply set up a width and height of equal value and provide a value making it look visible.

How do I center text around a circle in HTML?

Here, we also specify the display as “inline-block” and add the text-align property set to “center” to the <div> to align the circles to the center. In our next example, we create a circular <div> and place a text inside it. In the following example, we create a responsive circle.

How to create an oval and triangle in CSS?

To create an oval in CSS, create a div with the ID name oval. Oval is almost similar with circle shape; however, the oval is rectangular in shape and will need a radius that is half of the height. In order to create a triangle in CSS, set up again a div with the ID name triangle. To create a triangle, manipulate the border property.


2 Answers

SVG

This is also possible using SVG.

The SVG version is very short as it mainly only requires an Arc command to control its shape, size and position.

<svg width="50%" viewbox="0 0 100 50">    <path d="M50,35              a20,20 0 1,0 0,-20              a20,20 0 1,0 0,20z"           fill="white"           stroke="black">    </path>  </svg>

SVG stands for Scalable Vector Graphic. The web browser views it as an image but you can add text and normal HTML elements within an SVG.

It is well supported across all browsers as viewable here: CanIUse

  • SVG | MDN
like image 196
Stewartside Avatar answered Oct 13 '22 22:10

Stewartside


Using Borders: Recommended

You could do it the same way as in your second snippet and use positioning like in the below snippet to avoid the two div elements from overlapping. Here the circles are produced by pseudo-elements and the overlapping part is cut out using overflow: hidden on their parents.

One thing to note here is that any hover effect should be added on the pseudo-elements and not the parent elements. This is because if the :hover is attached to parent then it would be triggered even when hovering outside the circle (because the parent is still a square).

Out of all the three solutions provided in this answer, this is the one that has the best browser support and would work even in IE8. Hence, this is the recommended one.

.left, .right {    position: relative;    float: left;    height: 200px;    width: 200px;    /* border: 1px solid; uncomment to see that they aren't overlapped */    overflow: hidden;  }  .left:after, .right:after {    position: absolute;    content: '';    height: calc(100% - 12px); /* 12px because of 6px border on either side */    width: calc(100% - 12px); /* 12px because of 6px border on either side */    border-radius: 50%;    border: 6px solid gray;  }  .left:after { right: -20px; }  .right:after { left: -20px; }
<div class='left'></div>  <div class='right'></div>

Using Radial Gradients:

If you don't want to use pseudo-elements and a overflow: hidden on the parent then you could also make use of radial-gradient background images to produce the circle and position them such that they end up producing the required effect. Below is a sample snippet for this approach.

The downside of this approach is the low browser support for radial-gradient. It would not work in IE9 and lower. Plus, the circles produced by radial gradients are generally jagged (rough edges) and when we modify the color stop positions to make it smoother, it gives a slightly blurred appearance.

.left, .right {    float: left;    height: 200px;    width: 200px;    /*border: 1px solid;  uncomment to see that they aren't overlapped */  }    /* generally the below code should be enough to produce 6px thick circular border  .left {    background: radial-gradient(circle at 70% 50%, transparent calc(50% - 3px), gray calc(50% - 3px), gray calc(50% + 3px), transparent calc(50% + 3px));  }  .right {    background: radial-gradient(circle at 30% 50%, transparent calc(50% - 3px), gray calc(50% - 3px), gray calc(50% + 3px), transparent calc(50% + 3px));  }  */    /* but it produces jagged edges and so we can change the color stops a bit like below     this produces smoother circles but the disadvantage is that they'd look a bit blurred */  .left {    background: radial-gradient(circle at 70% 50%, transparent calc(50% - 4px), gray calc(50% - 2px), gray calc(50% + 2px), transparent calc(50% + 4px));  }  .right {    background: radial-gradient(circle at 30% 50%, transparent calc(50% - 4px), gray calc(50% - 2px), gray calc(50% + 2px), transparent calc(50% + 4px));  }
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>  <div class='left'></div>  <div class='right'></div>

Using Clip Paths (CSS/SVG):

Another approach that could be used is to use clip-path. The advantage of this approach is that the hover effects would be triggered only when the cursor is within the circle (as can be seen in snippet). This is because the unnecessary portions are clipped.

Downside is again the poor browser support. CSS version of clip-path is supported only in Webkit but not in Firefox, IE whereas the SVG version (using inline SVG) is supported in Webkit, Firefox but not IE.

.left, .right {    float: left;    height: 200px;    width: 200px;    border-radius: 50%;    border: 6px solid gray;  }    /* CSS Clip Path - not supported by FF and IE */  .left.css-clip {    clip-path: polygon(0% 0%, 80% 0%, 80% 100%, 0% 100%);  }  .right.css-clip {    margin-left: -86px;  /* 20% width * 2 (which is the clipped space) - border width */    clip-path: polygon(20% 0%, 100% 0%, 100% 100%, 20% 100%);  }    /* SVG Clip Path - supported by Webkit, FF but not IE */  .left.svg-clip {    clip-path: url(#clipper-left);  }  .right.svg-clip {    margin-left: -86px;  /* 20% width * 2 (which is the clipped space) - border width */    clip-path: url(#clipper-right);  }    /* Just for demo */    h3{ clear: both; }  .left:hover, .right:hover{ background: red; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>    <h3>CSS Clip Path</h3>  <div class='left css-clip'></div>  <div class='right css-clip'></div>    <h3>SVG Clip Path</h3>  <div class='left svg-clip'></div>  <div class='right svg-clip'></div>    <!-- Inline SVG for SVG Clip Path -->  <svg width='0' height='0'>    <defs>      <clipPath id='clipper-left' clipPathUnits='objectBoundingBox'>        <path d='M0,0 .8,0 .8,1 0,1z' />        </clipPath>      <clipPath id='clipper-right' clipPathUnits='objectBoundingBox'>        <path d='M.2,0 1,0 1,1 .2,1z' />        </clipPath>      </defs>    </svg>
like image 32
Harry Avatar answered Oct 13 '22 20:10

Harry