Pseudo-elements have been helping front-end developers implement creative designs for years. Although it still has an important place, we can now leave pseudo-elements behind in some scenarios, thanks to newer CSS features.
Per die W3C specification, “A pseudo-element represents an element that does not appear directly in the document tree”. They have been around since version 1 of the CSS specification
::first-line was introduced. The popular
::after pseudo-elements were added in version 2-it represents content that does not exist in the source document at all. They can be considered as two additional elements on which you can “fasten” their original element. When front-end developers hear ‘pseudo-elements’, we think of them
::after more often than not, as we use it in different ways to add embellishments to our elements.
Interestingly, after years of web development, I never found it
::first-line, but it is quite neat and responds well to the size of windows! Look at that.
::selection is another pseudo-element that achieves a lot. When a user highlights text, the color of the highlight is a color that you specify.
Pseudo-elements use one colon in versions 1 and 2 of the CSS specification, but have two columns of version 3. This distinguishes them from pseudo-classes, which describe the state of an element. Pseudo-class uses a colon.
- Use two colons for pseudo-elements (eg
- Use one colon for pseudo-classes (e.g.
Pseudo-elements are not always necessary
Pseudo-elements still have a place. This article is not “never use pseudo-elements”, but rather “we do not need to use pseudo-elements anymore”. We can style a number of popular user interface elements without the need for pseudo-elements. By relying less on pseudo-elements, we can write less CSS, eliminate nested elements, ignore context issues, and forget positioning.
Revisit Reliable Techniques With New CSS Properties
For years, we have been patiently waiting for browsers to use CSS technology faster. A turning point for many front-end developers came when some major players announced that they would discontinue Internet Explorer (IE11) support:
- All Microsoft 365 web applications have stopped supporting IE11 21 August 2021.
- Google Workspace (Gmail, Calendar, Row, etc.) stopped IE11 support 15 March 2021.
This has enabled many of us to explore newer CSS technologies more freely: CSS Grid,
background-blend-mode, and more. The state of CSS property support is excellent. And with upgradeable browsers, support accelerates.
Many front-end developers know how to use it
::after pseudo-elements and CSS boundary rules to create shapes. There are many generator tools dedicated to this – this is one which I made a bookmark. These tools guide you in choosing a shape (often triangles), and give you the right CSS rules.
These tools are lifesavers when making oblique buttons. For oblique buttons it is no longer necessary.
Many of you who read this are used to a pseudo-element version:
- We use a relatively placed wrapping element with a large right filling to accommodate our corner – this is ours
- Many of us, students of the sliding door technique, is accustomed to nesting an element to assume the background color of the button;
- Finally, we absolutely place a pseudo-element with its boundary rules in our
<button>is the right filling of the empty space – we use
Apart from these steps, our gliding styles need to consider both our nested element and pseudo-element. It may seem manageable to you, but the more complicated our button designs become, the more costly we have with hoover styles. Also with this version, word cover buttons simply fail.
No Pseudo-element version
It is much easier without a pseudo-element.
- We use one casing element – we
- We reach out to the
clip-pathproperty to show only the parts of our button we want to use
calc()along with a CSS-customized feature to enlarge our angle – these sets of points correspond to top left, top right, center right, bottom right and bottom left:
polygon(0% 0%, calc(100% - var(--angle-width)) 0%, 100% 50%, calc(100% - var(--angle-width)) 100%, 0% 100%)
In the CodePen example, you change the
--angle-width personal property of
2rem to another value to adjust the angle of our button accordingly.
Our hover styles only need to consider one element – our button. Word envelope buttons also work in a more graceful way.
More angular button styles in the display case
Visit the last display to make these other button styles easier without pseudo-elements. In particular, the pseudo-element version of the blue slanted button is pretty brutal. The total work is significantly reduced, thanks to
A sweep effect is a popular button style. I included left-to-right and top-to-bottom cloths.
This can be achieved by
transitioning a pseudo-element’s
- We absolutely position a
::beforepseudo-element and give it a
transform: scaleX(0)so it is not visible.
- We must also make it explicit
transform-origin: 0 0to ensure that the wipe enters from the left instead of the middle (
transform-origindefault to center).
- We set up
transformfor a bit of smooth jazz animation floating on / off.
- Because our pseudo-element is absolutely placed, we need a nested element to hold the text of the button,
position: relativeon this nested element creates a new stack context so that our text stays on top of our erase pseudo-element.
- On the soar we can use our pseudo-element and
scaleXto be now
1 (transform: scaleX(1)).
No Pseudo-element version
Why worry about nested elements, positioning of pseudo-elements, stacking contexts and extended hover rules when it is not necessary?
We can reach for
background-size to catch it.
- We give our
background-colorfor the default state, while also providing a
background-image– but the
0, so by default we will not see anything.
- As we move, we change the
100% 100%which gives us our livestock effect!
linear-gradient() use the
background-image property and
background-color, so this is what takes precedence in gliding.
That’s it. No nested element required. Do you want a vertical cattle? Just change the
linear-gradient direction and the
background-size values. I changed it via CSS custom properties.
Tiles with screen color overlays
This is a common pattern where a semi-transparent color overlays a tile / card. The tile of our example also has a background image. In this pattern, it is often important to maintain a fixed aspect ratio so that tiles look uniform when more than one appears in a set.
Some of the same things come into play with our pseudo-element version:
- We use the aspect ratio “fill-up trick”, with a 60% fill-top value (ratio 5: 3) for our tile.
- We need to place our pseudo-element of our screen color so that it is a 100%
heightto fill the tile-we aim this pseudo-element on hover to change its
- Due to the absolute position of the pseudo-element, we need to use a nested element for our textual content, and also give it
position: absoluteso that it can appear above here our screen color scheme in the stacking order and to ensure that it appears in the tile where it should.
No Pseudo-element version
aspect-ratio does not work in Safari 14.x but does in version 15.
That said, at the time of writing, caniuse call it with 70% + worldwide support.
- The padding trick is replaced by
aspect-ratio: 400/240(we can use a 5: 3 based value here).
- We use both
background-blend-mode– simply change the
background-colorof our tile element on hover.
background-blend-mode blends a
background-color with an element’s
background-image. Any Photoshop users who read it will find it
background-blend-mode reminds of the mixing modes of Photoshop. Other than
background-blend-mode does not create a new stack context! So no
Front-end development is exciting and fast-paced. With newer CSS features, we can wipe the dust off our old techniques and give it back. By doing so, the reduced and simpler code is promoted. Pseudo-elements are useful, but we do not have to achieve so much for them.