When Pseudo-Elements Are No Longer Required

Pseudo-elements have been a dependable part of CSS for decades. According to the W3C spec, they represent elements not directly present in the document tree, with typographic, highlight, and tree-abiding categories.

In practice, most use involves ::before and ::after for decorations. But newer CSS properties now make some of those workarounds obsolete. This is not a call to abandon pseudo-elements entirely; rather, it is a look at patterns where they are no longer needed.

Removing Old Crutches With Modern CSS

The end of Internet Explorer 11 support—initiated by Microsoft 365 in August 2021 and Google Workspace in March 2021—opened the door wider for newer CSS features like CSS Grid, clamp(), and background-blend-mode.

Old techniques that relied on extra markup, positioning hacks, and stacking context management can sometimes be simplified or eliminated. In the patterns below, the pseudo-element version still works—and still has its place—but a pseudo-free version often means less code and fewer edge cases.

Angled Buttons Without Extra Elements

Creating angled buttons used to involve CSS border tricks, which typically required ample ::before/::after use and nested markup. Dedicated tools for generating such CSS snippets were common. But with modern CSS, the number of moving parts drops dramatically.

Instead of a pseudo-element positioned within an angled space, a single button element can use the clip-path property to mask out a corner. With polygon(), you specify points for the top-left, top-right, middle-right, bottom-right, and bottom-left corners, incorporating a CSS custom property to control the cutout angle:

  • The button remains a single wrapper element.
  • Each angle point is calculated with polygon(0% 0%, calc(100% - var(--angle-width)) 0%, 100% 50%, calc(100% - var(--angle-width)) 100%, 0% 100%).
  • To adjust the angle in the demo, change the --angle-width custom property from 2rem to another value.

With the pseudo-free version, hover styles apply to one element, and multiline text behaves more gracefully. A showcase demo illustrates several more button styles, some of which become significantly simpler with this approach.

Button Wipes via Background Properties

Hover wipes on buttons have often relied on an absolutely positioned pseudo-element whose transform is transitioned from scaleX(0) to full width. That approach forces management of transform-origin, stacking contexts, and a nested element for text to sit above the wipe layer.

A simpler path uses CSS gradients and background sizing:

  • Set a default background-color and define a linear-gradient as the background-image.
  • Set background-size: 0 so the gradient is hidden initially.
  • Transition background-size to 100% 100% on hover to produce the wipe effect.

No nested element or pseudo-element is needed. Since linear-gradient() belongs to background-image, it supersedes background-color when fully visible. Vertical wipes require little more than changing the gradient direction and the background-size values accordingly.

Screen Color Overlays on Tiles

The common pattern of an image tile with a semi-transparent hover overlay has a classic pseudo-element implementation. It typically relies on the aspect-ratio “padding trick,” absolute positioning for the overlay, and often a nested absolute-positioned element for text to ensure proper stacking above the overlay.

A cleaner approach no longer necessitates any of that:

  • The aspect-ratio property reserves space directly, without the extra padding trick. Note that aspect-ratio doesn’t work in Safari 14.x, though it’s supported in version 15.
  • background-blend-mode blends the element’s background-color with its background-image.
  • Altering the tile’s background-color on hover is sufficient for the overlay effect.

Unlike mix-blend-mode, background-blend-mode does not create a new stacking context, which avoids a common source of layout headaches.

Rethinking Familiar Patterns

Still, the original pseudo-element implementations are not obsolete. They work, and in many contexts they remain stable and predictable. But for these patterns, the modern CSS path is leaner and leaves less to juggle.

As browser support for newer features matures, long-standing workarounds can be revisited. A full showcase of the most interesting applications shows how often a pseudo-free solution is attainable, making it worthwhile to reassess where previous complexity was justified.