How to create a circle with links on border side
Asked Answered
S

8

19

I am trying to make a circle like this. I was able to make it in the fiddle, but the problem is that I need each orange side to be a link and I can't do it with borders. If anyone can help me with this I will be really grateful.

#circle {
  width: 200px;
  height: 200px;
  border-radius: 50%;
  background: green;
}
#incircle {
  width: 100px;
  height: 100px;
  border-radius: 50%;
  border: 50px dotted orange;
}
<div id="circle">
  <div id="incircle"></div>
</div>
Silly answered 14/1, 2015 at 12:32 Comment(14)
@chipChocolate.py No each orange border must be different linksSilly
"i need each orange side to be a link" - Do you mean the left and right sides should be two different links?Delanadelancey
Are you particular about the shape of each orange colored area too? I mean their inner part looks like an arc.Presentative
@chipChocolate.py: I guess OP intends it to be like a fortune wheel with each boxed area being a unique item.Presentative
@chipChocolate.py There are six orange fig there and each should be a link leading to different placesSilly
@Presentative Yes there shapes are the one that's troubling me it is a bit hardSilly
I only see one orange shape, not six. In the event you want shapes like the ones on a spinning fortune wheel, I suggest you use SVG graphics as you can link to certain shapes inside the SVG, or use a drawing library such as Rafael (raphaeljs.com) or Paper.js (paperjs.org)Crossbeam
See @the8472's answer below, he has the same idea and I believe it will be the best solution.Crossbeam
@Crossbeam Thanks i will have a look at itSilly
what about a map ? w3schools.com/tags/tag_map.aspTrevethick
Just thought i'd place this here...Carlyn
@Carlyn That is really good nice thinkingSilly
@Akshay: I was having more fun with spinning that than I was coding an answer!! hahaCarlyn
related: https://mcmap.net/q/244581/-css-only-pie-chart-how-to-add-spacing-padding-between-slices/8620333Oldenburg
P
20

The key to creating a circle with segments is to find points along the circle which would be used in the SVG path elements as coordinates. Finding points on a circle can be done easily using trigonometric equations if we know the angles.

X Coordinate of point = Radius of the circle * Cos(Angle in Radians) + X Coordinate of center point

Y Coordinate of point = Radius of the circle * Sin(Angle in Radians) + Y Coordinate of center point

Angle in Radians = Angle in Degrees * Math.PI / 180

The angles depend on the no. of segments that we have to create. The generic formula is (360 / no. of segments). So to create a circle with 6 segments, the angle covered by each of the segment would be 60 degrees. The first segment would cover from 0 to 60 degrees, second from 60 to 120 degrees and so on.


Demo of Circle with 6 Segments:

Below table shows how the points are calculated for a circle with 6 segments (where radius of circle is 50, center point is 55,55):

enter image description here

Once the points are calculated, coding the path itself is simple. The path should start and end at the center point (which is 50,50), from the center point, we should first draw a line to From Point and from there draw an arc to the To Point. Below is how a sample path would look like:

<path d='M55,55 L105,55 A50,50 0 0,1 80,98.30z' />

svg {
  height: 220px;
  width: 220px;
}
path {
  fill: transparent;
  stroke: black;
}
<svg viewBox='0 0 110 110'>
  <path d='M55,55 L105,55 A50,50 0 0,1 80,98.30z' />
  <path d='M55,55 L80,98.30 A50,50 0 0,1 30,98.30z' />
  <path d='M55,55 L30,98.30 A50,50 0 0,1 5,55z' />
  <path d='M55,55 L5,55 A50,50 0 0,1 30,11.69z' />
  <path d='M55,55 L30,11.69 A50,50 0 0,1 80,11.69z' />
  <path d='M55,55 L80,11.69 A50,50 0 0,1 105,55z' />
</svg>

Demo of Circle with 12 Segments:

For a circle with 12 segments, each segment would cover 30 degrees and so the points would be calculated as in the below table:

enter image description here

