An easy way to implement smooth shapes (such as Superellipse and Squircle) into a user interface.

Solution for all sizes and colors.

Image for post
Image for post

Every time you see a rectangle with rounded corners in the web, your eye gets stuck at the point where the edge and the corner of the shape meets.
This is not the way it should be, so I decided to find a different way to stylize web elements!

All that massive corner rounding is compounded by the fact that there exists an ideal shape — Superellipse, absolutely slight, without any points of intersection and sharpness.

The Superellipse is the name given to a family of shapes and the most popular of them is Squircle, the shape intermediate between circle and square. The appearance of squircle seems optically balanced: no sharpness, no angles…

Is there a way to implement these Super shapes into your interface?

Let’s figure it out!

All the shapes obtained in this article are named something like this: similar to Superellipse, similar to Squircle and so on… It’s because they were created without exact calculations with Superformula.

The purpose of this article is to find a better way to stylize web interface with optically pleasant forms.

But I will give the comparison of the true Superellipse and obtained Similar to Superellipse form. Will you find the difference? 😏

I highly recommend you to read this article, which explains a lot of how we see things and about our perception of forms, why Superellipse is so pretty to look at:

What’s wrong with border-radius?

To create a new way of styling elements, let’s first figure out what’s wrong with the existing method…

Among all the CSS properties we can use for trying to make rectangles smoother the most obvious decision is to use border-radius.

The result of setting this property to one single value is predictable — an old plain rectangle with rounded corners.

This way is very common, it produces a circular curvature and styles all four corners the same way.

You can create elliptical corners by rounding them independently with shorthand property defining values for each corner separately.

border-radius: 5px 10px 5px 10px / 10px 5px 10px 5px;

The first set is for horizontal radii, second for vertical.

When you set horizontal and vertical radii to not equal values, the outcome will be an elliptical curve.

But the result is always the same — you still see these junction points.

Image for post
Image for post
Horizontal radius set for the half of width, vertical smaller than height.
Image for post
Image for post
Horizontal radius — half of width, vertical — half of height.

As you can see that the best result with border-radius, which you can achieve without any junction points visible is an ellipse and it’s not the way we want to see our rectangle.

Missing element

I propose to look at the problem from a different perspective.

Let’s move on to the graphic design software (I’m working in Affinity Designer).

If you create simple circle shape and then convert it to a curve you see that now it has four anchor points and eight handles.

Paired opposite handles result in a smooth curve representing our circle.

Image for post
Image for post

What if we try to make the handles longer?

Image for post
Image for post

Longer…

Image for post
Image for post

As you can see anchor points are centered at the edges, and when the width of handles increases, our shape becomes more rectangular, saving its smoothness.

The outcoming form is very similar to Superellipse. Probably we have to work with handles, not with border-radius…
But how to use handles through HTML and CSS?

SVG!

The Path

There is no better element in SVG to manipulate curves than the Path. It has five commands to produce the exact curvature you want:

  • C — cubic Bézier curve
  • S — smooth cubic Bezier (shorthand for C)
  • Q — quadratic bezier curve
  • T — smooth quadratic Bezier curve (shorthand for Q)
  • A — elliptical arc

If you want to learn more about how path commands work, I can recommend you to read this article:

Elliptical arc command (A) takes much more parameters in comparison with the other four commands. So in order to provide well-balanced and optimized code, only first four commands will be examined.

Only four numbers needed to construct SVGs with the desired shape:

  • Width (500px)
  • Height (300px)
  • Half of Width (250px)
  • Half of Height (150px)

All examples assume that handles are parallel to the edges they belong to and are equal to the half of edge’s length.

  1. Starting with C command:
Image for post
Image for post
Path C command smooth result

2. S command try:

Image for post
Image for post
Not the result expected

What’s wrong with the left top corner?

There is one trick. When you use the S command, the first control point that the curve is attached to is always a reflection of the final control point of the first Bezier curve.

To fix this, it’s better to start with C command and then use S command.

Cooperation of two commands:

Image for post
Image for post
The same smooth rectangle with C+S commands

Command Q:

Image for post
Image for post
Seems like Super Egg…
Image for post
Image for post
Similar to Super Egg form vs ellipse

The difference between C and Q commands is that first draws a curve based on two control points, the second requires a single control point.

Well, T command acts like S for C, it smoothes the connection between curves, by using the reflection of a control point.

Image for post
Image for post
Shorthand with T command

Actually, I find both shapes beautiful and smooth. Much better than rectangles styled with border-radius!

Compare to Superellipse

To compare created SVGs with True Superellipse we need a resource to generate the last.

Searching for Superellipse generator I’ve found one, which I like more. It allows enter necessary properties and let download generated shape as SVG, here is the reference:

