CSS Pseudo-Elements Reference

All CSS pseudo-elements with syntax, generates flag and content area context.

A searchable reference for CSS pseudo-elements including ::before, ::after, ::marker, ::placeholder, ::slotted() and view-transition pseudo-elements, with what each targets, whether it generates content and browser support. It runs free in your browser on Gera Tools, with nothing uploaded.

Last updated Source: Gera Tools

What is the difference between :: and : in pseudo-elements?

The double-colon syntax (::before) distinguishes pseudo-elements from pseudo-classes, which use a single colon. For the four original pseudo-elements (::before, ::after, ::first-line, ::first-letter) the single-colon legacy form is still accepted for backwards compatibility.

This is a searchable reference for CSS pseudo-elements — the double-colon selectors that target a sub-part of an element or insert generated content. It spans the classic four (::before, ::after, ::first-line, ::first-letter), interface pseudo-elements like ::marker, ::selection and ::placeholder, shadow-DOM bridges, and the newer view-transition pseudo-element tree.

How it works

A pseudo-element is written with two colons followed by a keyword. Conceptually it lets you style something that is not a real element in your markup: the first letter of a paragraph, the bullet of a list item, the placeholder text in an input, or a fresh box of generated content. The generates column distinguishes the two kinds. ::before and ::after are generative — they create new boxes that only appear when you set the content property (use content: "" for purely decorative boxes). The rest are not generative — they hook into an existing sub-part such as ::first-line, ::marker or ::placeholder and only a restricted set of properties applies to each.

Pseudo-element directory

Pseudo-elementGeneratesWhat it targetsNotes
::beforeYesContent inserted before element’s contentRequires content; not on replaced elements
::afterYesContent inserted after element’s contentRequires content; not on replaced elements
::first-lineNoFirst formatted line of a blockLimited property subset only
::first-letterNoFirst letter (or punctuation) of a blockUseful for drop caps
::markerNoList item bullet or numberAccepts color, font, content only
::selectionNoCurrently selected textAccepts color, background-color
::placeholderNoPlaceholder text in form inputsStyle with care for contrast
::backdropNoBackground behind modal/fullscreenUsed with dialog[open] and Fullscreen API
::slotted()NoSlotted light-DOM children in shadow DOMShadow-internal only
::part()NoShadow-DOM elements with part attributePage-external styling hook
::view-transitionNoView transition snapshot tree rootCustomize cross-fade/slide transitions

Practical examples

Drop cap using ::first-letter:

p:first-of-type::first-letter {
  font-size: 3.5em;
  line-height: 0.8;
  float: left;
  margin: 0.05em 0.1em 0 0;
  font-weight: bold;
}

Custom counter badge using ::before:

.badge::before {
  content: counter(step);
  counter-increment: step;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.5em;
  height: 1.5em;
  border-radius: 50%;
  background: currentColor;
  color: white;
  font-size: 0.75em;
  margin-right: 0.5em;
}

Styled list markers:

li::marker {
  content: "→ ";
  color: #3b82f6;
}

Placeholder contrast fix:

input::placeholder {
  color: #6b7280; /* meets 4.5:1 on white */
  font-style: italic;
}

Tips and notes

Generative pseudo-elements cannot be placed on replaced elements like img, br, input or iframe, because those have no content box to host children. ::first-letter honours leading punctuation and is the standard way to build a drop cap. ::marker only accepts a handful of properties (color, font, content) — set list-style-type or its content to change the bullet. For shadow DOM, ::slotted() styles from inside the component while ::part() styles from outside, giving deliberate, contract-based theming hooks.

Everything runs in your browser; nothing you search is uploaded.