svg {
  height: 220px;
  width: 220px;
}
path {
  fill: transparent;
  stroke: black;
}
<svg viewBox='0 0 110 110'>
  <path d='M55,55 L105,55 A50,50 0 0,1 98.30,80z' />
  <path d='M55,55 L98.30,80 A50,50 0 0,1 80,98.30z' />
  <path d='M55,55 L80,98.30 A50,50 0 0,1 55,105z' />
  <path d='M55,55 L55,105 A50,50 0 0,1 30,98.30z' />
  <path d='M55,55 L30,98.30 A50,50 0 0,1 11.69,80z' />
  <path d='M55,55 L11.69,80 A50,50 0 0,1 5,55z' />
  <path d='M55,55 L5,55 A50,50 0 0,1 11.69,30z' />
  <path d='M55,55 L11.69,30 A50,50 0 0,1 30,11.69z' />
  <path d='M55,55 L30,11.69 A50,50 0 0,1 55,5z' />
  <path d='M55,55 L55,5 A50,50 0 0,1 80,11.69z' />
  <path d='M55,55 L80,11.69 A50,50 0 0,1 98.30,30z' />
  <path d='M55,55 L98.30,30 A50,50 0 0,1 105,55z' />
</svg>

Circle with an unsegmented inner portion:

If it should look as though a portion of the circle (with a smaller radius) in center looks unsegmented and if that inner portion need not be transparent, just add an extra circle element at the end within the SVG.

svg {
  height: 220px;
  width: 220px;
}
path {
  fill: transparent;
  stroke: black;
}
circle {
  fill: yellowgreen;
  stroke: black;
}
<svg viewBox='0 0 110 110'>
  <path d='M55,55 L105,55 A50,50 0 0,1 80,98.30z' />
  <path d='M55,55 L80,98.30 A50,50 0 0,1 30,98.30z' />
  <path d='M55,55 L30,98.30 A50,50 0 0,1 5,55z' />
  <path d='M55,55 L5,55 A50,50 0 0,1 30,11.69z' />
  <path d='M55,55 L30,11.69 A50,50 0 0,1 80,11.69z' />
  <path d='M55,55 L80,11.69 A50,50 0 0,1 105,55z' />
  <circle cx='55' cy='55' r='25' />
</svg>

Different Background for each Segment:

If each of the segments should have a different background to them then just add the fill attribute to each path element.

svg {
  height: 220px;
  width: 220px;
}
path {
  stroke: black;
}
circle {
  fill: yellowgreen;
  stroke: black;
}
<svg viewBox='0 0 110 110'>
  <path d='M55,55 L105,55 A50,50 0 0,1 80,98.30z' fill='crimson' />
  <path d='M55,55 L80,98.30 A50,50 0 0,1 30,98.30z' fill='tomato' />
  <path d='M55,55 L30,98.30 A50,50 0 0,1 5,55z' fill='sandybrown' />
  <path d='M55,55 L5,55 A50,50 0 0,1 30,11.69z' fill='mediumseagreen' />
  <path d='M55,55 L30,11.69 A50,50 0 0,1 80,11.69z' fill='chocolate' />
  <path d='M55,55 L80,11.69 A50,50 0 0,1 105,55z' fill='teal' />
  <circle cx='55' cy='55' r='25' />
</svg>

Demo with a transparent inner portion:

If the center portion cannot have a solid color then the whole thing becomes more complex because we can no longer start and end the path at the center point. In such cases, we have to find points on both the outer circle and the inner circle like below:

enter image description here

In this case, the path has to start from the "From(Inner)" and end at same point, from the start a line should be drawn to "From(Outer)", then an arc to "To(Outer)", a line to "To(Inner)" and an arc to "From (Inner)".

svg {
  height: 220px;
  width: 220px;
}
path {
  fill: transparent;
  stroke: black;
}
<svg viewBox='0 0 110 110'>
  <path d='M80,55 L105,55 A50,50 0 0,1 80,98.30 L67.5,76.65 A25,25 0 0,0 80,55z' />
  <path d='M67.5,76.65 L80,98.30 A50,50 0 0,1 30,98.30 L42.5,76.65 A25,25 0 0,0 67.5,76.65z' />
  <path d='M42.5,76.65 L30,98.30 A50,50 0 0,1 5,55 L30,55 A25,25 0 0,0 42.5,76.65z' />
  <path d='M30,55 L5,55 A50,50 0 0,1 30,11.69 L42.5,33.34 A25,25 0 0,0 30,55z' />
  <path d='M42.5,33.34 L30,11.69 A50,50 0 0,1 80,11.69 L67.5,33.34 A25,25 0 0,0 42.5,33.34z' />
  <path d='M67.5,33.34 L80,11.69 A50,50 0 0,1 105,55 L80,55 A25,25 0 0,0 67.5,33.4z' />
