8

I am trying to create a pointy leaf shape in CSS, as in the image:

I managed to figure out a way to create a default leaf shape, but have some issues in finding out how to create the pointy corners. I am only looking for ways of creating half of the leaf, as I intend to draw the image to animate it, and each half of the leaves will be independent. Is there a way to create that shape using CSS?

Default leaf shape: https://jsfiddle.net/xwvyo1c5/

.leaf { 
  width: 100px; height: 100px;
  background-color: #A0DE21; 
  -moz-border-radius: 100px 0px;
  -webkit-border-radius: 100px 0px;
  border-radius: 100px 0px;
}
loleck
  • 83
  • 1
  • 4
  • 3
    Have you considered using SVG? – web-tiki Nov 23 '15 at 15:51
  • I don't have any experience with SVG yet, and as I need to animate (by animate I mean give the leaves a fan-like movement on click, to sort of open up) I checked multiple CSS animations techniques which might give me what I'm looking for in the end – loleck Nov 23 '15 at 15:57
  • 1
    CSS isn't the right tool to make double curves like the leaf you are trying to make. SVG is [way more appropriate](http://stackoverflow.com/a/28988476/1811992). And although it seems more complicated, it is highly animatable. – web-tiki Nov 23 '15 at 16:02

4 Answers4

8

As the others user have told you... that is a very difficult shape to be done with CSS's. SVG is the way to go.

Even if you are new to it don't be afraid, it's not as hard as it looks.

You could always use a svg generator online (plenty around) to create the shape that will be repeated many times. For this example I have use this generator online to get this code:

<svg  xmlns="http://www.w3.org/2000/svg" style="vector-effect: non-scaling-stroke;" stroke="null">
 <g stroke="null">
  <path stroke="#f90202" d="m70,159c102,-16.597 98.862,-36 138,-35c39.138,-2 49,19.403 134,35c-2,-0.403 -62.862,0 -138,0c-72.138,-1 -135,0.597 -134,0z" id="svg_10" stroke-linecap="null" stroke-linejoin="null" stroke-dasharray="null" stroke-width="0" fill="#fc0202"/>
 </g>
</svg>  

Notice, please, this is a rough shape. I did it in a few seconds and for your project you may need to spend a bit more time to make the shape better.

Then I have just put the code into a container, duplicate it 7 times, and absolute positioned every container with top, leftand rotate.

And this is the final result: JSFIDDLE

.leaf1 {
  position: absolute;
  top: 100px;
  left: 0;
}
.leaf2 {
  position: absolute;
  top: 100px;
  left: 200px;
}
.leaf3 {
  position: absolute;
  top: 135px;
  left: 83px;
  transform: rotate(-90deg);
}
.leaf4 {
  position: absolute;
  top: 18px;
  left: 233px;
  transform: rotate(90deg);
}
.leaf5 {
  position: absolute;
  top: 11px;
  left: 99px;
  transform: rotate(45deg);
}
.leaf6 {
  position: absolute;
  top: 199px;
  left: 75px;
  transform: rotate(-135deg);
}
.leaf7 {
  position: absolute;
  top: 115px;
  left: 324px;
  transform: rotate(135deg);
}
.leaf8 {
  position: absolute;
  top: 91px;
  left: 136px;
  transform: rotate(-45deg);
}
<div class="leaf1">
  <svg xmlns="http://www.w3.org/2000/svg" style="vector-effect: non-scaling-stroke;" stroke="null">
    <g stroke="null">
      <path stroke="#f90202" d="m70,159c102,-16.597 98.862,-36 138,-35c39.138,-2 49,19.403 134,35c-2,-0.403 -62.862,0 -138,0c-72.138,-1 -135,0.597 -134,0z" id="svg_10" stroke-linecap="null" stroke-linejoin="null" stroke-dasharray="null" stroke-width="0" fill="#fc0202"
      />
    </g>
  </svg>
</div>
<div class="leaf2">
  <svg xmlns="http://www.w3.org/2000/svg" style="vector-effect: non-scaling-stroke;" stroke="null">
    <g stroke="null">
      <path stroke="#f90202" d="m70,159c102,-16.597 98.862,-36 138,-35c39.138,-2 49,19.403 134,35c-2,-0.403 -62.862,0 -138,0c-72.138,-1 -135,0.597 -134,0z" id="svg_10" stroke-linecap="null" stroke-linejoin="null" stroke-dasharray="null" stroke-width="0" fill="#fc0202"
      />
    </g>
  </svg>
