Using @supports To Test For Clip-Path

I stopped using Modernizer a few years back for a few reasons, mainly because I wanted to drop as many dependencies and scripts as I could. I was using Modernzier mainly for smaller visual items that wouldn’t be missed if certain users couldn’t see them, so I didn’t see it as a critical script. Since then, I’ve been using CSS3 features such as border-radius and text-shadow with abandon, and allowing older browsers to display without them.

Recently, a client gave me an interesting design to code up. The design was split into sections, with each section the edge was angled up or down. Some of the sections had image backgrounds and some had a flat black background. Something similar to this:


Except imagine around 8 or 9 modules, all with different edge angles butting up against one another. I decided to take this project on as a challenge. I didn’t want to use images with the angle in them, because that would put the burden on the client to be able to cut that out themselves in an image editor. Nor did I want to upload a huge image for just a plain color background, or try using negative positioning or margins or pseudo elements to get a slice to line up properly. I also wanted to be able to control this responsively – to either be able to turn the angles off completely, or at least make them less severe when on a small mobile device.

The first thing I turned to was the new clip-path property. It’s currently only supported in Chrome and Safari, so Firefox, Opera and IE users would just see regular flat rectangles. This was fine.

Each section had to be given a manual padding to vertically align the text (since auto vertical aligning like the absolute and transform trick would take the tip of the angle into account, we couldn’t use these) and a negative margin so it would butt up with the section before it. The code and output looked a bit like this:

<div class="box box1">SECTION 1</div>
<div class="box box2">SECTION 2</div>
.box {
  background: pink;
  color: #fff;
  height: 250px;
  padding: 50px;
  text-align: center;
  width: 100%;
.box1 {
  -webkit-clip-path: polygon(0 0, 100% 0, 100% 75%, 0 100%);
   clip-path: polygon(0 0, 100% 0, 100% 75%, 0 100%);
   padding-top: 210px;
.box2 {
  background: url('') no-repeat;
  background-size: cover;
  -webkit-clip-path: polygon(0 25%, 100% 0, 100% 100%, 0% 100%);
  clip-path: polygon(0 25%, 100% 0, 100% 100%, 0% 100%);
  margin-top: -221px;
  padding-top: 368px;


Now usually, when a browser can’t support something, it just ignores it and things are fine. But because we were using extreme paddings and margins, things looked a bit shit in browsers like Firefox:


The second module was negatively positioned up, so it was eating the section before it, and then text positioning was off.

Luckily I had one more idea! @supports! I’ve been reading it for a while, but didn’t see a use for it just yet, because everything I used “degraded” just fine in older browsers. But in this case, I could use @supports to check for clip-path support, and put not only the clip-path code inside of the module, but the negative margins and paddings as well.

I loved the idea of having almost an if/else ability in CSS now. Basically the browser would read the regular CSS without these properties first, and then would come to the @supports module. If it was an older browser that didn’t support @supports, it would ignore it completely. If it was Firefox, or a newer browser it would read @supports and check to see if it was a supported property (in this case, does the browser support clip path)? And would either output or ignore it.

My final code became this (try checking out the Codepen in both Chrome and Firefox to see the difference).

See the Pen Combining @supports and clip-path by Amber Weinberg (@amberweinberg) on CodePen.

You’ll notice a big difference in the positioning of text.

Being my first time using @supports, I did have a bit of trouble getting it to work at first. I found that you need to use both the browser prefixed and regular versions of the rule you’re checking for, so:

@supports(-webkit-clip-path: polygon(0 0, 100% 0, 100% 75%, 0 100%)) or (clip-path: polygon(0 0, 100% 0, 100% 75%, 0 100%))

Also, pay major attention to syntax and the parenthesis order. That was a huge trip up for me!