</svg>

Making each segment a clickable link:

This is pretty simple to do once the shape itself has been created. Like in chipChocolate.py's answer, just wrap each path within a SVG anchor tag (<a xlink:href="#"> where # should be replaced the URL of the linked page).

svg {
  height: 220px;
  width: 220px;
}
path {
  fill: transparent;
  stroke: black;
}
<svg viewBox='0 0 110 110'>
  <a xlink:href="#"><path d='M55,55 L105,55 A50,50 0 0,1 80,98.30z' /></a>
  <a xlink:href="#"><path d='M55,55 L80,98.30 A50,50 0 0,1 30,98.30z' /></a>
  <a xlink:href="#"><path d='M55,55 L30,98.30 A50,50 0 0,1 5,55z' /></a>
  <a xlink:href="#"><path d='M55,55 L5,55 A50,50 0 0,1 30,11.69z' /></a>
  <a xlink:href="#"><path d='M55,55 L30,11.69 A50,50 0 0,1 80,11.69z' /></a>
  <a xlink:href="#"><path d='M55,55 L80,11.69 A50,50 0 0,1 105,55z' /></a>
</svg>

Adding text within the shape:

Text addition in SVG is slightly more complex because again we have to specify the point where the text should be placed. If the text is reasonably small (say a few characters), then we can again find points on the circle such that the angle is exactly in the middle of the segment and use it. The radius could be set such that it is half the parent circle's radius (if there is no unsegmented portion) or such that it is half way between the inner circle and outer circle. The text-anchor, dominant-baseline settings that are added via CSS would make sure that the text is positioned in such a way that both the horizontal and vertical center of the text matches with the specified point.

If the text is large (and needs to wrap around), then extra handling should be done because contents within the SVG text tag won't get wrapped around automatically.

Point calculation for circle with 6 segments and no central unsegmented area:

enter image description here

Point calculation for circle with 6 segments and central unsegmented area:

enter image description here

svg {
  height: 220px;
  width: 220px;
}
path {
  fill: transparent;
  stroke: black;
}
text {
  text-anchor: middle;
  dominant-baseline: middle; /* doesn't work in IE */
  font: 12px Calibri, Arial;
}
<svg viewBox='0 0 110 110'>
  <path d='M55,55 L105,55 A50,50 0 0,1 80,98.30z' />
  <text x='76.65' y='67.5'>1</text>
  <path d='M55,55 L80,98.30 A50,50 0 0,1 30,98.30z' />
  <text x='55' y='80'>2</text>
  <path d='M55,55 L30,98.30 A50,50 0 0,1 5,55z' />
  <text x='33.4' y='67.5'>3</text>
  <path d='M55,55 L5,55 A50,50 0 0,1 30,11.69z' />
  <text x='33.4' y='42.5'>4</text>
  <path d='M55,55 L30,11.69 A50,50 0 0,1 80,11.69z' />
  <text x='55' y='30'>5</text>
  <path d='M55,55 L80,11.69 A50,50 0 0,1 105,55z' />
  <text x='76.65' y='42.5'>6</text>
</svg>
<svg viewBox='0 0 110 110'>
  <path d='M55,55 L105,55 A50,50 0 0,1 80,98.30z' />
  <text x='87.47' y='73.75'>1</text>
  <path d='M55,55 L80,98.30 A50,50 0 0,1 30,98.30z' />
  <text x='55' y='92.5'>2</text>
  <path d='M55,55 L30,98.30 A50,50 0 0,1 5,55z' />
  <text x='22.52' y='73.75'>3</text>
  <path d='M55,55 L5,55 A50,50 0 0,1 30,11.69z' />
  <text x='22.52' y='36.25'>4</text>
  <path d='M55,55 L30,11.69 A50,50 0 0,1 80,11.69z' />
  <text x='55' y='17.5'>5</text>
  <path d='M55,55 L80,11.69 A50,50 0 0,1 105,55z' />
  <text x='87.47' y='36.25'>6</text>
  <circle cx='55' cy='55' r='25' />