</div>
<div class="leaf3">
  <svg xmlns="http://www.w3.org/2000/svg" style="vector-effect: non-scaling-stroke;" stroke="null">
    <g stroke="null">
      <path stroke="#f90202" d="m70,159c102,-16.597 98.862,-36 138,-35c39.138,-2 49,19.403 134,35c-2,-0.403 -62.862,0 -138,0c-72.138,-1 -135,0.597 -134,0z" id="svg_10" stroke-linecap="null" stroke-linejoin="null" stroke-dasharray="null" stroke-width="0" fill="#fc0202"
      />
    </g>
  </svg>
</div>
<div class="leaf4">
  <svg xmlns="http://www.w3.org/2000/svg" style="vector-effect: non-scaling-stroke;" stroke="null">
    <g stroke="null">
      <path stroke="#f90202" d="m70,159c102,-16.597 98.862,-36 138,-35c39.138,-2 49,19.403 134,35c-2,-0.403 -62.862,0 -138,0c-72.138,-1 -135,0.597 -134,0z" id="svg_10" stroke-linecap="null" stroke-linejoin="null" stroke-dasharray="null" stroke-width="0" fill="#fc0202"
      />
    </g>
  </svg>
</div>
<div class="leaf5">
  <svg xmlns="http://www.w3.org/2000/svg" style="vector-effect: non-scaling-stroke;" stroke="null">
    <g stroke="null">
      <path stroke="#f90202" d="m70,159c102,-16.597 98.862,-36 138,-35c39.138,-2 49,19.403 134,35c-2,-0.403 -62.862,0 -138,0c-72.138,-1 -135,0.597 -134,0z" id="svg_10" stroke-linecap="null" stroke-linejoin="null" stroke-dasharray="null" stroke-width="0" fill="#fc0202"
      />
    </g>
  </svg>
</div>
<div class="leaf6">
  <svg xmlns="http://www.w3.org/2000/svg" style="vector-effect: non-scaling-stroke;" stroke="null">
    <g stroke="null">
      <path stroke="#f90202" d="m70,159c102,-16.597 98.862,-36 138,-35c39.138,-2 49,19.403 134,35c-2,-0.403 -62.862,0 -138,0c-72.138,-1 -135,0.597 -134,0z" id="svg_10" stroke-linecap="null" stroke-linejoin="null" stroke-dasharray="null" stroke-width="0" fill="#fc0202"
      />
    </g>
  </svg>
</div>
<div class="leaf7">
  <svg xmlns="http://www.w3.org/2000/svg" style="vector-effect: non-scaling-stroke;" stroke="null">
    <g stroke="null">
      <path stroke="#f90202" d="m70,159c102,-16.597 98.862,-36 138,-35c39.138,-2 49,19.403 134,35c-2,-0.403 -62.862,0 -138,0c-72.138,-1 -135,0.597 -134,0z" id="svg_10" stroke-linecap="null" stroke-linejoin="null" stroke-dasharray="null" stroke-width="0" fill="#fc0202"
      />
    </g>
  </svg>
</div>
<div class="leaf8">
  <svg xmlns="http://www.w3.org/2000/svg" style="vector-effect: non-scaling-stroke;" stroke="null">
    <g stroke="null">
      <path stroke="#f90202" d="m70,159c102,-16.597 98.862,-36 138,-35c39.138,-2 49,19.403 134,35c-2,-0.403 -62.862,0 -138,0c-72.138,-1 -135,0.597 -134,0z" id="svg_10" stroke-linecap="null" stroke-linejoin="null" stroke-dasharray="null" stroke-width="0" fill="#fc0202"
      />
    </g>
  </svg>
</div>
Alvaro Menéndez
  • 8,766
  • 3
  • 37
  • 57
7

you can change a bit the shape altering the initial border-radius values, background-gradient can help to draw lines too :

I'm aware it is not the answer, just see css options ( for bg gradient look for bg pattern to learn more) it can avoid the use of SVG for basic shapes or pattern.

