How to Use CSS3 Pseudo-Elements to Create Asymmetrical Designs

A Beginner’s Guide

Rose Gauthier
Jul 11, 2016 · 4 min read

View in CodePen

Asymmetric or diagonal elements and non-right angles have gained traction with web designers in recent years. Luckily for us developers, they are also fairly straightforward to implement. If your design requires some asymmetry or diagonal elements you can do it simply with CSS3.

The transform property works perfectly if the desired outcome is a parallelogram. The “rotate” property value allows us to easily turn squares into diamonds, the “skew” value does the trick if you’re trying to achieve a parallelogram with non-right angles. Transforms are simple, readable and powerful to help you create dramatic effect with very little CSS. If diamonds, diagonal bars or really any other parallelogram is what you’re after, I suggest you head over to CSS Tricks to learn all about these values.

What if you want the effect of the “skew”, but only on one side or perhaps wish to add angles that move in opposite directions? Enter CSS pseudo-elements, specifically ::before and ::after. For this basic example, I’ll show you how to make a section of your page into a geometric shape, like this:

The font used in the example is Raleway, available on Google Fonts

I added some styling to 3 HTML sections to give a good starting place.

View in CodePen

To add the angle at the top of the section I’m going to use a ::before pseudo-element on the section. This pseudo-element will be identical to the section in height and width. Add “position: relative” to the .asymmetric section and position the ::before absolutely. In the finished product I’ll change the colour of the pseudo-element to match the section, but for now I’ve chosen a contrasting colour to highlight the pseudo-element.

.asymmetric {
position: relative;
background-color: #7CCBF2;
}
View in CodePen

So what happened? The pseudo-element, pictured above in purple, is the same size as the .asymmetric so the content is hidden underneath. I’ll fix this a little later, but for now I’m going to use the CSS3 property transform to add some diagonal lines. More specifically, I’m going to apply the “skew” value to the ::before to change the angle of the .asymmetric block element. I am trying to achieve a vertical skew, so the value is skewY(). I want to skew the pseudo-element upwards, and to match the example I’m going to change the angles by 3deg. I also used another handy property called “transform-origin”. This essentially allows me to control the base positioning of the transformed element. 2D transforms are well supported, but vendor prefixes are required. I have not included them in my example code for simplicity’s sake.

.asymmetric::before {
position: absolute;
content: "";
width: 100%;
height: 100%;
top: 0;
left: 0;
background-color: rebeccapurple;
transform-origin: top left;
transform: skewY(-3deg)
}
View in CodePen

Now we have created this great angled edge to our section. I can see the blue background of the .asymmetric section peeking through underneath the pseudo-element, and I’ll use a z-index to push the pseudo-element underneath so our content will again be visible.

.asymmetric::before {
position: absolute;
content: "";
width: 100%;
height: 100%;
top: 0;
left: 0;
background-color: rebeccapurple;
transform-origin: top left;
transform: skewY(-3deg)
z-index: -10;
}
View in CodePen

Change the background colour of the pseudo-element to match the .asymmetric section and it appears as though you have a section with one non-parallel side.

View in CodePen

To create the effect of the diverging angles, I will repeat the process with a second pseudo-element. It is worth noting that you can only have one ::before and one ::after per element, so I will use ::after, and simply switch the skewY() to 3deg. I’m trying to achieve a downward slope from left to right, so I’ll also change the transform-origin to bottom. This last bit of styling achieves the desired result of a section with diverging sides.

.asymmetric::after {
position: absolute;
content: "";
width: 100%;
height: 100%;
top: 0;
left: 0;
background-color: #7CCBF2;
transform-origin: bottom left;
transform: skewY(3deg);
z-index: -10;
}
View in CodePen