</svg>

Dynamic creation with JavaScript:

Below is a rough JS based implementation in order to create the segments dynamically. The function takes four arguments - the X coordinate of the circle's center, the Y coordinate of its center, the radius of the circle and the no. of segments/slices.

var fromAngle, toAngle, fromCoordX, fromCoordY, toCoordX, toCoordY, path, d;

function createPie(cx, cy, r, slices) {
  for (var i = 0; i < slices; i++) {
    path = document.createElementNS("http://www.w3.org/2000/svg", "path");
    fromAngle = i * 360 / slices;
    toAngle = (i + 1) * 360 / slices;
    fromCoordX = cx + (r * Math.cos(fromAngle * Math.PI / 180));
    fromCoordY = cy + (r * Math.sin(fromAngle * Math.PI / 180));
    toCoordX = cx + (r * Math.cos(toAngle * Math.PI / 180));
    toCoordY = cy + (r * Math.sin(toAngle * Math.PI / 180));
    d = 'M' + cx + ',' + cy + ' L' + fromCoordX + ',' + fromCoordY + ' A' + r + ',' + r + ' 0 0,1 ' + toCoordX + ',' + toCoordY + 'z';
    path.setAttributeNS(null, "d", d);
    document.getElementById('pie').appendChild(path);
  }
}

createPie(55, 55, 50, 6);
svg {
  height: 220px;
  width: 220px;
}
path {
  fill: transparent;
  stroke: black;
}
<svg viewBox="0 0 110 110" id="pie"></svg>

JS sample doesn't cover the examples with an unsegmented inner circle but that can be achieved by extending this.

Presentative answered 20/1, 2016 at 14:39 Comment(5)
Is there a way we could generate this with javascript?Prefatory
Yes @inspired. It is definitely possible but I'm quite busy at the moment and so can't provide a demo. All that you'd need to do is find out the co-ordinates based on the formula, concatenate them into a string (to form the value of d attribute) and then set that attribute to the path element. I'll post a demo when I get some free time,Presentative
Thanks! Please let me know when you do so. I'll make one for myself and show it to you when i'm done today.Prefatory
@inspired: Here is a rough demo with JavaScript. I am sure you will be able to extend this in case you need an inner circle that is unsegmented :)Presentative
why do to simple, if could be much more complicated? https://mcmap.net/q/244582/-quot-circular-quot-menu-using-svg-duplicateFunambulist
D
19

You could use svg's arcs to create the sections and svg's anchor(equivalent to HTML anchor tags) tags for the links.

enter image description here

.frag {
  fill: #FFA500;
  stroke: #FFFFFF;
  transition: fill 0.3s ;
}
.center {
  fill: #008000;
}
a:hover .frag {
  fill: #FFC722;
}
text {
  font-size: 17px;
  fill: #FFFFFF;
}
<svg width="200" height="200" viewBox="-2 -2 202 203" shape-rendering="geometricPrecision">
  <a xlink:href="#"><path class="frag" d="M100,100 v-100 a100,100 1 0,1 86.6025,50" /><text x="135" y="42.5" text-anchor="middle">1</text></a>
  <a xlink:href="#"><path class="frag" d="M100,100 l86.6025,-50 a100,100 1 0,1 0,100" /><text x="170" y="105" text-anchor="middle">2</text></a>
  <a xlink:href="#"><path class="frag" d="M100,100 l86.6025,50 a100,100 1 0,1 -86.6025,50" /><text x="135" y="170" text-anchor="middle">3</text></a>
  <a xlink:href="#"><path class="frag" d="M100,100 v100 a100,100 1 0,1 -86.6025,-50" /><text x="65" y="170" text-anchor="middle">4</text></a>
  <a xlink:href="#"><path class="frag" d="M100,100 l-86.6025,50 a100,100 1 0,1 0,-100" /><text x="27.5" y="105" text-anchor="middle">5</text></a>
  <a xlink:href="#"><path class="frag" d="M100,100 l-86.6025,-50 a100,100 1 0,1 86.0025,-50" /><text x="65" y="42.5" text-anchor="middle">6</text></a>
  <a xlink:href="#"><path class="center" d="M100,100 v-50 a50,50 1 0,1 0,100 a50,50 1 0,1 0,-100" /></a>
