Modern CSS pseudo-elements for styling without extra DOM nodes. Use when implementing view transitions, adding decorative layers, or styling native browser UI...
Modern CSS pseudo-elements provide direct styling hooks into browser-native features—dialogs, popovers, view transitions—reducing the need for JavaScript. Sometimes you don't need to install a library; the browser has you covered.
Reference these guidelines when:
| Pseudo-Element | Purpose |
|---|---|
::before / ::after |
Decorative layers, icons, hit targets |
::view-transition-group(name) |
Control view transition animations |
::view-transition-old(name) |
Style the outgoing snapshot |
::view-transition-new(name) |
Style the incoming snapshot |
::backdrop |
Style dialog/popover backdrops |
::placeholder |
Style input placeholders |
::selection |
Style selected text |
Create anonymous inline elements as first/last child. Require content to render.
.button {
position: relative;
}
.button::before {
content: "";
position: absolute;
inset: 0;
transform: scale(0.95);
opacity: 0;
transition: transform 0.2s, opacity 0.2s;
}
.button:hover::before {
transform: scale(1);
opacity: 1;
}
Use cases:
Animate between DOM states with document.startViewTransition(). The browser captures snapshots and generates pseudo-elements for both states.
view-transition-name to source elementdocument.startViewTransition()sourceImg.style.viewTransitionName = "card";
document.startViewTransition(() => {
sourceImg.style.viewTransitionName = "";
targetImg.style.viewTransitionName = "card";
});
::view-transition-group(card) {
animation-duration: 300ms;
animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
}
When two elements share the same view-transition-name across a transition, the browser treats them as the same element and interpolates between their positions, sizes, and styles.