When you’re following alongside, that is the third put up in a collection concerning the new CSS form()
operate. We’ve discovered how to attract traces and arcs and, on this third half, I’ll introduce the curve
command — the lacking command it’s essential to know to have full management over the form()
operate. In actuality, there are extra instructions, however you’ll hardly ever want them and you’ll simply study them later by checking the documentation.
curve
command
The This command provides a Bézier curve between two factors by specifying management factors. We will both have one management level and create a Quadratic curve or two management factors and create a Cubic curve.
Bézier, Quadratic, Cubic, management factors? What?!
For a lot of of you, that definition is solely unclear, and even ineffective! You may spend a couple of minutes studying about Bézier curves however is it actually price it? In all probability not, until your job is to create shapes all of the day and you’ve got a stable background in geometry.
We have already got cubic-bezier()
as an easing operate for animations however, truthfully, who actually understands the way it works? We both depend on a generator to get the code or we learn a “boring” rationalization that we neglect in two minutes. (I’ve one proper right here by the way in which!)
Don’t fear, this text is not going to be boring as I’ll principally deal with sensible examples and extra exactly the use case of rounding the corners of irregular shapes. Here’s a determine as an example a number of examples of Bézier curves.

The blue dots are the beginning and ending factors (let’s name them A and B) and the black dots are the management factors. And spot how the curve is tangent to the dashed traces illustrated in crimson.
On this article, I’ll think about just one management level. The syntax will comply with this sample:
clip-path: form(
from Xa Ya,
curve to Xb Yb with Xc Yc
);
arc
command vs. curve
command
We already noticed in Half 1 and Half 2 that the arc
command is helpful establishing rounded edges and corners, nevertheless it is not going to cowl all of the circumstances. That’s why you will have the curve
command. The difficult half is to know when to make use of each and the reply is “it relies upon.” There isn’t any generic rule however my recommendation is to first see if it’s doable (and straightforward) utilizing arc
. If not, then you must use curve
.
For some shapes, we are able to have the identical consequence utilizing each instructions and it is a good start line for us to grasp the curve
command and evaluate it with arc
.
Take the next instance:
That is the code for the primary form:
.form {
clip-path: form(from 0 0,
arc to 100% 100% of 100% cw,
line to 0 100%)
}
And for the second, now we have this:
.form {
clip-path: form(from 0 0,
curve to 100% 100% with 100% 0,
line to 0 100%)
}
The arc
command wants a radius (100%
on this case), however the curve
command wants a management level (which is 100% 0
on this instance).

Now, for those who look carefully, you’ll discover that each outcomes aren’t precisely the identical. The primary form utilizing the arc
command is creating 1 / 4 of a circle, whereas the form utilizing the curve
command is barely totally different. When you place each of them above one another, you’ll be able to clearly see the distinction.
That is fascinating as a result of it means we are able to spherical some corners utilizing both an arc
or a curve
, however with barely totally different outcomes. Which one is healthier, you ask? I might say it is determined by your visible choice and the form you might be creating.
In Half 1, we created rounded tabs utilizing the arc
command, however we are able to additionally create them with curve
.
Can you notice the distinction? It’s barely seen nevertheless it’s there.
Discover how I’m utilizing the by
directive the identical manner I’m doing with arc
, however this time now we have the management level, which can be relative. This half will be complicated, so pay shut consideration to this subsequent bit.
Contemplate the next:
form(from Xa Ya, curve by Xb Yb with Xc Yc)
It signifies that each (Xb,Yb)
and (Xc,Yc)
are relative coordinates calculated from the coordinate of the start line. The equal of the above utilizing a to
directive is that this:
form(from Xa Ya, curve to (Xa + Xb) (Ya + Yb) with (Xa + Xc) (Yb + Yc))
We will change the reference of the management level by including a from
directive. We will both use begin
(the default worth), finish
, or origin
.
form(from Xa Ya, curve by Xb Yb with Xc Yc from finish)
The above signifies that the management level will now think about the ending level as an alternative of the start line. The result’s much like:
form(from Xa Ya, curve to (Xa + Xb) (Ya + Yb) with (Xa + Xb + Xc) (Ya + Yb + Yc))
When you use origin
, the reference would be the origin, therefore the coordinate of the management level turns into absolute as an alternative of relative.
The from
directive might add some complexity to the code and the calculation, so don’t hassle your self with it. Merely understand it exists in case you face it, however hold utilizing the default worth.
I believe it’s time on your first homework! Much like the rounded tab train, attempt to create the inverted radius form we lined within the Half 1 utilizing curve
as an alternative of arc
. Listed here are each variations so that you can reference, however attempt to do it with out peeking first, for those who can.
Let’s draw extra shapes!
Now that now we have overview of the curve
command, let’s think about extra complicated shapes the place arc
received’t assist us around the corners and the one resolution is to attract curves as an alternative. Contemplating that every form is exclusive, so I’ll deal with the approach slightly than the code itself.
Slanted edge
Let’s begin with an oblong form with a slanted edge.

Getting the form on the left is kind of easy, however the form on the suitable is a bit difficult. We will spherical two corners with a easy border-radius
, however for the slanted edge, we’ll use form()
and two curve
instructions.
Step one is to put in writing the code of the form with out rounded corners (the left one) which is fairly easy since we’re solely working with the line
command:
.form {
--s: 90px; /* slant dimension */
clip-path:
form(from 0 0,
line to calc(100% - var(--s)) 0,
line to 100% 100%,
line to 0 100%
);
}
Then we take every nook and attempt to spherical it by modifying the code. Here’s a determine as an example the approach I’m going to make use of for every nook.

