Skip to main content

CSS Pseudo-Elements Cheatsheet

Complete reference for all CSS pseudo-elements. Create content, style text parts, and customize browser UI.
Click any example to copy the code to your clipboard.

:: vs : Syntax

CSS3 introduced the double colon (::) notation for pseudo-elements to distinguish them from pseudo-classes which use a single colon (:). For legacy browser support, ::before and ::after also work with single colons, but the double colon is the modern standard.

Interactive Demos

::before and ::after Demo

Decorative quotes:

The only way to do great work is to love what you do.

External link indicator:

Required field asterisk:

.quote::before {
  content: '"';
  font-size: 2em;
  color: var(--primary);
}

.external-link::after {
  content: ' ↗';
}

.required::after {
  content: ' *';
  color: red;
}

::first-letter Demo (Drop Cap)

Once upon a time, in a land far away, there lived a developer who discovered the magic of CSS pseudo-elements. With just a few lines of code, they could create beautiful drop caps that made their articles look like they belonged in a classic book.

p::first-letter {
  font-size: 3.5em;
  float: left;
  font-family: Georgia, serif;
  font-weight: bold;
  color: var(--primary);
  line-height: 0.8;
  margin-right: 0.1em;
  margin-top: 0.05em;
}

Allowed properties: font, color, background, margin, padding, border, text-decoration, text-transform, line-height

::first-line Demo

The first line of this paragraph is styled differently. The rest of the text continues normally. Try resizing your browser window to see how the first line selection changes dynamically based on where the line breaks. This is a key difference from styling the first sentence - it's truly based on visual line breaks.

article::first-line {
  font-weight: bold;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--primary);
}

Note: The selection is dynamic - try resizing the viewport to see how it adjusts!

::selection Demo

Try selecting this text with your mouse:

Select this text to see the custom selection color! The background will turn coral and the text will become white. This creates a branded feel for your website and makes the selection experience unique.

/* Global selection style */
::selection {
  background-color: #ff6b6b;
  color: white;
}

/* Element-specific selection */
.special-text::selection {
  background-color: gold;
  color: black;
}

Allowed properties: color, background-color, text-decoration, text-shadow, stroke-color, fill-color

::placeholder Demo

input::placeholder {
  color: #e91e63;
  font-style: italic;
  opacity: 0.8;
}

/* Vendor prefixes for older browsers */
input::-webkit-input-placeholder { }
input::-moz-placeholder { }
input:-ms-input-placeholder { }

Accessibility tip: Ensure placeholder text has at least 4.5:1 contrast ratio with the input background.

::marker Demo

Colored markers:

  • First item
  • Second item
  • Third item

Emoji markers:

  • Task completed
  • Task completed
  • Task completed

Arrow markers:

  • Step one
  • Step two
  • Step three
/* Change marker color */
li::marker {
  color: #6366f1;
  font-size: 1.3em;
}

/* Custom content markers */
li::marker {
  content: '→ ';
  color: green;
}

/* Emoji markers */
li::marker {
  content: '✅ ';
}

::backdrop Demo

The ::backdrop pseudo-element styles the area behind a dialog or fullscreen element.

dialog::backdrop {
  background: rgba(0, 0, 0, 0.7);
  backdrop-filter: blur(4px);
}

/* For fullscreen elements */
video:fullscreen::backdrop {
  background: black;
}

Usage: Works with native <dialog> element using showModal() and elements in fullscreen mode.

Content Generation

Pseudo-elements that create content before or after an element

::beforeAll browsers

Creates a pseudo-element as the first child of the selected element. Requires the content property.

.quote::before {
  content: '"';
  font-size: 2em;
  color: gray;
}

Note: The content property is REQUIRED - without it, the pseudo-element won't render.

Click to copy
::afterAll browsers

Creates a pseudo-element as the last child of the selected element. Requires the content property.

.external-link::after {
  content: ' ↗';
  font-size: 0.8em;
}

Note: Works the same as ::before but appears after the element's content.

Click to copy

Text Styling

Pseudo-elements for styling specific parts of text content

::first-letterAll browsers

Targets the first letter of the first line of a block element. Perfect for drop caps.

p::first-letter {
  font-size: 3em;
  float: left;
  line-height: 0.8;
  margin-right: 0.1em;
}

Note: Only works on block elements. Limited properties: font, color, background, margin, padding, border, text-decoration, text-transform, line-height.

Click to copy
::first-lineAll browsers

Targets the first line of text in a block element. The selection is dynamic based on viewport width.

article::first-line {
  font-weight: bold;
  font-size: 1.1em;
  color: navy;
}

Note: Limited properties: font, color, background, text-decoration, text-transform, letter-spacing, word-spacing, line-height.

Click to copy

User Selection

Pseudo-elements for styling user-selected content

::selectionAll browsers