</svg>

You could also stretch or resize the svg.

enter image description here

.frag {
  fill: #FFA500;
  stroke: #FFFFFF;
  transition: fill 0.3s ;
}
.center {
  fill: #008000;
}
a:hover .frag {
  fill: #FFC722;
}
text {
  font-size: 17px;
  fill: #FFFFFF;
}
<svg width="100" height="200" viewBox="-2 -2 202 203" shape-rendering="geometricPrecision" preserveAspectRatio="none">
  <g id="circle">
    <a xlink:href="#"><path class="frag" d="M100,100 v-100 a100,100 1 0,1 86.6025,50" /><text x="135" y="42.5" text-anchor="middle">1</text></a>
    <a xlink:href="#"><path class="frag" d="M100,100 l86.6025,-50 a100,100 1 0,1 0,100" /><text x="170" y="105" text-anchor="middle">2</text></a>
    <a xlink:href="#"><path class="frag" d="M100,100 l86.6025,50 a100,100 1 0,1 -86.6025,50" /><text x="135" y="170" text-anchor="middle">3</text></a>
    <a xlink:href="#"><path class="frag" d="M100,100 v100 a100,100 1 0,1 -86.6025,-50" /><text x="65" y="170" text-anchor="middle">4</text></a>
    <a xlink:href="#"><path class="frag" d="M100,100 l-86.6025,50 a100,100 1 0,1 0,-100" /><text x="27.5" y="105" text-anchor="middle">5</text></a>
    <a xlink:href="#"><path class="frag" d="M100,100 l-86.6025,-50 a100,100 1 0,1 86.0025,-50" /><text x="65" y="42.5" text-anchor="middle">6</text></a>
    <a xlink:href="#"><path class="center" d="M100,100 v-50 a50,50 1 0,1 0,100 a50,50 1 0,1 0,-100" /></a>
  </g>
</svg>

<svg width="200" height="100" viewBox="-2 -2 202 203" shape-rendering="geometricPrecision" preserveAspectRatio="none">
  <use xlink:href="#circle" />
</svg>

<svg width="150" height="150" viewBox="-2 -2 202 203" shape-rendering="geometricPrecision" preserveAspectRatio="none">
  <use xlink:href="#circle" />
</svg>

<svg width="100" height="100" viewBox="-2 -2 202 203" shape-rendering="geometricPrecision" preserveAspectRatio="none">
  <use xlink:href="#circle" />
</svg>

<svg width="50" height="50" viewBox="-2 -2 202 203" shape-rendering="geometricPrecision" preserveAspectRatio="none">
  <use xlink:href="#circle" />
</svg>
Delanadelancey answered 14/1, 2015 at 13:24 Comment(7)
it seem useful but it doesn't look like the provided example .Trevethick
@chipChocolate.py If you saw what the OP provided as expected design, you should know what I mean ^^.Trevethick
@Trevethick - OP marked the question as accepted. I believe he got what he was looking for, Period! If he has any problem with the current design, I'm more than happy to re-design it. :)Delanadelancey
I need 11 sections instead of 6. What should be changed in the code?Charie
@Charie - You need to calculate each co-ordinate and apply accordingly in the d attribute of path element. This might help. I will make a JavaScript function to make sections arbitrarily and post it in my answer.Delanadelancey
@Delanadelancey The space between 6 or 1 is not accurate. I have added stroke-width: 4; space between is not coming properly Can you please help me out how we can fix this problem.Homicidal
@Homicidal - Here's what you're after :)Delanadelancey
A
11

CSS-only approach

NOTE: Markup can be significantly reduced by using pseudoelements, which I haven't currently used.

You can use SVG, but this can be made with CSS and HTML alone.

What I did was create 12 semicircles (by adding overflow: hidden; to parent container). I then created separate groups of 6 semicircles.

The angles at the center should be 30deg each ( 360/12 ). To achieve this, we have to rotate the semicircles from their original circle's center. We can do this with transform-origin: 50% 100%;

Now you just have to rotate/flip the second group of 6 semicircles to complete design.

Finally, add a central green circle to complete the design.