body {
  padding: 1em;
}

.leaf {
  width: 80px;
  height: 140px;
  background-image: linear-gradient(to top left, #A0DE21 49%, transparent 49.5%, transparent 51%, #A0DE21 51%);
  -moz-border-radius: 100% /120px 0px;
  -webkit-border-radius: 100% / 120px 0px;
  border-radius: 100% 0 / 140px 0px;
}
<div class="leaf"></div>

3 leaves could be

body {
  padding: 1em;
}

.leaf, .leaf:last-of-type {
  box-shadow: -1px 1px 2px #835d46;
  width: 80px;
  height: 140px;
  background-image: linear-gradient(to top left, #A0DE21 49%, transparent 49.5%, transparent 51%, #A0DE21 51%);
  -moz-border-radius: 100% /120px 0px;
  -webkit-border-radius: 100% / 120px 0px;
  border-radius: 100% 0 / 140px 0px;
  display:inline-block;
  transform:rotate(15deg);
  margin:0 -0.5em;
}
.leaf:first-of-type {  
  background-image: linear-gradient(to top right, #A0DE21 49%, transparent 49.5%, transparent 51%, #A0DE21 51%);
  border-radius: 0 100%  /0  140px ;  
  transform:rotate(-15deg);
}
.leaf:first-child + .leaf {
  transform:rotate(-29deg);
  vertical-align:1.3em;
  margin:0 -1em;
}
<div class="leaf"></div>
<div class="leaf"></div>
<div class="leaf"></div>
G-Cyrillus
  • 101,410
  • 14
  • 105
  • 129
4

CSS is a technology whose main target is to separate style information from content (HTML) and behaviour (scripts server and client side).

Sure, it allow you to make some pretty and quite fluid animations (called transitions) which are mainly oriented to translate elements between different states, but this doesn't mean that it's capable or a good option for shape drawing or animation.

Nevertheless, there are people working on it and making remarkable progress, althoug IMHO this wouldn't be a desired approach to the problem. Check, for example: https://www.css-tricks.com/examples/ShapesOfCSS/

SVG and HTML5 Canvas are technologies that have been designed with vectorial graphics development in mind. They are designed for that, they are efficient, powerful and standard, and they'll allow you to fulfill your needs faster and in a better way than if you try to use a technology that's not fit for the problem.

They are, definitively, your way to go.

Mogsdad
  • 44,709
  • 21
  • 151
  • 275
Bardo
  • 2,470
  • 2
  • 24
  • 42
3

CSS

This is a very hard thing to do and i would almost certainly recommend you do it in SVG.

But as you have requested it in CSS and it is in some ways possible in CSS (albeit the design is a bit off), I will show a possible CSS way and let you edit it to your hearts content and work on an SVG answer in the mean time.

This uses positioning and transforms to rotate the elements into place.

.container {
  width: 400px;
  height: 200px;
  overflow: hidden;
  position: relative;
}
.leaf {
  position: absolute;
  width: 30px;
  height: 100px;
  top: 25px;
  left: calc(50% - 15px);
  transition: all 0.2s ease;
}
.leaf:hover {
  width: 34px;
  left: calc(50% - 17px);
}
.leaf:before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  width: 15px;
  height: 100%;
  background: red;
  border-radius: 15px 0 0 15px / 50px 0 0 50px;
}
.leaf:after {
  content: '';
  position: absolute;
  top: 0;
  right: 0;
  width: 15px;
  height: 100%;
  background: red;
  border-radius: 0 15px 15px 0 / 0 50px 50px 0;
}
.leaf:nth-child(1) {
  transform-origin: 0% 150%;
  transform: rotate(-90deg);
}
.leaf:nth-child(2) {
  transform-origin: 0% 150%;
  transform: rotate(-45deg);
}
.leaf:nth-child(3) {
  transform-origin: 100% 150%;
  transform: rotate(45deg);
}
.leaf:nth-child(5) {
  transform-origin: 100% 150%;
  transform: rotate(90deg);
}
<div class="container">
  <div class="leaf"></div>
  <div class="leaf"></div>
  <div class="leaf"></div>
  <div class="leaf"></div>
  <div class="leaf"></div>
</div>
Stewartside
  • 20,378
  • 12
  • 60
  • 81