Over at Medium, Jon Moore recently identified “non-rectangular headers” as a tiny trend. A la: it’s not crazy popular yet, but just you wait, kiddo.
We’re talking about headers (or, more generally, any container element) that have a non-rectangular shape.
Such as trapezoids:

Or more complex geometric shapes:


Or rounded/elliptical:

Or even butt-cheek shaped:

My money is on these gaining popularity too. So let’s beat the crowd, and talk about a few ways of coding these up. Because let’s face it: they do look pretty awesome.
Image
Perhaps the simplest way to create any of the non-rectangular headers pictured above is to slap an image on top of your header.
But there are a few issues here:
- 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.
With an angled background one like, one choice you have to make is: what should remain constant as the screen-width changes, the angle or the height differential between the two sides?
If you want the angle to remain constant, set the height of the SVG in vw:

If you want the height differential to remain constant, set the height of the SVG in pixels:

And you need not pick just one – we can style this responsively, since SVG elements are subject to media queries. Check out this geometric style header at widths below and above 700px.
Shoot, son. What’s not to love? Oh, and we can even do the butt-cheeks style.
(Perhaps that’s more properly done with beziers, but you get the idea!)
One more thing worth nothing, and that is if you want to do an SVG background entirely in CSS, you could save the SVG and reference its URL in a pseudo element.
header::after {
content: "";
position: absolute;
bottom: 0;
width: 100%;
height: 100px;
background: url(divider.svg);
}
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
.
And a concave elliptical header could simply have the border-radius on the element after the header.
section {
border-bottom-left-radius: 50% 20%;
border-bottom-right-radius: 50% 20%;
}
Another benefit to this method is that the background of the section below the header could still have background images.
transform: skew
If we know that we want to create do a trapezoidal header, we can use a CSS transform to skew the whole thing.
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.


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.
I wish you would be more specific in the browser support category. All browsers support clip-path except, Microsoft browsers, both IE and Edge.
At the moment FF has issues with clip-path: polygon() and % units. But it will be resolved in FF53.
I’m not seeing clip-path working on iOS either.
Wow, thank you so, so much for sharing this with us!!!
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 agree it’s an awesome post ;)
It’s by Erik Kennedy, who has a lot more to teach in his course we linked up at the bottom!
If you’re trying to use SVGs with complex backgrounds, clipping might be a viable option.
https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Clipping_and_masking
Hey Erik,
Great post! :)
I just implemented this the non rectangular header for a new service we were launching. I went with the rounded/elliptical one and used clip-path with subtle animation :)
https://juststickers.in/app-icon-stickers/
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 :)
Interesting topic. Thank you for the great ideas (as always). : )
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.
What if header’s shape must drop shadow?
box-shadow will work perfectly with transform: skew, see example → http://i.imgur.com/X5DRAEw.png
You can also use filters like the webkit-filter: drop-shadow. This way the shadow will follow the shape of your element. I just had this case today, using it on an animated wave. :)
If you’re not using skewing, you can either use CSS filters (drop-shadop) or SVG filters (more complex).
2Alex
Agree. Box-shadow works with streight egdes. But in the example with border-radius it’s better to use filter: drop-shadow.
Awesome article! I loved it!
Simple geometric shapes can be done with CSS linear-gradient: http://codepen.io/anon/pen/ygwGzg
Using transparent part of the gradient (rgba(255, 255, 255, 0)) it is possible to show a background bellow the header.
Another way to do this, with transform: skew, can be done without an extra element. We can skew header and then unskew all child elements: http://codepen.io/anon/pen/OWqrBV
We recently opted to go with the approach of using a pseudo element that is skewed, seemed to work best, but it only works for simple diagonal headers.
Hi guys, you are making a great work here!
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?
Thank a lot!
Love this! thanks for sharing!
Sadly, SVGs in Safari on macOS, on a retina device is not really perfect. Haven’t tested Chrome though. I blame it on the crisp screen.
Jep, surprised the author didn’t address this as it’s an easy fix — just create the shape so it’s “blocky” in the bottom (maybe equivalent of 4px and then set margin-bottom on the svg to e.g. -2px
Feeling pretty validated about my design choice now <:)
https://yourweb.expert
I’ve had some success in the past using CSS Pseudo-elements, in a background-additive manner.
Here’s a quick demo of some of the possible techniques: http://codepen.io/ndorfin/pen/egqOLG?editors=0100
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.
https://github.com/josephfusco/angled-edges
Haha, I was just starting to tackle this last month. So glad I came here so I don’t have to struggle and figure it out on my own. I posted this concept on Feb 01 https://dribbble.com/shots/3259225-Arctic-Explorer-site