.cont, #bag {
    height:200px;
    width:400px;
    overflow:hidden;
}
#one, #two, #three, #four, #five, #six {
    height:400px;
    width:400px;
    border-radius:200px;
}
#bag > div {
    position:relative;
    transform-origin:50% 100%;
}
#one, #three, #five {
    background-color:orange;
}
#one:hover, #three:hover, #five:hover {
    background-color:gold;
}
#two, #four, #six {
    background-color:forestgreen;
}
#bag > :nth-child(2) {
    top:-200px;
    -webkit-transform:rotate(30deg);
    transform:rotate(30deg);
}
#bag > :nth-child(3) {
    top:-400px;
    transform:rotate(60deg);
    transform:rotate(60deg);
}
#bag > div:nth-child(4) {
    top:-600px;
    -webkit-transform:rotate(90deg);
    transform:rotate(90deg);
}
#bag > :nth-child(5) {
    top:-800px;
    -webkit-transform:rotate(120deg);
    transform:rotate(120deg);
}
#bag > :nth-child(6) {
    top:-1000px;
    -webkit-transform:rotate(150deg);
    transform:rotate(150deg);
}
#bag:nth-of-type(2){
    transform:scale(-1);
    transform-origin:50% 50%;
}
#green-center {
    height:200px;
    width:200px;
    border-radius:50%;
    background-color:forestgreen;
    position: relative;
    top:-300px;
    left:100px;
}
<div id="bag">
    <div class="cont">
        <a href="http://example.com/"><div id="one"></div></a>
    </div>
    <div class="cont">
        <div id="two">ABC</div>
    </div>
    <div class="cont">
        <a href="http://example.com/"><div id="three"></div></a>
    </div>
    <div class="cont">
        <div id="four"></div>
    </div>
    <div class="cont">
        <a href="http://example.com/"><div id="five"></div></a>
    </div>
    <div class="cont">
        <div id="six"></div>
    </div>
</div>
<div id="bag">
    <div class="cont">
        <a href="http://example.com/"><div id="one"></div></a>
    </div>
    <div class="cont">
        <div id="two"></div>
    </div>
    <div class="cont">
        <a href="http://example.com/"><div id="three"></div></a>
    </div>
    <div class="cont">
        <div id="four"></div>
    </div>
    <div class="cont">
        <a href="http://example.com/"><div id="five"></div></a>
    </div>
    <div class="cont">
        <div id="six"></div>
    </div>
</div>
<div id="green-center">

Output on Firefox, Google Chrome and IE:

enter image description here

Atonsah answered 15/1, 2015 at 12:9 Comment(9)
you have completely broke his design ^^Trevethick
I don't get it. What did you mean by that? My english is not very good.Atonsah
Just run the "code snippet" of the OP ask and compare with the result you suggestTrevethick
Appreciate the effort you have putting in getting this done with just CSS. Excellent work. But a note of caution to future readers, such complex shapes are better achieved using SVG or other techniques as CSS wasn't really designed for such sort of things.Presentative
@Presentative Thanks! I took like half an hour just to make this shape! I think with SVG it can be done in just about 5-10 mins.Atonsah
That is really great i never thought that it was possible with css thanks +1Silly
@Silly Thanks! If more sides are needed (orange ones), you simply have to calculate the degree and rotate. Btw doesn't this apply better to your original question?Atonsah
@ThePragmatick Yes got it i accepted his answer because it is not that complex your is really good and is worth a green tick but there is only one tick right.. but for your effort +2Silly
If you want to discuss about this chat.stackoverflow.com/rooms/68886/…Silly
T
3

Try this pure css:

*{box-sizing: border-box;padding: 0; margin: 0}
nav,nav:before{
    border-radius:50%;
    background:green
}
nav{
    width:200px;
    height:200px;
    margin: 40px auto;
    position: relative;
    overflow: hidden
}
nav:before{
    content: '';
    position:absolute;
    top: 50%;
    left: 50%;
    width: 100px;
    height: 100px;
    z-index: 2;
    transform: translate3d(-50%,-50%,0)
}
#incircle{
    width:100px;
    height:100px;
    border-radius:50%;
    border:50px dotted orange;
}

nav a{
    position: absolute;
    z-index: 1;
    cursor: pointer;
    width: 0px;
    height: 0px;
    border-top: 30px solid transparent;
    border-bottom: 30px solid transparent
}
nav a:nth-child(3),nav a:nth-child(4){
    left: 70px;
    border-left: 30px solid transparent;
    border-right: 30px solid transparent
}

