'How to create a lollipop shape by stacking divs in a circular manner?

How to stack divs in a circular manner in which last div should come beneath the first div but above the second last div. Is it possible with the css? any helps would be appreciated.

enter image description here

Please find the Codepen. Giving the sample code snippet

<div class="frame">
  <div class="lolly-pop__wrapper">
    <div class="lollypop-top">
      <div class="lollypop-top__item"></div>
      <div class="lollypop-top__item"></div>
      <div class="lollypop-top__item"></div>
      <div class="lollypop-top__item"></div>
      <div class="lollypop-top__item"></div>
      <div class="lollypop-top__item"></div>
      <div class="lollypop-top__item"></div>
      <div class="lollypop-top__item"></div>
      <div class="lollypop-top__item"></div>
      <div class="lollypop-top__item"></div>
      <div class="lollypop-top__item"></div>
      <div class="lollypop-top__item"></div>
    </div>
  </div>
</div>


.frame {
  position: absolute;
  display: flex;
  justify-content: center;
  top: 50%;
  left: 50%;
  width: 400px;
  height: 400px;
  margin-top: -200px;
  margin-left: -200px;
  border-radius: 2px;
  box-shadow: 4px 8px 16px 0 rgba(0,0,0,0.1);
  overflow: hidden;
  background: #F5CE51;
  color: #333;
  font-family: 'Open Sans', Helvetica, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.lollypop-top {
    position: relative;
    height: 150px;
    width: 150px;
    background-color: #fff;
    border-radius: 100%;
    overflow: hidden;

    .lollypop-top__item {
        position: absolute;
        height: 150px;
        width: 150px;
        top: -50%;
        border-radius: 100%;
        transform-origin: bottom;
        background-color: #fff;

        &:nth-child(odd) {
            background-color: #D70606;
        }

        &:nth-child(1) {
            transform: rotate(30deg);
        }

        &:nth-child(2) {
            transform: rotate(60deg);
        }

        &:nth-child(3) {
            transform: rotate(90deg);
        }

        &:nth-child(4) {
            transform: rotate(120deg);
        }

        &:nth-child(5) {
            transform: rotate(150deg);
        }

        &:nth-child(6) {
            transform: rotate(180deg);
        }

        &:nth-child(7) {
            transform: rotate(210deg);
        }

        &:nth-child(8) {
            transform: rotate(240deg);
        }

        &:nth-child(9) {
            transform: rotate(270deg);
        }

        &:nth-child(10) {
            transform: rotate(300deg);
        }

        &:nth-child(11) {
            transform: rotate(330deg);
        }

        &:nth-child(12) {
            transform: rotate(360deg);
        }
      }
    }

.frame {
  position: absolute;
  display: flex;
  justify-content: center;
  top: 50%;
  left: 50%;
  width: 400px;
  height: 400px;
  margin-top: -200px;
  margin-left: -200px;
  border-radius: 2px;
  box-shadow: 4px 8px 16px 0 rgba(0, 0, 0, 0.1);
  overflow: hidden;
  background: #F5CE51;
  color: #333;
  font-family: 'Open Sans', Helvetica, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.lollypop-top {
  position: relative;
  height: 150px;
  width: 150px;
  background-color: #fff;
  border-radius: 100%;
  overflow: hidden;
}

.lollypop-top .lollypop-top__item {
  position: absolute;
  height: 150px;
  width: 150px;
  top: -50%;
  border-radius: 100%;
  transform-origin: bottom;
  background-color: #fff;
}

.lollypop-top .lollypop-top__item:nth-child(odd) {
  background-color: #D70606;
}

.lollypop-top .lollypop-top__item:nth-child(1) {
  transform: rotate(30deg);
}

.lollypop-top .lollypop-top__item:nth-child(2) {
  transform: rotate(60deg);
}

.lollypop-top .lollypop-top__item:nth-child(3) {
  transform: rotate(90deg);
}

.lollypop-top .lollypop-top__item:nth-child(4) {
  transform: rotate(120deg);
}

.lollypop-top .lollypop-top__item:nth-child(5) {
  transform: rotate(150deg);
}

.lollypop-top .lollypop-top__item:nth-child(6) {
  transform: rotate(180deg);
}

.lollypop-top .lollypop-top__item:nth-child(7) {
  transform: rotate(210deg);
}

.lollypop-top .lollypop-top__item:nth-child(8) {
  transform: rotate(240deg);
}

.lollypop-top .lollypop-top__item:nth-child(9) {
  transform: rotate(270deg);
}

.lollypop-top .lollypop-top__item:nth-child(10) {
  transform: rotate(300deg);
}

.lollypop-top .lollypop-top__item:nth-child(11) {
  transform: rotate(330deg);
}

.lollypop-top .lollypop-top__item:nth-child(12) {
  transform: rotate(360deg);
}
<div class="frame">
  <div class="lolly-pop__wrapper">
    <div class="lollypop-top">
      <div class="lollypop-top__item"></div>
      <div class="lollypop-top__item"></div>
      <div class="lollypop-top__item"></div>
      <div class="lollypop-top__item"></div>
      <div class="lollypop-top__item"></div>
      <div class="lollypop-top__item"></div>
      <div class="lollypop-top__item"></div>
      <div class="lollypop-top__item"></div>
      <div class="lollypop-top__item"></div>
      <div class="lollypop-top__item"></div>
      <div class="lollypop-top__item"></div>
      <div class="lollypop-top__item"></div>
    </div>
  </div>
</div>


Solution 1:[1]

My approach would be a reusable SVG <symbol>, with paths shaped by quadratic-bézier curves:

#svg-lollipop path { transform-origin: 50% 50%; }

#svg-lollipop path:nth-child(2) {  transform: rotateZ(60deg); }
#svg-lollipop path:nth-child(3) {  transform: rotateZ(120deg); }
#svg-lollipop path:nth-child(4) {  transform: rotateZ(180deg); }
#svg-lollipop path:nth-child(5) {  transform: rotateZ(240deg); }
#svg-lollipop path:nth-child(6) {  transform: rotateZ(300deg); }

.lollipop {
  width: 30%;
  display: inline-block;
  overflow: hidden;
  border-radius: 50%;
  position: relative;
  margin: 0 20px;
  aspect-ratio: 1;
}

.lollipop svg {
  position: absolute;  
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
  height: 100%;
  fill: currentColor;
}

.lollipop--animated {
  animation: rotate 10s linear 0s infinite;
}

@keyframes rotate {
  0% { transform: rotateZ(0) }
  100% { transform: rotateZ(1turn) }
}
<svg style="display: none;">
   <symbol id="svg-lollipop">
      <path d="M150,150 Q75,185 0,150 H0 V63.6 Q75,150 150,150 z" />
      <path d="M150,150 Q75,185 0,150 H0 V63.6 Q75,150 150,150 z" />
      <path d="M150,150 Q75,185 0,150 H0 V63.6 Q75,150 150,150 z" />
      <path d="M150,150 Q75,185 0,150 H0 V63.6 Q75,150 150,150 z" />
      <path d="M150,150 Q75,185 0,150 H0 V63.6 Q75,150 150,150 z" />
      <path d="M150,150 Q75,185 0,150 H0 V63.6 Q75,150 150,150 z" />
   </symbol>
</svg>

<div class="lollipop lollipop--animated" 
  style="background-color: #FFF; color:#E92120;">
  <svg viewBox="0 0 300 300"><use xlink:href="#svg-lollipop"></use></svg>
</div>

<div class="lollipop" 
  style="background-color: #004991; color:#007BC1;">
  <svg viewBox="0 0 300 300"><use xlink:href="#svg-lollipop"></use></svg>
</div>

How it works

The same shape was cloned 6 times and rotated in order to fill the whole svg. In this example, every coloured shape has an angle ? = 30deg.

Then from trigonometry we can find the coordinates of the origin points for the curves: in the path the y-coordinate 63.6 is obtained as 150 - (150 * tan(?)), so if you need to change the amount of shapes and the angle, you can easily find yourself the origin points (quadratic curves are really easy to draw).

Finally, the outer wrapper has a border-radius and a hidden overflow in order to give a rounded shape.

enter image description here


The final result is also responsive, since the outer wrapper keeps its 1:1 aspect ratio.

The white area can be changed with a background-color set on the container, the coloured area can be changed instead with the color property (the fill property of the svg elements is set to currentColor for your convenience).


something I've noticed later

if you add a box-shadow: inset 0 0 20px #aaa; to the wrapper the image looks like an inflatable beach balloon than a lollipop.

Serendipity.

Solution 2:[2]

Checkout this answer as well.Codepen

<div class="frame">
<div class="lolly-pop__wrapper">
<div class="lollypop-top">
    <div class="first__half">
        <div class="lollypop-top__item"></div>
        <div class="lollypop-top__item"></div>
        <div class="lollypop-top__item"></div>
        <div class="lollypop-top__item"></div>
        <div class="lollypop-top__item"></div>
        <div class="lollypop-top__item"></div>
        <div class="lollypop-top__item"></div>
        <div class="lollypop-top__item"></div>
        <div class="lollypop-top__item"></div>
        <div class="lollypop-top__item"></div>
        <div class="lollypop-top__item"></div>
        <div class="lollypop-top__item"></div>
        <div class="lollypop-top__item"></div>
        <div class="lollypop-top__item"></div>
    </div>
        <div class="second__half">
        <div class="lollypop-top__item"></div>
        <div class="lollypop-top__item"></div>
        <div class="lollypop-top__item"></div>
        <div class="lollypop-top__item"></div>
        <div class="lollypop-top__item"></div>
        <div class="lollypop-top__item"></div>
        <div class="lollypop-top__item"></div>
        <div class="lollypop-top__item"></div>
        <div class="lollypop-top__item"></div>
        <div class="lollypop-top__item"></div>
        <div class="lollypop-top__item"></div>
        <div class="lollypop-top__item"></div>
        <div class="lollypop-top__item"></div>
        <div class="lollypop-top__item"></div>
    </div>
</div>
</div>
</div>


.frame {
  position: absolute;
  display: flex;
  justify-content: center;
  top: 50%;
  left: 50%;
  width: 400px;
  height: 400px;
  margin-top: -200px;
  margin-left: -200px;
  border-radius: 2px;
  box-shadow: 4px 8px 16px 0 rgba(0,0,0,0.1);
  overflow: hidden;
  background: #F5CE51;
  color: #333;
  font-family: 'Open Sans', Helvetica, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.lollypop-top {
    position: relative;
    height: 150px;
    width: 150px;
    background-color: #ccc;
    border-radius: 100%;
    overflow: hidden;

.lollypop-top__item {
    position: absolute;
    height: 150px;
    width: 150px;
    top: -50%;
    border-radius: 100%;
    transform-origin: bottom;
    background-color: #fff;

    &:nth-child(odd) {
        background-color: #D70606;
    }

    &:nth-child(1) {
        transform: rotate(30deg);
    }

    &:nth-child(2) {
        transform: rotate(60deg);
    }

    &:nth-child(3) {
        transform: rotate(90deg);
    }

    &:nth-child(4) {
        transform: rotate(120deg);
    }

    &:nth-child(5) {
        transform: rotate(150deg);
    }

    &:nth-child(6) {
        transform: rotate(180deg);
    }

    &:nth-child(7) {
        transform: rotate(210deg);
    }

    &:nth-child(8) {
        transform: rotate(240deg);
    }

    &:nth-child(9) {
        transform: rotate(270deg);
    }

    &:nth-child(10) {
        transform: rotate(300deg);
    }

    &:nth-child(11) {
        transform: rotate(330deg);
    }

    &:nth-child(12) {
        transform: rotate(360deg);
    }

    &:nth-child(13) {
        transform: rotate(390deg);
    }

    &:nth-child(14) {
        transform: rotate(420deg);
    }
  }
}

.first__half,
.second__half {
    position: absolute;
    left: 0;
    top: 0;
    height: 100%;
    overflow: hidden;
}

.first__half {
    width: 50%;
}

.second__half {
    right: 0;
    width: 50%;
    transform: rotate(180deg);
    transform-origin:right center;
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Vivekraj K R