Responsive behavior? These masks tend to be full-width, and it becomes tedious to define multiple widths of the shape (e.g. srcset) or risk pixelation of raster assets.

It's a totally separate file that needs to be fetched from the server – seems wasteful for simple shapes.

It's slow to iterate in-browser if you have to re-export an image file(s) from your design program.

We can solve all of these problems at once. You might already know where this one is going.

SVG

Compared to exporting a JPG from Sketch, using an inline SVG is more performant, easy to make responsive, and easy to iterate the design of. In fact, for most cases, this is the way I'd recommend using. Versatile, cross-browser, vector, and fabulous.

And if you use `divider.svg` as a repeating element in different scenarios, you can also color it different as you need:

header::after polygon {
fill: white;
}

But here's an issue: what if the section below the header has a complicated background? In all these examples so far, we've just assumed a plain white background. What if there's a fancy gradient, or another background image or something? Then what?

clip-path

This property comes to the rescue if you have a moderately complex background below the header, and therefore want the masking to be done from within the non-rectangular header, as opposed to by an element after it.

And like the similar SVG syntax, if you want to change the responsive behavior of the above from angle-is-held-constant to height-differential-is-held-constant, you can change the calculated height to a simple percentage.

Clip-path's biggest downside? Browser support is not that great. However, depending on how important your non-rectangular header or div is, it might qualify as a progressive enhancement. In which case, clip-path away!

border-radius

Now, up to now, we've only mentioned methods that work for generating all the shapes I called out above. However, if we know what particular shape we want our header to have, we might have access to an easier way.

For instance, a convex elliptical header is a perfect fit for border-radius.

This has the side effect of skewing any child elements of the skewed element, so you’ll want to add a child element in the header that gets skewed, and everything else will go in sibling elements.

Skewed.And unskewed.

Stripe's homepage design uses this method, and even more brilliantly, they include a few children spans (each is a block of color) that get skewed with the parent element, creating a more complex and colorful effect.

Which is best?

As far as I'm concerned, SVG is generally the way to go. However, if you have a more complex background below the header, then the best choice depends on the shape. In that case, I'd investigate if skew or border-radius could meet the art direction needed, or if browser support was enough of a non-issue to go with clip-path.

Allows complex BG below

Browser support

Shapes creatable

Image

No

Yes

All

SVG

No

Yes

All

Clip-path

Yes

No

All

Border-radius

Yes

Yes

Elliptical only

Transform: skew

Yes

Yes

Trapezoidal only

Erik Kennedy is an independent UX/UI designer and the creator of Learn UI Design, a practical online video course about visual design for screens. Includes color, typography, process, and more. Over 16 hours of video across 30+ lessons.

Awesome post, Chris! I’ve been keeping up with this whole trend and it’s my signature for custom built themes and templates. You just gave me a lot to work with. Didn’t even think about the “butt” shape lol thanks!

I think I got inspired by Chris’s tweet regarding non-rectangular headers sometime back. Did he do it or may be retweeted something related to it. Nevertheless, really happy with the non rectangular approach. It kind of refreshes the way a page looks like in 2017 :)

The transform: skew method seems nice, but I played with it a few weeks ago and it definitely has some downsides: when you animate (css transitions/animations) something inside the skewed element, the whole element renders badly (like with no smoothing or antialiasing), especially as it comes to fonts. Checked in Firefox, both on Windows and Linux. After the animation stops, everything looks good again.

Please, just one thing, maybe I am just overworked or something, but how does the color change of a background svg work (the fill trick)? I tried it several times and looked up a bit about it and it seems that as a css background image its not part of the DOM, so it should not be possible to work with it just like that. Am I missing something obvious?

I created a mixin using the SVG method. It encodes the SVG and sets it as a background image in a pseudo element. This allows for quick usage in a self contained manner than doesn’t require additional inline markup.

👋

CSS-Tricks* is created, written by, and maintained by Chris Coyier and a team of swell people. It is built on WordPress and powered up by Jetpack. It is made possible through sponsorships from products and services we like.