Frontend Development 14 min read

Master CSS shape(): Create Complex Clip‑Path Shapes with Percentages and Arcs

This tutorial explains the CSS shape() function, its syntax, and how it extends clip‑path and offset‑path capabilities, allowing developers to craft responsive, irregular shapes using percentages, variables, and arc commands, with practical code examples and browser compatibility notes.

Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Master CSS shape(): Create Complex Clip‑Path Shapes with Percentages and Arcs

Write at the Beginning

Learn

shape()

and you can easily create a variety of irregular shape effects.

What Is shape()?

shape() CSS function defines the shapes for clip-path and offset-path properties. It combines an initial start point with a series of shape commands and is a member of the data type.

Syntax

<code>clip-path: shape(...);</code>
<code>offset-path: shape(...);</code>

Why Do We Need shape()?

We already have many

clip-path

types, but

shape()

offers a more standard CSS syntax, supports full CSS features such as

px

,

rem

,

%

units, and mathematical functions, and dynamically converts commands to actual values.

In this sense,

shape()

is a superset of

path()

. Converting a

path()

to

shape()

is easy, but converting back requires CSS environment information.

Thus,

shape()

lets you use percentages and CSS calculations like

var()

,

calc()

,

sin()

, etc.

Appetizer – Simple Comparison!💃

Let’s compare

shape()

with

path()

using an example.

<code>&lt;div class="shape"&gt;&lt;/div&gt;</code>
<code>.shape {</code>
<code>    --r: 6px;</code>
<code>    height: 64px;</code>
<code>    width: 189px;</code>
<code>    background: linear-gradient(60deg, #BD5532, #601848);</code>
<code>    color: #fff;</code>
<code>    border-radius: 12px;</code>
<code>}</code>
<code>:nth-child(1 of .shape) {</code>
<code>    clip-path: path("M189 0H123.486s2.909 15.998-20.337 15.998c0 0-2.909-5.821-2.909-15.998 0 0 0 8.705-5.821 8.705S88.874 0 88.874 0c0 10.129-2.909 15.998-2.909 15.998-23.246 0-20.337-15.998-20.337-15.998H0c36.295 4.364 30.486 36.295 30.486 36.295 56.691-11.608 64 27.387 64 27.387s7.309-38.995 64-27.387c0 0-5.821-31.998 30.486-36.295z");</code>
<code>}</code>
<code>:nth-child(2 of .shape) {</code>
<code>    clip-path: shape(from 100% 0%, hline to 65.34%, smooth by -10.76% 25.12% with 1.54% 25.12%, curve by -1.54% -25.12% with 0% 0%/-1.54% -9.14%, curve by -3.08% 13.67% with 0% 0%/0% 13.67%, smooth to 47.02% 0% with 47.02% 0%, curve by -1.54% 25.12% with 0% 15.91%/-1.54% 25.12%, curve by -10.76% -25.12% with -12.3% 0%/-10.76% -25.12%, hline to 0%, curve by 16.13% 56.99% with 19.2% 6.85%/16.13% 56.99%, curve by 33.86% 43.01% with 30% -18.23%/33.86% 43.01%, smooth by 33.86% -43.01% with 3.87% -61.23%, curve by 16.13% -56.99% with 0% 0%/-3.08% -50.25%, close);</code>
<code>}</code>

No change – this proves shape() is a superset of path() . You can convert

path

to

shape

automatically using tools like "SVG to CSS Shape".

If you only need the same effect as

path()

, using

shape()

is unnecessary; however,

shape()

supports percentages and scaling, which

path()

does not.

Now we can officially start learning

shape()

with a simple example.

Tip: shape() works in Chrome >= 135.
<code>.shape {</code>
<code>    background: repeating-linear-gradient(45deg, #F07818 0 15px, #F0A830 0 30px);</code>
<code>    color: #fff;</code>
<code>    width: 200px;</code>
<code>    height: 200px;</code>
<code>    clip-path: shape(from 0 0, line to 100% 0, vline to 100%, hline to 0, close);</code>
<code>}</code>
<code>&lt;div class="shape"&gt;&lt;/div&gt;</code>

At this point there is no clipping effect; the

from 0 0

command simply defines the start point.

line / vline / hline

line [x] [y]

draws a straight line from the previous point to the specified

x y

.

hline

and

vline

are shorthand for

line

, automatically keeping the previous

y

or

x

value.

<code>clip-path: shape(from 0 0, hline to 100%, line to 0 100%, close);</code>

The

hline

and

vline

commands are essentially shorthand for

line

, allowing you to omit the

y

or

x

coordinate respectively.

arc

The

arc

command draws an elliptical arc. Syntax:

<code>&lt;arc-command&gt;: arc to Xb Yb of R [large or small] [cw or ccw] rotate &lt;angle&gt;;</code>

Example:

<code>--r: 25px;</code>
<code>clip-path: shape(from 0 0, arc to calc(var(--r) * 2) 0 of var(--r), hline to 100%, vline to 100%, hline to 0%, vline to 0);</code>

The

arc

command supports three additional parameters:

arc-sweep

(cw or ccw),

arc-size

(large or small), and

angle

(rotation in degrees).

arc-sweep:cw

– clockwise.

arc-sweep:ccw

– counter‑clockwise (default).

<code>clip-path: shape(    from 0 0,    line to calc(50% - var(--r)) 0,    arc by calc(var(--r) * 2) 0 of var(--r) cw,    hline to 100%,    vline to 100%,    hline to 0%,    vline to 0 );</code>

Now we have learned

line

and

arc

commands and can create a Chrome‑style tab effect.

Chrome Tab Effect💘

Before

shape()

, achieving this effect required complex tricks. Using the commands we learned, the effect becomes straightforward.

Requires Chrome version >= 135.

Concave Rounded Corners💟

This classic effect can be achieved with just three

arc

commands combined with

border-radius

, without excessive code.

Requires Chrome version >= 135.

Compatibility!

Hope for broader support soon.

Conclusion

It’s been a while since the blog was updated. Lately I’ve been learning a lot about

Three.js

and getting back into fitness. Hope everyone’s life gets better!

References

https://css-tricks.com/better-css-shapes-using-shape-part-1-lines-and-arcs/

frontend developmentCSSlineweb designarcclip-pathshape()
Rare Earth Juejin Tech Community
Written by

Rare Earth Juejin Tech Community

Juejin, a tech community that helps developers grow.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.