Pointy leaf shape - css

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;
}

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>

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>

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.

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>

Related

How to rotate multiple SVG reused elements around same origin?

How can I rotate 3 irregular SVG circles around same origin? They are written as a path and reused. I have set transform-origin to center, what else am I missing? They should all be in the same space and overlap in center like in this image
<svg width="900" height="500" viewBox="0 0 900 500">
<defs>
<path id="circle" d="m 43.467262,110.65774 c -2.81733,25.95379 9.663408,54.24201 33.479611,66.3315 12.768318,6.52194 29.493997,6.26667 40.854417,-3.07058 12.79824,-9.29014 25.48168,-19.76411 33.26937,-33.78136 4.54432,-8.49226 5.12542,-19.52979 -0.73083,-27.56368 C 142.27364,100.40343 128.56364,93.579328 115.25185,88.674523 98.350761,82.775856 78.939082,80.223234 62.116925,87.733369 52.940099,92.163321 45.975566,100.79364 43.467262,110.65774 Z" />
</defs>
<g class="group">
<use class="circle circle--1" xlink:href="#circle" />
<use class="circle circle--2" xlink:href="#circle" />
<use class="circle circle--3" xlink:href="#circle" />
</g>
</svg>
svg {
width: 900px;
path {
stroke: #333;
stroke-width: 3px;
fill: transparent;
}
}
g {
position: relative;
transform-origin: center center;
}
.circle {
transform-origin: 50% 50%;
perspective: 500px;
&--1 {
transform: rotateZ(60deg);
}
&--2 {
transform: rotateZ(120deg);
}
&--3 {
transform: rotateZ(180deg);
}
}
https://codepen.io/anon/pen/mQdLvX
You want transform-box: fill-box; i.e.
.circle {
transform-box: fill-box;
transform-origin: 50% 50%;
perspective: 500px;
&--1 {
transform: rotateZ(60deg);
}
&--2 {
transform: rotateZ(120deg);
}
&--3 {
transform: rotateZ(180deg);
}
}
When the svg draw is not centered on the canvas, this gets a bit more difficult. I've ajusted the SVG viewBox values, take a look at the following snippet:
svg {
border: 1px solid red;
}
svg path {
stroke: #333;
stroke-width: 3px;
fill: transparent;
}
.circle {
transform-origin: 50% 50%;
}
.circle--1 {
transform: rotateZ(90deg);
}
.circle--2 {
transform: rotateZ(160deg);
}
.circle--3 {
transform: rotateZ(270deg);
}
<svg width="900" height="500" viewBox="0 0 250 250">
<defs>
<path id="circle" d="m 43.467262,110.65774 c -2.81733,25.95379 9.663408,54.24201 33.479611,66.3315 12.768318,6.52194 29.493997,6.26667 40.854417,-3.07058 12.79824,-9.29014 25.48168,-19.76411 33.26937,-33.78136 4.54432,-8.49226 5.12542,-19.52979 -0.73083,-27.56368 C 142.27364,100.40343 128.56364,93.579328 115.25185,88.674523 98.350761,82.775856 78.939082,80.223234 62.116925,87.733369 52.940099,92.163321 45.975566,100.79364 43.467262,110.65774 Z" />
</defs>
<g class="group">
<use class="circle circle--1" xlink:href="#circle" />
<use class="circle circle--2" xlink:href="#circle" />
<use class="circle circle--3" xlink:href="#circle" />
</g>
</svg>

CSS: mix-blend-mode = color-dodge not working in Chrome but okay in Firefox