Additional parameters for this calculator are left as default, width and height values are from the examlpes above, I still needed one extra value for the n parameter… I’ve tried several values for this property and discovered one interesting thing: C+S example has n about 5, Q+T example has n about 2.37!

Final calculator result for C+S example:

Image for post
Image for post

Final calculator result for Q+T example:

Image for post
Image for post

Generated Superellipse’s SVG were overlapped with SVGs produced in this article, they are the same! You shouldn’t believe me, just try.

Image for post
Image for post
Blue — Generated true Superellipse
Image for post
Image for post
Blue — Generated true Superellipse

But wait, we have these SVGs, what else? Feels like we can’t do much with it within our interface…

Now it’s time to think about implementation.

Background SVG with Data URI

We will implement it through the style sheet to have access to all our elements in the DOM.

The data URI scheme is a uniform resource identifier (URI) scheme that provides a way to include data in-line in web pages as if they were external resources.

There are several advantages using such way of implementation:

  • No DOM weighting. (Versus inline SVG) Only elements you really need to structure your page. Styles and structure apart.
  • No extra HTTP requests. (Versus background with a link to file).
  • Easy styling desired set of elements by adding a class.

Here is the example of embedding SVG with data URI:

Not bad… We can do it even better!

Imagine all the elements…

…into you interface are different, have various sizes, colors, sometimes gradients, but they are all styled with the same smoothness.

Imagine super mixin, which you can add to different classes. It can take different variables to deal with properties, that gives a great flexibility to style your interface. It is supported even in IE9…

Here it goes!

Super mixins for Super Shapes

To create super mixins I’ve chosen two variations of SVG, with C+S commands and Q+T. Let name them super-rectangle and super-circle.

As you can see from the above example, we need only four parameters to measure our shape: width, height, half of the width, half of the height;
For styling let’s first take one parameter — color.

There are few rules to make our background SVG IE9+ friendly and allow us to add variables.

  • Replace ‘<’ with ‘%3C’ and ‘>’ with ‘%3E’ (%3Cpath%3E similar to <path>)
  • Replace ‘#’ with ‘%23’ (%23f9ed32 similar to #f9ed32)
  • Wrap url content with double quotes, while using inner attribute values’ with single quotes, except variables.

That would be enough to understand the example.

Needed parameters:

background: url("data:image/svg+xml;charset=US-ASCII,<svg version='1.1' id='shape-1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' width='500' height='300' viewBox='0 0 500 300' enable-background='new 0 0 500 300' xml:space='preserve'><path fill='#ED2F5B' stroke='none' d='M 0,150 C 0,0 0,0 250,0 S 500,0 500,150 500,300 250,300 0,300 0,150'></path></svg>") left top no-repeat;

Replace our parameters with variables:

background: url("data:image/svg+xml;charset=US-ASCII,%3Csvg version='1.1' id='shape-1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' width='"+$width+"' height='"+$height+"' viewBox='0 0 "+$width+" "+$height+"' enable-background='new 0 0 "+$width+" "+$height+"' xml:space='preserve'%3E%3Cpath fill='"+$color+"' stroke='none' d='M 0,"+$halfHeight+" C 0,0 0,0 "+$halfWidth+",0 S "+$width+",0 "+$width+","+$halfHeight+" "+$width+","+$height+" "+$halfWidth+","+$height+" 0,"+$height+" 0,"+$halfHeight+"'%3E%3C/path%3E%3C/svg%3E");

To highlight brackets replacement:

background: url("data:image/svg+xml;charset=US-ASCII,%3Csvg version='1.1' id='shape-1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' width='"+$width+"' height='"+$height+"' viewBox='0 0 "+$width+" "+$height+"' enable-background='new 0 0 "+$width+" "+$height+"' xml:space='preserve'%3E%3Cpath fill='"+$color+"' stroke='none' d='M 0,"+$halfHeight+" C 0,0 0,0 "+$halfWidth+",0 S "+$width+",0 "+$width+","+$halfHeight+" "+$width+","+$height+" "+$halfWidth+","+$height+" 0,"+$height+" 0,"+$halfHeight+"'%3E%3C/path%3E%3C/svg%3E");

For this working properly we need extra functions:

  • To replace ‘#’ in color code
  • To cut units like ‘px’

I included several examples in CodePen (gradients, clip-path, background, and shadows). The form itself works well in any modern browser, shadows and gradients are more specific.

Feel free to play with Super shapes here:

You can do interesting things with hover just adding other parameters in the mixins, style it different ways, you can even change the curvature by decreasing handle’s width, I just provide you few examples…

I hope this article will help you create beautiful things and inspire you to develop new interesting forms.

Written by

UX-Designer + Front-End Developer + Product Designer + Project Manager = Web Marketing Director 🤷🏼‍♀️

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store