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:
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:
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 ).
Huzzah! We're getting really close now, it's probably time to ditch those borders and let the parent background shine through instead.
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!