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-element | Generates | What it targets | Notes |
|---|---|---|---|
::before | Yes | Content inserted before element’s content | Requires content; not on replaced elements |
::after | Yes | Content inserted after element’s content | Requires content; not on replaced elements |
::first-line | No | First formatted line of a block | Limited property subset only |
::first-letter | No | First letter (or punctuation) of a block | Useful for drop caps |
::marker | No | List item bullet or number | Accepts color, font, content only |
::selection | No | Currently selected text | Accepts color, background-color |
::placeholder | No | Placeholder text in form inputs | Style with care for contrast |
::backdrop | No | Background behind modal/fullscreen | Used with dialog[open] and Fullscreen API |
::slotted() | No | Slotted light-DOM children in shadow DOM | Shadow-internal only |
::part() | No | Shadow-DOM elements with part attribute | Page-external styling hook |
::view-transition | No | View transition snapshot tree root | Customize 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.