We outline a distance, R
, that controls the radius. From either side of the nook level, I transfer by that distance to create two new factors, that are illustrated above in crimson. Then, I draw my curve
utilizing the brand new factors as beginning and ending factors. The nook level would be the management level.
The code turns into:
.form {
--s: 90px; /* slant dimension */
clip-path:
form(from 0 0,
Line to Xa Ya,
curve to Xb Yb with calc(100% - var(--s)) 0,
line to 100% 100%,
line to 0 100%
);
}
Discover how the curve
is utilizing the coordinates of the nook level within the with
directive, and now we have two new factors, A and B.
Till now, the approach is just not that complicated. For every nook level, you change the line
command with line
+ curve
instructions the place the curve
command reuses the previous level in its with
directive.
If we apply the identical logic to the opposite nook, we get the next:
.form {
--s: 90px; /* slant dimension */
clip-path:
form(from 0 0,
line to Xa Ya,
curve to Xb Yb with calc(100% - var(--s)) 0,
line to Xc Yc,
curve to Xd Yd with 100% 100%,
line to 0 100%
);
}
Now we have to calculate the coordinates of the brand new factors. And right here comes the difficult half as a result of it’s not at all times easy and it might require some complicated calculation. Even when I element this case, the logic received’t be the identical for the opposite shapes we’re making, so I’ll skip the maths half and provide the ultimate code:
.field {
--h: 200px; /* aspect top */
--s: 90px; /* slant dimension */
--r: 20px; /* radius */
top: var(--h);
border-radius: var(--r) 0 0 var(--r);
--_a: atan2(var(--s), var(--h));
clip-path:
form(from 0 0,
line to calc(100% - var(--s) - var(--r)) 0,
curve by calc(var(--r) * (1 + sin(var(--_a))))
calc(var(--r) * cos(var(--_a)))
with var(--r) 0,
line to calc(100% - var(--r) * sin(var(--_a)))
calc(100% - var(--r) * cos(var(--_a))),
curve to calc(100% - var(--r)) 100% with 100% 100%,
line to 0 100%
);
}
I do know the code appears to be like a bit scary, however the excellent news is that the code can be very easy to regulate utilizing CSS variables. So, even when the maths is just not simple to know, you don’t should cope with it. It must be famous that I have to know the peak to have the ability to calculate the coordinates which suggests the answer isn’t good as a result of the peak is a set worth.
Arrow-shaped field
Right here’s the same form, however this time now we have three corners to spherical utilizing the curve
command.
The ultimate code remains to be complicated however I adopted the identical steps. I began with this:
.form {
--s: 90px;
clip-path:
form(from 0 0,
/* nook #1 */
line to calc(100% - var(--s)) 0,
/* nook #2 */
line to 100% 50%,
/* nook #3 */
line to calc(100% - var(--s)) 100%,
line to 0 100%
);
}
Then, I modified it into this:
.form {
--s: 90px;
clip-path:
form(from 0 0,
/* nook #1 */
line to Xa Ya
curve to Xb Yb with calc(100% - var(--s)) 0,
/* nook #2 */
line to Xa Ya
curve to Xb Yb with 100% 50%,
/* nook #3 */
line to Xa Yb
curve to Xb Yb with calc(100% - var(--s)) 100%,
line to 0 100%
);
}
Lastly, I exploit a pen and paper to do all of the calculations.
You may suppose this method is ineffective in case you are not good with math and geometry, proper? Not likely, as a result of you’ll be able to nonetheless seize the code and use it simply because it’s optimized utilizing CSS variables. Plus, you aren’t obligated to be tremendous correct and exact. You may depend on the above approach and use trial and error to approximate the coordinates. It’s going to in all probability take you much less time than doing all the maths.
Rounded polygons
I do know you might be ready for this, proper? Due to the brand new form()
and the curve
command, we are able to now have rounded polygon shapes!

Right here is my implementation utilizing Sass the place you’ll be able to management the radius, variety of sides and the rotation of the form:
If we omit the complicated geometry half, the loop is kind of easy because it depends on the identical approach with a line
+ curve
per nook.
$n: 9; /* variety of sides*/
$r: .2; /* management the radius [0 1] */
$a: 15deg; /* management the rotation */
.poly {
aspect-ratio: 1;
$m: ();
@for $i from 0 by ($n - 1) {
$m: append($m, line to Xai Yai, comma);
$m: append($m, curve to Xbi Ybi with Xci Yci, comma);
}
clip-path: form(#{$m});
}
Right here is one other implementation the place I outline the variables in CSS as an alternative of Sass:
Having the variables in CSS is fairly helpful particularly if you wish to have some animations. Right here is an instance of a cool hover impact utilized to hexagon shapes:
I’ve additionally up to date my on-line generator so as to add the radius parameter. In case you are not acquainted with Sass, you’ll be able to simply copy the CSS code from there. Additionally, you will discover the border-only and cut-out variations!

Conclusion
Are we achieved with the curve
command? In all probability not, however now we have overview of its potential and all of the complicated shapes we are able to construct with it. As for the code, I do know that now we have reached a degree that isn’t simple for everybody. I might have prolonged the reason by explicitly breaking down the maths, however then this text can be overly complicated and make it look like utilizing form()
is more durable than it’s.
This stated, many of the shapes I code can be found inside my on-line assortment that I always replace and optimize so you’ll be able to simply seize the code of any form!
If you’d like follow-up to this text, I wrote an article for Frontend Masters the place you’ll be able to create blob shapes utilizing the curve
command.