I am trying to use an effect where the same shape (SVG in my case) at different locations is overlayed, and its colors should be "color dodged". The shape is coming in the primary colors red, green and blue. Where all shapes meet, the color is white, and in other places combinations occur. I've created a pen at https://codepen.io/anon/pen/dgKQqz to demonstrate. In short, the styles:
body { background-color: #222; }
.demo { mix-blend-mode: color-dodge; }
.center { position: fixed; top: 50%; left: 50%; }
.pr { transform: translate(-30%, -50%); }
.pg { transform: translate(-80%, -50%); }
.pb { transform: translate(-50%, -30%); }
And the shapes:
<svg class="demo center pr" width="100" height="100">
<circle cx="50" cy="50" r="40" fill="#ff0000" />
</svg>
<svg class="demo center pg" width="100" height="100">
<circle cx="50" cy="50" r="40" fill="#00ff00" />
</svg>
<svg class="demo center pb" width="100" height="100">
<circle cx="50" cy="50" r="40" fill="#0000ff" />
</svg>
This works as I expect in Firefox (62), but no mixing seems to take place in Chrome (70). The issue is not with SVG, as even regular text in a div element behaves like described.
Am I doing something wrong, can this be achieved so it works in both browsers, or is this a Chrome bug?
In fact using the SVGs as background-image is working:
.demo {
width:100px;
height:100px;
mix-blend-mode: color-dodge;
}
body {
background-color: #222;
}
.center {
position: fixed;
top: 50%;
left: 50%;
}
.pr {
transform: translate(-30%, -50%);
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='100' height='100'%3E%3Ccircle cx='50' cy='50' r='40' fill='%23ff0000' /%3E%3C/svg%3E");
}
.pg {
transform: translate(-80%, -50%);
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='100' height='100'%3E%3Ccircle cx='50' cy='50' r='40' fill='%2300ff00' /%3E%3C/svg%3E");
}
.pb {
transform: translate(-50%, -30%);
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='100' height='100'%3E%3Ccircle cx='50' cy='50' r='40' fill='%230000ff' /%3E%3C/svg%3E");
}
<div class="demo center pr"></div>
<div class="demo center pg"></div>
<div class="demo center pb"></div>

CSS - Clip path svg not working on firefox

I'm trying to use clip path but this is not working on firefox.
I already search about this and i found this code in stack overflow.
I have several shapes implemented but this is just work in chrome and safari.
.shape
{
width: 300px;
height: 300px;
display: inline-block;
position: relative;
box-sizing: border-box;
-webkit-clip-path: url(#clipper);
-moz-clip-path: url(#clipper);
clip-path: url(#clipper);
background-color: $page-title-background-green;
}
img
{
position: absolute;
top: 2px;
left: 2px;
width: 296px;
height: 296px;
-webkit-clip-path: url(#clipper);
-moz-clip-path: url(#clipper);
clip-path: url(#clipper);
}
<svg width="0" height="0">
<defs>
<clipPath id="clipper" clipPathUnits="objectBoundingBox">
<polygon points=".15 0, .7 0, 1 .5, .7 1, .15 1, 0 .7, .2 .5, 0 .3"/>
</clipPath>
</defs>
</svg>
<div class="shape">
<img src="http://lorempixel.com/g/600/400/">
</div>
How can i solve that?
Thank's
I have this code:
<body>
<svg class="svg-defs">
<defs>
<clipPath id="clipping">
<polygon points="98.4999978 153.75 38.2520165 185.424245 49.7583542 118.337123 1.01670635 70.8257603 68.3760155 61.037872 98.5000012 1.1379786e-14 128.624005 61.0378871 195.98331 70.8258091 147.241642 118.337136 158.747982 185.424247"></polygon>
</clipPath>
</defs>
</svg>
<svg width="200" height="300">
<style type="text/css" media="screen">
image {
clip-path: url(#clipping);
}
</style>
<image xlink:href="http://img-fotki.yandex.ru/get/5607/5091629.6b/0_612e6_b9039c0d_M.jpg" width="200" height="300" />
</svg>
</body>
So, try to set the style inside your SVG element, or give a style attribute to image, like this:
<image style="clip-path: url(#clipping);" xlink:href="...">

SVG progress bar

I have a requirement where I need to load js files dynamically and show the progress of loading files through a SVG icon. The SVG icon will act as progress bar where it fills with a color from bottom to top, linearly.
Here is the codepen
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="79.36px" height="93.844px" viewBox="0 0 79.36 93.844">
<path fill="transparent" stroke="black" d="M50,2C30-4,8,7,2,28c-6,20,5,42,26,48h0l-4,15l33-18c0-0,0-0,1-0l0-0l-0-0c8-4,15-12,17-22C83,30,71,8,50,2z" />
</svg>
I am planning to make this icon independent such that I will only pass the percentage value dynamically.
I somehow able to get the animation done but unable to keep the border or outline of the svg. Here is the code.
#progressMove {
transition: .3s y;
}
#progressMove:hover {
y: 60%;
}
<svg id="kenseoProgress" width="79.36px" height="93.844px" viewBox="0 0 79.36 93.844">
<defs>
<mask id="bubbleKenseo">
<path fill="red" stroke="black" d="M50,2C30-4,8,7,2,28c-6,20,5,42,26,48h0l-4,15l33-18c0-0,0-0,1-0l0-0l-0-0c8-4,15-12,17-22C83,30,71,8,50,2z" />
</mask>
</defs>
<g x="0" y="0" width="79.36px" height="93.844px" mask="url(#bubbleKenseo)" height="100">
<rect id="progressMove" x="0" y="0%" width="100%" height="100%" fill="blue" stroke="black" />
</g>
</svg>
So, the problems I have are:
Unable to maintain the border to the SVG
Whatever the color I add is having some kind of opacity which I am unable to remove.
Edit: Browser compatibility: IE11+, chrome, safari and firefox
PS: I don't want to use SMIL animations.
CHROME/SAFARI SOLUTION
Using the CSS property transform and counter-increment you can achieve the fill and number increment.
jsFiddle
CODE SNIPPET
for (var i = 0; i < 100; i++) {
setTimeout(function() {
$(".progress-container p").append("<span>");
}, i * 20);
}
pattern #progressMove {
transform: translateY(100%);
color: purple;
animation: progressBar 2s steps(100, end) forwards;
}
#keyframes progressBar {
to {
transform: translateY(0);
}
}
.progress-container {
margin: 0;
display: inline-block;
position: relative;
counter-reset: progress;
}
.progress-container figcaption {
position: absolute;
top: 40%;
left: 50%;
transform: translate(-40%, -50%);
}
.progress-container p {
margin: 0;
font-weight: bold;
}
.progress-container span {
counter-increment: progress;
}
.progress-container p::after {
content: counter(progress)"%";
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<figure class="progress-container">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="79.36px" height="93.844px" viewBox="0 0 79.36 93.844">
<pattern id="progress" x="0" y="0" width="79.36" height="93.844" patternUnits="userSpaceOnUse">
<rect id="progressMove" x="0" y="0" width="100%" height="100%" stroke="none" fill="currentColor" />
</pattern>
<path fill="url(#progress)" stroke="#000" d="M50,2C30-4,8,7,2,28c-6,20,5,42,26,48h0l-4,15l33-18c0-0,0-0,1-0l0-0l-0-0c8-4,15-12,17-22C83,30,71,8,50,2z" />
</svg>
<figcaption>
<p>
</p>
</figcaption>
</figure>
Note:
Will update if I can give a better solution to cover browser support.
EDIT:
Based on Persijn answer, you will as well have to change the color of the background to that of its parent.
The whole component would be the figure element, sadly the symbol in the spritesheet will only be used to provide the path and background.
Note: jQuery removed in this version.
jsFiddle
for (var i = 0; i < 100; i++) {
setTimeout(function() {
var progressCounter = document.querySelector(".progress__counter"),
number = document.createElement("span");
progressCounter.appendChild(number);
}, i * 20);
}
#spritesheet {
display: none;
}
.icon {
display: inline-block;
width: 1em;
height: 1em;
}
.icon-bubble {
font-size: 7em;
color: white;
}
.progress-container {
margin: 0;
display: inline-block;
position: relative;
counter-reset: progress;
overflow: hidden;
line-height: 0;
}
.progress__inner {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: -1;
}
.progress__fill {
background-color: purple;
height: 100%;
transform: translateY(100%);
animation: progressFill 2s steps(100, end) forwards;
}
#keyframes progressFill {
to {
transform: translateY(0);
}
}
.progress__counter {
position: absolute;
top: 40%;
left: 50%;
transform: translate(-40%, -50%);
margin: 0;
font-weight: bold;
}
.progress__counter span {
counter-increment: progress;
}
.progress__counter::after {
content: counter(progress)"%";
}
<figure class="progress-container">
<svg class="icon icon-bubble">
<use xlink:href="#icon-bubble"></use>
</svg>
<figcaption class="progress__inner">
<div class="progress__fill"></div>
<p class="progress__counter"></p>
</figcaption>
</figure>
<svg id="spritesheet">
<symbol id="icon-bubble" viewBox="0 0 79.36 93.844">
<title>Loading Bubble</title>
<path id="bubble-cover" fill="currentColor" stroke="#000" d="M-10,-10 100,-10 100,100 -10,100 -10,-10 50,2C30-4,8,7,2,28c-6,20,5,42,26,48h0l-4,15l33-18c0-0,0-0,1-0l0-0l-0-0c8-4,15-12,17-22C83,30,71,8,50,2z" />
</symbol>
</svg>
TESTS:
Chrome 53
IE10
Edge
FireFox 47
IOS 10 Safari
PLAYGROUND
jsFiddle
for (var i = 0; i < 100; i++) {
setTimeout(function() {
var progressCounter = document.querySelector(".progress__counter"),
number = document.createElement("span");
progressCounter.appendChild(number);
}, i * 20);
}
#spritesheet {
display: none;
}
.icon {
display: inline-block;
width: 1em;
height: 1em;
}
.icon-bubble {
font-size: 7em;
color: white;
}
.progress-container {
margin: 0;
display: inline-block;
position: relative;
counter-reset: progress;
overflow: hidden;
line-height: 0;
}
.progress__inner {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: -1;
}
.progress__fill {
background-color: purple;
height: 100%;
transform: translateY(100%);
animation: progressFill 2s steps(100, end) forwards, progressFillColor 100ms linear 2s forwards;
position: relative;
}
#keyframes progressFill {
to {
transform: translateY(0);
}
}
#keyframes progressFillColor {
to {
background-color: green;
}
}
.progress__counter {
position: absolute;
top: 40%;
transform: translateY(-40%);
text-align: center;
width: 100%;
margin: 0;
font-weight: bold;
animation: progressCounter 100ms linear 1s forwards;
}
.progress__counter span {
counter-increment: progress;
}
.progress__counter::after {
content: counter(progress)"%";
animation: progressCounterCompleted 1s linear 2s forwards;
}
#keyframes progressCounter {
to {
color: white;
}
}
/* Chrome Only*/
#keyframes progressCounterCompleted {
33% {
content: "File(s)";
}
66% {
content: "Uploaded";
}
100% {
content: "Successfully!";
}
}
<figure class="progress-container">
<svg class="icon icon-bubble">
<use xlink:href="#icon-bubble"></use>
</svg>
<figcaption class="progress__inner">
<div class="progress__fill"></div>
<p class="progress__counter"></p>
</figcaption>
</figure>
<svg id="spritesheet">
<symbol id="icon-bubble" viewBox="0 0 79.36 93.844">
<title>Loading Bubble</title>
<path id="bubble-cover" fill="currentColor" stroke="#000" d="M-10,-10 100,-10 100,100 -10,100 -10,-10 50,2C30-4,8,7,2,28c-6,20,5,42,26,48h0l-4,15l33-18c0-0,0-0,1-0l0-0l-0-0c8-4,15-12,17-22C83,30,71,8,50,2z" />
</symbol>
</svg>
SVG with pattern and y transition:
svg:hover pattern #fillshape {
y: 0%;
}
pattern #fillshape {
transition: y 1s;
y: 100%;
}
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="79.36px" height="93.844px" viewBox="0 0 79.36 93.844">
<pattern id="pattern1"
x="0" y="0" width="79.36" height="93.844"
patternUnits="userSpaceOnUse" >
<rect id="fillshape" x="0" y="0" width="100%" height="200%" stroke="none" fill="purple" />
</pattern>
<path fill="url(#pattern1)" stroke="black" d="M50,2C30-4,8,7,2,28c-6,20,5,42,26,48h0l-4,15l33-18c0-0,0-0,1-0l0-0l-0-0c8-4,15-12,17-22C83,30,71,8,50,2z" />
</svg>
Now this does not work in Firefox or Edge. It does not recognize x and y as CSS properties...
Here is a solution that uses a div behind the svg shape.
The downside of this solution is that the svg shape gets a background eg. if you want the shape only you would have to match the background color of the shape with that of the background of the page.
svg {
position: relative;
}
.spesial {
width: 90px;
height: 0px;
display: inline-block;
background-color: purple;
margin-left: -100px;
transition: height 1s;
}
svg:hover + .spesial {
height: 100px;
}
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="100" height="100" viewBox="0 0 75 90">
<path stroke="black" fill="gray" d="M-10,-10 100,-10 100,100 -10,100 -10,-10 50,2C30-4,8,7,2,28c-6,20,5,42,26,48h0l-4,15l33-18c0-0,0-0,1-0l0-0l-0-0c8-4,15-12,17-22C83,30,71,8,50,2z" />
</svg>
<div class="spesial">
</div>
First off, you want to use clip-path, or set the mask fill to white for 100% opacity: mask is used as a greyscale alpha channel and the red fill color causes the opacity change.
As for the stroke, you want to add it as a separate element that is not affected by the clipping. (You can probably re-use the path with defs and use, I just copy-pasted it here)
#progressMove {
transition: .3s y;
}
#progressMove:hover {
y: 60%;
}
<svg id="kenseoProgress" width="79.36px" height="93.844px" viewBox="0 0 79.36 93.844">
<defs>
<clipPath id="bubbleKenseo">
<path d="M50,2C30-4,8,7,2,28c-6,20,5,42,26,48h0l-4,15l33-18c0-0,0-0,1-0l0-0l-0-0c8-4,15-12,17-22C83,30,71,8,50,2z" />
</clipPath>
</defs>
<path stroke="black" stroke-width="1" fill="transparent" d="M50,2C30-4,8,7,2,28c-6,20,5,42,26,48h0l-4,15l33-18c0-0,0-0,1-0l0-0l-0-0c8-4,15-12,17-22C83,30,71,8,50,2z" />
<g x="0" y="0" width="79.36px" height="93.844px" clip-path="url(#bubbleKenseo)" height="100">
<rect id="progressMove" x="0" y="0%" width="100%" height="100%" fill="blue" stroke="black" />
</g>
</svg>
var prObject = document.getElementById("prObject"),
prDom = document.getElementById("progressMove"),
prValue = 0;
prObject.onmouseenter = function() {
prDom.setAttribute('class', 'prHover')
};
prObject.onmouseleave = function() {
prDom.removeAttribute('class')
};
/*prDom.setAttributeNS(null, 'y', '0');*/
var cTimer = setInterval(function() {
prValue += 20.6;
prDom.style.transform = "translateY(" + [100 - Math.min(prValue, 100)] + "%)";
if (prValue >= 100) {
clearInterval(cTimer);
}
}, 450);
#progressMove {
transition: transform 0.20s linear;
}
#progressMove.prHover {
transform: translateY(40%) !important;
}
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<svg id="kenseoProgress" width="79.36px" height="93.844px" viewBox="0 0 79.36 93.844">
<defs>
<path id="mypath" fill="white" d="M50,2C30-4,8,7,2,28c-6,20,5,42,26,48h0l-4,15l33-18c0-0,0-0,1-0l0-0l-0-0c8-4,15-12,17-22C83,30,71,8,50,2z" />
<mask id="bubbleKenseo">
<use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#mypath"></use>
</mask>
</defs>
<g x="0" y="0" width="79.36px" height="93.844px" mask="url(#bubbleKenseo)" height="100" stroke-width="0">
<rect id="progressMove" x="0" y="0" width="100%" height="100%" fill="blue" stroke="black" style="transform: translateY(100%);" />
</g>
<g id="prObject" x="0" y="0" width="79.36px" height="93.844px" height="100" fill-opacity="0" stroke="black" stroke-width="0.5px">
<use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#mypath"></use>
</g>
</svg>
</body>
</html>

