simeonGriggs.dev
Twitter
GitHub

Responsive, Extendable Squircles with SVG

Rounded corners don't have to be so boring.

View in Sanity Studio

2020-09-28

Remember life before border-radius? You had to work for those sweet non-square corners. But now you can slap a border-radius on just about anything.

And that's cool. But you know what is really cool? Squircles. (Squared circles). Even though they're not natively supported in CSS, they're not all that difficult to pull off either. SVGs are your friend.

The goal is to easily give any HTML element a squircle-y rounded shape, while still taking attributes like background colour, and always stretching to the size of the element.

Like these!

SVG Clip Path

The trick is to use an SVG clip path. That is, insert an SVG anywhere into the DOM. /You can hide it with CSS, but not with display: none. For example, change its position to absolute and hide it with opacity.

Then, so long as your SVG has a <clipPath> element with an id, it's available to use in CSS.

Olga Nikolskaya's blog post used this technique, but the shapes aren't responsive and the background colours aren't dynamic. Which makes it tough to use with a utility CSS framework like Tailwind CSS.

So our SVG in the examples above...

<svg width="10" height="10" viewBox="0 0 10 10">
<clipPath id="squircleClip" clipPathUnits="objectBoundingBox">
<path
fill="red"
stroke="none"
d="M 0,0.5 C 0,0 0,0 0.5,0 S 1,0 1,0.5 1,1 0.5,1 0,1 0,0.5"
/>
</clipPath>
</svg>

... has the id="squircleClip" attribute.

Which means now with one line of CSS ...

.squircle {
clip-path: url(#squircleClip);
}

... we can make any element have the same clip path as our SVG.

So now it's this easy to give any element this shape, while still inheriting other utility classes, the correct background colour (or image) and fit to the element's padding, size and/or content.

<button class="squircle button bg-blue-500">Deliciously Rounded</button>

But we're not finished, not just any SVG will work! There's one more attribute to take note of in the SVG above.

Eric Meyer's guide on responsive SVG clipping paths introduces us to clipPathUnits="objectBoundingBox". Which makes the SVG scale.

Often this means you'll need to set every point in the SVG to a value between 0 and 1 to define its location – since most design tools won't export SVGs in this way.

(It sure would be nice if one did, though)

This is what makes our squircle SVG clipPath stretch to fill whichever element it's been placed into.

Drawbacks

The only issue I've found with this approach is losing access to box-shadow. CSS Clip Path's will prevent anything from outside the clip area showing. You can kind-of solve this by dropping another element the same size behind the squircle element – but getting the shadow to look right can take some tweaking.

It's okay on a big shadow, but getting a really tight shadow won't happen.

More reading

In addition to the above blog post links be sure to check out Sara Soueidan's guide on SVG Clipping, which is likely more than you might want to know on the topic.