While working on a recent project, I needed to use angled background stripes on a number of pages.
Here are a couple of requirements that limited my options:
- Angled stripes with text content and a background color and/or image
- Angled stripes stacked on top of each other
CSS transform: skewY()
My first idea was to try transform: skewY(4deg)
on a wrapper element and transform: skewY(-4deg)
on the internal element(s). Makes sense, right? Skew it and then unskew it? Two problems with this approach though:
- Causes extra work for the rendering engine (and therefore performance hit)
- Messes with layout: if you have multiple elements with the negative skew, the tops get offset the further down the row you go because the wrapper itself is skewed.
CSS pseudo-content with transform: skewY()
My next idea was to simply use :before
and :after
pseudo-content blocks and use transform: skewY(4deg)
to angle them as required.
Pros
- Cross-browser
- Fairly easy to implement: specify an angle and you’re done
Cons
- Only works with background images/colors
- Can’t stretch
<img…/>
tags to cut them off at an angle
Sample Code
https://gist.github.com/macbookandrew/acf0d90bf14db9c8cec92d0c8ee5a65a#file-pseudo-content-method-scss
CSS clip-path: polygon()
property
The next idea and the one I ended up using for most of the project was the clip-path: polygon()
property along with vw
units to keep the angle consistent at all browser widths.
Pros
- Work with
<img…/>
tags and other content (lets you clip off parts of an image) - Much less code 😄
Cons
- Doesn’t work in any version of IE
- A bit more complicated to figure out since you have to ensure child elements have enough padding so they don’t end up getting clipped
Sample Code
https://gist.github.com/macbookandrew/acf0d90bf14db9c8cec92d0c8ee5a65a#file-clip-path-method-scss