One thing that has long surprised (and saddened) me is that the clip-path property, as awesome as it is, only takes a few values. The circle() and ellipse() functions are nice, but hiding overflows and rounding with border-radius generally helps there already. Perhaps the most useful value is polygon() because it allows us to draw a shape out of straight lines at arbitrary points.
Update: all three browser engines have clip-path: path() now. Yay!
Here’s a demo of each value:
The sad part comes in when you find out that clip-path doesn’t accept path(). C’mon it’s got path in the name! The path syntax, which comes from SVG, is the ultimate syntax. It allows us to draw literally any shape.
More confusingly, there already is a path() function, which is what properties like offset-path take.
I was once so flabbergasted by all this that I turned it into a full conference talk.
The talk goes into the shape-outside property and how it can’t use path(). It also goes into the fact that we can change the d property of a literal <path>.
I don’t really blame anyone, though. This is weird stuff and it’s being implemented by different teams, which inevitably results in different outcomes. Even the fact that SVG uses unit-less values in the <path d=""> syntax is a little weird and an anomaly in CSS-land. How that behaves, how values with units behave, what comma-syntax is allowed and disallowed, and what the DOM returns when asked is plenty to make your head spin.
Anyway! Along comes Firefox with an implementation!
Does anyone know if clip-path: path() is behind a flag in chrome or something. Can’t seem to find it, but they do support offset-path: path(), so figured they would support both.
Thanks @CSS and @ChromiumDev friends.https://t.co/YTmwcnilRB works behind a flag in FF. Chrome?
— Estelle Weyl (@estellevw) September 13, 2018
Support
Here’s that flag in Firefox (layout.css.clip-path-path.enabled):

Update!
Also shipped in Firefox 71 today — support for using SVG path() syntax with Clip Path in CSS.
Yup — this is now a thing:
clip-path: path(‘M0.5,1 C0.5,1,0,0.7,0,0.3 A0.25,0.25,1,1,1,0.5,0.3 A0.25,0.25,1,1,1,1,0.3 C1,0.7,0.5,1,0.5,1 Z’);
— Jen Simmons (@jensimmons) December 3, 2019
And here’s a demo…
you’ll see a square in unsupported browsers and a heart in the ones that support clip-path: path(); — which is only Firefox Nightly with the flag turned on at the time of this writing.

Now, all we need is:
clip-pathto be able to point to the URL of a<path>in SVG, likeurl("#clip-path");shape-outsideto be able to usepath()shape-outsideto be able to point to a<path>offset-pathto take all the other shape functions- Probably a bunch of specs to make sure this is all handled cleanly (Good luck, team!)
- Browsers to implement it all
😉
(I started this as a twitter comment, but it turned into a thread, so I figured it would fit better here! And then after I’d written it here, I realized that to collect feedback it should also be on the working group’s issue tracker. So it’s copied there, please add your votes: https://github.com/w3c/csswg-drafts/issues/3468 )
## Re: “bunch of specs—Good luck, team!”
The tricky part is fill-rule. The
polygon()function includes fill-rule keywords as an optional first parameter:But a
<path>element uses the keywords set by thefill-ruleORclip-ruleproperties, depending on the shape’s context. So having a keyword inside thedproperty would create a conflict.The
path()function as currently spec’d foroffset-pathdoesn’t include a keyword parameter, because motion only uses the outline, not the fill.We have agreed to use that syntax for
d(<path>shape) as a property.But for
clip-path(and future stuff likeshape-insideto define the text wrapping area as a shape), we need to know which fill rule to use.One idea I mused about (but never wrote down) is to define two different CSS data types, one of which is a super class of the other:
<outline-shape>doesn’t have fill-rule keywords<filled-shape>=<outline-shape>(with default fill-rule) |polygon()andpath()with keywordsSo, the
dproperty would take an<outline-shape>function, no keywords allowed, and would still use thefill-rule/clip-ruleproperties with no conflict.Another option is to define an
autovalue for the keyword inside the functions, and make that the default. Inclip-path, anautovalue would behave just like the current default (nonzero), But ind, it would behave as “check thefill-ruleorclip-ruleproperty according to context and use that”. If you did specify a different keyword in a function insided, it would override the other properties:A side benefit, in my opinion, is that this means we could long-term plan to deprecate usage of the
fill-rule/clip-ruleproperties, which are already super annoying in the way they depend on context. If you want context-specific keyword values in the CSS function notation, you could use inherited CSS variable values.But the most important benefit of either of these approaches is that they would allow all the shape functions (possibly minus fill-rule keywords) to be used in all the shape-related properties!!!
If you have opinions on any and all of this, please let us (CSS/SVG editors) and browser teams know! At this point, I’d really like to pick one option so that we can get the full suite of shape functions in all the related properties:
https://github.com/w3c/csswg-drafts/issues/3468#issuecomment-449760438
There are still a few other spec-related things that need to be tidied, like animation rules and how much the syntax of path strings gets normalized when you call
getComputedStyle()or otherwise serialize from the DOM. But there isn’t much disagreement there, it’s just a matter of hammering out the details.(Well, and then there are all sorts of future enhancements I’d like to see, like being able to concatenate multiple path strings stored in variables, or use units in paths. But that’s for later…)
By the way, I am intrigued by the idea of being able to use an SVG
<clipPath>element inshape-outside.In SVG 2 (sections that are currently being deferred to SVG Sometime), the plan was that
shape-outsideandshape-insidecould directly reference a single SVG shape element (like a<path>). But maybe referencing a<clipPath>makes more sense, because a clipPath already defines rules for scaling it to fit a referencing element?Anyway, if you have more ideas on that particular suggestion, Chris, I’d love to see them in the official issue tracker.