nav a:first-child{
    top: 70px;
    left: 0;
    border-left: 100px solid orange
}
nav a:nth-child(2){
    left: 20px;
    border-left: 100px solid orange;
    top: 20px;
    transform: rotateZ(60deg);
}
nav a:nth-child(3){
    transform: rotateZ(30deg);
    top: 0px;
    left: 86px;
    border-top: 100px solid orange;
}
nav a:nth-child(4){
    left: 46px;
    border-bottom: 100px solid orange;
    bottom: -4px;
    transform: rotateZ(28deg);
}
nav a:nth-child(5){
    right: 24px;
    border-right: 100px solid orange;
    bottom: 20px;
    transform: rotateZ(60deg);
}
nav a:last-child{
    top: 70px;
    right: 0;
    border-right: 100px solid orange
}
<nav> 
    <a></a>
    <a></a>
    <a></a>
    
    <a></a>
    <a></a>
    <a></a>
</nav>
Tirade answered 14/1, 2015 at 12:58 Comment(2)
from using borders- I feel it could be loosing definition between the green and orange sections. But still, it's better than my solution (IMO)Carlyn
Yea same thing as @Carlyn mentions. The link area has expanded wide off the mark.Atonsah
T
3

You could use a map, like this :

#circle{
    position:relative;
    width:200px;
    height:200px;
    border-radius:50%;
    background:green;
}

#mappinglink{
    position:absolute;
    top:0px;
    left:0px;
}

#incircle{
    width:100px;
    height:100px;
    border-radius:50%;
    border:50px dotted orange;
    border-spacing: 10px 50px;
}
<div id="circle">
    <div id="incircle"></div>
    <img id="mappinglink" width="200" height="200" usemap="#mymap" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"/>
    <map name="mymap">
        <area  alt="" title="" href="#" shape="poly" coords="29,28,71,3,84,50,64,64" style="outline:none;" target="_self"     />
        <area  alt="" title="" href="#" shape="poly" coords="148,12,122,55,142,73,184,46" style="outline:none;" target="_self"     />
        <area  alt="" title="" href="#" shape="poly" coords="149,96,199,93,192,142,146,121" style="outline:none;" target="_self"     />
        <area  alt="" title="" href="#" shape="poly" coords="105,149,128,141,159,180,112,200" style="outline:none;" target="_self"     />
        <area  alt="" title="" href="#" shape="poly" coords="59,133,79,147,65,193,23,164" style="outline:none;" target="_self"     />
        <area  alt="" title="" href="#" shape="poly" coords="48,87,50,108,3,120,4,71" style="outline:none;" target="_self"     />
    </map>
</div>
Trevethick answered 14/1, 2015 at 13:3 Comment(2)
Nice approach. But since you define a fixed no. of points, a considerable amount of area is not under the link (towards the outer circumference.)Atonsah
Don't understand, that's what the OP was looking for if you see the provided example in the fiddle.Trevethick
I
1

Here's a fiddle.

HTML

<div id="circle">
    <a id='left' href='left'></a>
    <a id='right' href='right'></a>
    <div id="mid"></div>
</div>

CSS

#circle{
    width: 200px;
    height: 200px;
    border-radius: 50%;
    position: relative;
    overflow: hidden;
}

a {
    height: 100%;
    width: 49%;
    background: orange;
    display: block;
}

#left {
    float: left;
}

#right {
    float: right;
}

#mid {
    border-radius: 50%;
    background: green;
    border: 4px solid white;
    position: absolute;
    display: block;
    height: 50%;
    width: 50%;
    left: 24%;
    top: 24%;
}

This can be trivially expanded to 4 parts instead of 2 by splitting up the a's vertically. However I recommend you look at something like RaphaelJS . You could even cheat and use a pie chart!

Incitement answered 14/1, 2015 at 12:50 Comment(2)
Thanks a that was good but i need space between them if i try it with border it almost works except that even the space will become linksSilly
@Akshay, here is another where the borders don't link: jsfiddle.net/4ns3bc9h/16Incitement
C
1

I was trying to use pure css, And came up with this:

