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.
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-pathtypes, 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><div class="shape"></div></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
pathto
shapeautomatically 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><div class="shape"></div></code>At this point there is no clipping effect; the
from 0 0command simply defines the start point.
line / vline / hline
line [x] [y]draws a straight line from the previous point to the specified
x y.
hlineand
vlineare shorthand for
line, automatically keeping the previous
yor
xvalue.
<code>clip-path: shape(from 0 0, hline to 100%, line to 0 100%, close);</code>The
hlineand
vlinecommands are essentially shorthand for
line, allowing you to omit the
yor
xcoordinate respectively.
arc
The
arccommand draws an elliptical arc. Syntax:
<code><arc-command>: arc to Xb Yb of R [large or small] [cw or ccw] rotate <angle>;</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
arccommand 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
lineand
arccommands 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
arccommands 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.jsand 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/
Rare Earth Juejin Tech Community
Juejin, a tech community that helps developers grow.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.