CSS Pseudo-Elements Table
| Pseudo-element | What it creates |
|---|---|
| ::before | Virtual element before the content - used for icons, decorations, counters |
| ::after | Virtual element after the content - used for badges, clearing floats, tooltips |
| ::placeholder | Styles the placeholder text of input and textarea elements |
| ::selection | Styles the highlighted portion when the user selects text |
| ::marker | Styles the bullet or number of list items |
| ::first-line | Styles the first line of a block-level element |
| ::first-letter | Styles the first letter of a block-level element (drop caps) |
| ::backdrop | Styles the area behind a modal dialog or fullscreen element |
CSS pseudo-elements create virtual elements that don’t exist in the HTML - ::before and ::after inject content, ::placeholder styles input hints, ::selection changes text highlight color. The double-colon syntax (::) distinguishes them from pseudo-classes (single colon :hover) since CSS3.
The two workhorses are ::before and ::after - they require the content property (even content: "") and are how every CSS icon, badge, tooltip and decoration is added without extra HTML elements.
How to use
- Filter by pseudo-element name or purpose - before, placeholder, selection - to find what you need.
- Click any pseudo-element to copy it into your CSS.
- Remember: ::before and ::after require the content property to render, even an empty string.
Frequently asked questions
What is the difference between ::before and ::after?
They are functionally identical except for position: ::before inserts before the element’s content, ::after inserts after. Both require the content property (even an empty string ""). Both are inline by default and can be styled with any CSS property. Convention: ::before for icons and leading decorations, ::after for trailing badges and clearfix.
Why does my ::before or ::after not show up?
The most common cause: missing the content property. Without content: "" (or any value), the pseudo-element does not render at all. Second cause: the parent element is empty - pseudo-elements are children of the element, so an empty element with no content has nothing to be before or after.
What is the ::backdrop pseudo-element?
It styles the area behind a modal dialog or fullscreen element - the dimmed background that appears when you use the <dialog> element with showModal() or the Fullscreen API. You can control its color, blur and transparency: dialog::backdrop { background: rgba(0,0,0,0.5) }.
How do I style the browser’s default text selection color?
Use ::selection: it changes the background and color of highlighted text. This is purely cosmetic - it does not affect usability or accessibility. Most design systems set it to the brand color at low opacity for a subtle branded touch.