Skewed backgrounds with CSS

In this post we'll talk about creating a skewed background with CSS, similar to the one used in the theme for this blog. It's not too hard of a problem, the real challenge is separating the background from the content so that we can skew the background without applying the effect to the rest of the content.

We'll start with a container and some content:

And we'll give it some basic styles:

...which produces this result:

The standard you walk past, is the standard you accept.

Adding the top of the background

To create our skewed background, we can use generated content in CSS via the ::before and ::after pseudo-elements.

Let's start with the top part of the background, shall we?

The first thing we'll do is add position: relative to our container, so that we establish a new stacking context to position within. We'll also add z-index: 1, to make sure that the main content is layered on top.

Then, we'll add some generated content using the ::before pseudo-element. While we're creating this content, we'll size it to match the parent container, and position it directly within the same bounding box (but using a lower z-index value, so that it sits "behind" the main content in the container).

Notice as well that we set content: '', which is an indication that we're only using this to draw an extra box on screen... if we wanted to show some text too we'd update this property to include it.

Finally, we'll apply a little skew and add a purple border so we can see what we're working with:

The standard you walk past, is the standard you accept.

Not bad, eh? Things are happening!

Don't worry if this doesn't all sink in right at once. A simplistic explanation of how this works is that the transform: skew(0, -2deg) rule is creating a transform, more specifically a skew of -2 degrees on the Y axis... a positive value will reverse the slope to be "down and to the right", although for that to work you'll also need to change the transform-origin propery, because...

Adding the bottom of the background

In addtion to ::before (which places the content before the selector, unsurpringly), we can also use ::after, which places the content after the selector, and more importantly gives us another chance to add some additional content that we'll use for the bottom part of the background.

We'll set the ::after content up similarly, but use a yellowgreen border instead so that we can tell them apart easily. We'll also need to adjust the transform-origin property, so that the skew effect is applied from the bottom right (again: without this the bottom background would be within the container ).

The standard you walk past, is the standard you accept.

Huzzah! We're getting really close now, it's probably time to ditch those borders and let the parent background shine through instead.

The standard you walk past, is the standard you accept.

Noice. Even if the web is really all boring rectangles underneath, we can certainly pretend otherwise.

That's it!

Hopefully this technique lets you add some visual flair to your designs. Remember too that the possibilities are nearly endless, you can take this idea and tweak it to suit your needs:

  • Use different angles for the the top and bottom
  • Apply the skew to the X axis (left / right) instead
  • Use border-radius to soften those sharp corners a bit

As always, thanks for reading!