.wrap {
  height: 200px;
  width: 200px;
  background: red;
  border-radius: 50%;
  position: relative;
  overflow: hidden;
}
.wrap:after {
  position: absolute;
  height: 50%;
  width: 50%;
  content: "";
  border-radius: 50%;
  background: green;
  left: 25%;
  top: 25%;
}
.slice {
  height: 0;
  width: 0;
  border-left: 200px solid blue;
  border-top: 200px solid transparent;
  position: absolute;
  top: -100px;
  left: -100px;
}
.part2 {
  border-left: 200px solid red;
  border-top: 200px solid transparent;
  transform: rotate(180deg);
  top: -100px;
  left: -100px;
}
.part3 {
  border-left: 200px solid pink;
  border-top: 200px solid transparent;
  transform: rotate(90deg);
  top: -100px;
  left: 100px;
}
<div class="wrap">
  <a href="#" class="slice"></a>
  <div class="slice part2"></div>
  <a href="#" class="slice part3"></a>
</div>

However, this is using the "border trick" to generate the blue div, and this would make part of it clickable. However, I do feel this when adapted, could work.

  • Or, if you were interested/open to using SCSS this
  • Or, you could use this as a basis for your design

Something like

var items = document.querySelectorAll('.circle a');

for(var i = 0, l = items.length; i < l; i++) {
  items[i].style.left = (50 - 35*Math.cos(-0.5 * Math.PI - 2*(1/l)*i*Math.PI)).toFixed(4) + "%";
  
  items[i].style.top = (50 + 35*Math.sin(-0.5 * Math.PI - 2*(1/l)*i*Math.PI)).toFixed(4) + "%";
}

document.querySelector('.menu-button').onclick = function(e) {
   e.preventDefault(); document.querySelector('.circle').classList.toggle('open');
}
@import "http://netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css";

body {
  background: #39D;
}

.circular-menu {
  width: 250px;
  height: 250px;
  margin: 0 auto;
  position: relative;
}

.circle {
  width: 250px;
  height: 250px;
  opacity: 0;
  
  -webkit-transform: scale(0);
  -moz-transform: scale(0);
  transform: scale(0);

  -webkit-transition: all 0.4s ease-out;
  -moz-transition: all 0.4s ease-out;
  transition: all 0.4s ease-out;
}

.open.circle {
  opacity: 1;

  -webkit-transform: scale(1);
  -moz-transform: scale(1);
  transform: scale(1);
}

.circle a {
  text-decoration: none;
  color: white;
  display: block;
  height: 40px;
  width: 40px;
  line-height: 40px;
  margin-left: -20px;
  margin-top: -20px;
  position: absolute;
  text-align: center;

}

.circle a:hover {
  color: #eef;
}

.menu-button {
  position: absolute;
  top: calc(50% - 30px);
  left: calc(50% - 30px);
  text-decoration: none;
  text-align: center;
  color: #444;
  border-radius: 50%;
  display: block;
  height: 40px;
  width: 40px;
  line-height: 40px;
  padding: 10px;
  background: #dde;
}

.menu-button:hover {
  background-color: #eef;
}

/* Author stuff */
h1.author {
  text-align:center;
  color: white;
  font-family: Helvetica, Arial, sans-serif;
  font-weight: 300;
}

h1.author a {
  color: #348;
  text-decoration:none;
}

h1.author a:hover {
  color: #ddd;
} 
<nav class="circular-menu">

  <div class="circle">
    <a href="" class="fa fa-home fa-2x"></a>
    <a href="" class="fa fa-facebook fa-2x"></a>
    <a href="" class="fa fa-twitter fa-2x"></a>
    <a href="" class="fa fa-linkedin fa-2x"></a>
    <a href="" class="fa fa-github fa-2x"></a>
    <a href="" class="fa fa-rss fa-2x"></a>
    <a href="" class="fa fa-pinterest fa-2x"></a>
    <a href="" class="fa fa-asterisk fa-2x"></a>
  </div>
  
  <a href="" class="menu-button fa fa-bars fa-2x"></a>

</nav>
  
Carlyn answered 14/1, 2015 at 13:32 Comment(0)
A
0

This sounds like a job for SVG. It has its own type of <a> element that can contain arbitrary shapes.

Ambit answered 14/1, 2015 at 12:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.