Styles the portion of text that is highlighted/selected by the user.

::selection {
  background: #ff6b6b;
  color: white;
}

Note: Limited properties: color, background-color, text-decoration, text-shadow, stroke-color, fill-color. Firefox requires ::-moz-selection for older versions.

Click to copy

Form Elements

Pseudo-elements for styling form-related content

::placeholderAll browsers

Styles the placeholder text in input and textarea elements.

input::placeholder {
  color: #999;
  font-style: italic;
  opacity: 1;
}

Note: For accessibility, ensure sufficient color contrast. Some browsers apply opacity to placeholders by default.

Click to copy

List Markers

Pseudo-elements for styling list item markers

::marker95%+ support

Styles the marker box of a list item (bullet point or number).

li::marker {
  color: #ff6b6b;
  font-size: 1.2em;
  content: '→ ';
}

Note: Limited properties: color, font properties, content, animation/transition properties. Relatively new but well-supported.

Click to copy

Dialog & Fullscreen

Pseudo-elements for modal and fullscreen contexts

::backdrop95%+ support

Styles the backdrop behind a dialog or element in fullscreen mode.

dialog::backdrop {
  background: rgba(0, 0, 0, 0.7);
  backdrop-filter: blur(4px);
}

Note: Used with <dialog> element and Fullscreen API. Great for creating modal overlays.

Click to copy

The content Property

The content property is required for ::before and ::after pseudo-elements. Here are all the possible values:

ValueDescription
content: "";Empty string - required for purely decorative pseudo-elements
content: "Text";Static text content
content: attr(data-label);Attribute value - pulls from data-* or other attributes
content: url("/icon.svg");Image content
content: counter(section);CSS counter value
content: open-quote;Opening quotation mark based on quotes property
content: close-quote;Closing quotation mark based on quotes property
content: "→ " attr(href);Combined values (text + attribute)

Practical Examples

External Link Icons

Add arrow icons after external links automatically

a[href^="http"]::after {
  content: ' ↗';
  font-size: 0.8em;
  vertical-align: super;
}
Click to copy

Decorative Underlines

Create custom animated underlines on hover

.fancy-link {
  position: relative;
}

.fancy-link::after {
  content: '';
  position: absolute;
  bottom: -2px;
  left: 0;
  width: 0;
  height: 2px;
  background: linear-gradient(to right, #6366f1, #ec4899);
  transition: width 0.3s ease;
}

.fancy-link:hover::after {
  width: 100%;
}
Click to copy

Tooltip Arrows

Create CSS-only tooltip arrows

.tooltip {
  position: relative;
}

.tooltip::after {
  content: '';
  position: absolute;
  bottom: 100%;
  left: 50%;
  transform: translateX(-50%);
  border: 8px solid transparent;
  border-bottom-color: #333;
}
Click to copy

Custom Checkboxes

Style checkboxes with pseudo-elements

.checkbox-custom {
  position: relative;
  padding-left: 28px;
  cursor: pointer;
}

.checkbox-custom::before {
  content: '';
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 20px;
  height: 20px;
  border: 2px solid #6366f1;
  border-radius: 4px;
}

.checkbox-custom.checked::after {
  content: '✓';
  position: absolute;
  left: 4px;
  top: 50%;
  transform: translateY(-50%);
  color: #6366f1;
  font-weight: bold;
}
Click to copy

Blockquote Styling

Add decorative quotation marks to blockquotes

blockquote {
  position: relative;
  padding-left: 40px;
  font-style: italic;
}

blockquote::before {
  content: '"';
  position: absolute;
  left: 0;
  top: -10px;
  font-size: 4em;
  font-family: Georgia, serif;
  color: rgba(99, 102, 241, 0.3);
  line-height: 1;
}
Click to copy

Clearfix Pattern

Classic clearfix for floated elements

.clearfix::after {
  content: '';
  display: table;
  clear: both;
}
Click to copy

Image Overlay

Add a color overlay on images

.image-overlay {
  position: relative;
}

.image-overlay::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to bottom,
    transparent,
    rgba(0, 0, 0, 0.7)
  );
}
Click to copy

Required Field Indicator

Add asterisk to required form labels

label.required::after {
  content: ' *';
  color: #ef4444;
  font-weight: bold;
}
Click to copy

Pseudo-Elements vs Pseudo-Classes

Pseudo-Elements (::)Pseudo-Classes (:)
Style parts of an elementStyle states of an element
Create virtual elements in the DOMTarget existing elements based on conditions
::before, ::after, ::first-letter:hover, :focus, :nth-child()
Only one pseudo-element per selectorCan chain multiple pseudo-classes

Browser Support Legend

All browsersSupported everywhere
95%+ supportAll modern browsers
Modern browsersChrome 105+, Safari 15.4+, Firefox 121+