You can achieve this effect with a mixture of CSS clip-path
and SVG filters.
First, we need to create the approximate shape using clip-path
. We need enough points so that it is close to the correct shape, but it is fine for it to have sharp corners. If your clip-path
knowledge is a little rusty, this article does a nice job of explaining it.
.bulged {
display: inline-block;
width: 150px;
color: red;
}
.bulged::before {
content: "";
display: block;
/* adjust the height */
padding-top: 70%;
background: currentColor;
/* draw the shape*/
clip-path: polygon(0 50%, 3% 20%, 8% 8%, 20% 3%, 50% 0, 80% 3%, 92% 8%, 97% 20%, 100% 50%, 97% 80%, 92% 92%, 80% 97%, 50% 100%, 20% 97%, 8% 92%, 3% 80%)
}
<div class="bulged" />
To round the sharp edges, we can use an SVG filter. To do this, we need to include an SVG in the same page as the bulged div, and inside the SVG, we will include an SVG filter. As noted in the code below, this filter works by blurring the edge of the shape and then removing the parts of the shape that are partially transparent. This makes the shape appear rounded because the edges become partially transparent when they are blurred.
.bulged {
display: inline-block;
width: 150px;
color: red;
filter: url('#round');
}
.bulged::before {
content: "";
display: block;
/* adjust the height */
padding-top: 70%;
background: currentColor;
/* draw the shape*/
clip-path: polygon(0 50%, 3% 20%, 8% 8%, 20% 3%, 50% 0, 80% 3%, 92% 8%, 97% 20%, 100% 50%, 97% 80%, 92% 92%, 80% 97%, 50% 100%, 20% 97%, 8% 92%, 3% 80%)
}
<div class="bulged"></div>
<svg style="visibility: hidden;" width="0" height="0" xmlns="http://www.w3.org/2000/svg" version="1.1">
<defs>
<filter id="round">
<!-- blur the entire shape, which makes the corners rounded -->
<!-- increase the standard deviation to make the corners more rounded -->
<feGaussianBlur in="SourceGraphic" stdDeviation="8" result="blur" />
<!-- unblur the shape, but keep the corners rounded -->
<!-- the color matrix increases the contrast of the alpha channel, which hides the blurry parts of the shape -->
<feColorMatrix in="blur" mode="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 19 -9" result="goo" />
</filter>
</defs>
</svg>
This answer was inspired by this article on CSS tricks and a related answer to a different question.