Css tricks with div box and borders

I am trying to make a div that looks like this:
Is there a way to do this with css only?
I have been trying to play this idea in jsfiddle
.box {
background-color : red;
position : relative;
display : block;
height : 50px;
width : 200px;
text-align : center;
margin : 0 auto;
}
.box p {
padding : 0px;
}
.box::before {
content: '';
height: 50px;
width: 10px;
background-color: blue;
position: absolute;
top: 0;
left: 0px;
transform: skewX(-10deg);
transform-origin: top;
-webkit-transform: skewX(-10deg);
-webkit-transform-origin: 0 0;
}
.box::after {
content: '';
height: 50px;
width: 15px;
background-color: green;
position: absolute;
top: 0;
right: -15px;
left: auto;
transform: skewX(-15deg);
transform-origin: top;
-webkit-transform: skewX(-15deg);
-webkit-transform-origin: 0 0;
}
It looks like i can play with the left and right, but i do not know how to do it with the bottom.
I know of one way to do it, which is using svg. Here is an online svg editor
The code below generates similar shape to what you seek. Jsfiddle is here
<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg">
<!-- Created with SVG-edit - http://svg-edit.googlecode.com/ -->
<g>
<title>Layer 1</title>
<line id="svg_2" y2="198" x2="509" y1="198" x1="59" stroke-linecap="null" stroke-linejoin="null" stroke-dasharray="null" stroke-width="5" stroke="#000000" fill="none" />
<line stroke="#000000" id="svg_3" y2="197" x2="60.999999" y1="320" x1="26" stroke-linecap="null" stroke-linejoin="null" stroke-dasharray="null" stroke-width="5" fill="none" />
<line id="svg_4" y2="258" x2="497" y1="317" x1="28" stroke-linecap="null" stroke-linejoin="null" stroke-dasharray="null" stroke-width="5" stroke="#000000" fill="none" />
<line id="svg_6" y2="258" x2="495" y1="195" x1="507" stroke-linecap="null" stroke-linejoin="null" stroke-dasharray="null" stroke-width="5" stroke="#000000" fill="none" />
</g>
</svg>

Resources