Skip to content

CSS Pseudo-element

Learn how to style specific parts of an element using pseudo-elements.

A CSS pseudo-element is a keyword added to a selector that lets you style a specific part of the selected element(s). They behave like adding virtual elements to the markup without actually modifying the HTML.

Common uses include:

  • Styling the first letter or first line of a text block (::first-letter, ::first-line).
  • Inserting content before or after an element’s actual content (::before, ::after).
  • Styling the placeholder text in form inputs (::placeholder).
  • Styling the user-selected portion of an element (::selection).
  • Styling list markers (::marker).

Modern CSS syntax requires using a double colon (::) to distinguish pseudo-elements from pseudo-classes (which use a single colon :).

selector::pseudo-element {
property: value;
}
Historical Note: CSS1 and CSS2 used a single colon (:) for both pseudo-elements and pseudo-classes. While browsers generally support the single-colon syntax for older pseudo-elements (like :first-line, :first-letter, :before, :after) for backward compatibility, always use the double colon (::) for modern CSS to maintain clarity and adhere to standards.

Applies styles to the first line of a block-level element (like <p>, <div>). The exact length of the first line depends on factors like element width, font size, etc.

p::first-line {
color: navy;
font-weight: bold;
text-transform: uppercase;
}

Only a subset of CSS properties can be used with ::first-line. Common ones include font, color, background, spacing, and text decoration properties. Check MDN for the full list.

Applies styles to the first letter of the first line of a block-level element, often used for creating “drop caps”.

p::first-letter {
color: #8A2BE2; /* BlueViolet */
font-size: 2.5em; /* Significantly larger */
float: left; /* Allows text to wrap around */
margin-right: 0.1em;
line-height: 0.8; /* Adjust line height for alignment */
}

Like ::first-line, only certain CSS properties apply. These often include font, color, background, margin, padding, border, text-decoration, and float properties.

These are arguably the most versatile pseudo-elements. They insert generated content before (::before) or after (::after) the actual content of an element. They are rendered inside the element but before/after its children.

Crucially, they require the content property to specify what to insert, even if it’s empty (content: '';).

blockquote::before {
content: '“'; /* Opening quote */
font-size: 2em;
color: gray;
margin-right: 5px;
}
blockquote::after {
content: '”'; /* Closing quote */
font-size: 2em;
color: gray;
margin-left: 5px;
}
.link-external::after {
content: ' ↗'; /* Unicode arrow */
font-size: 0.8em;
display: inline-block; /* Needed for potential transforms */
margin-left: 3px;
}
/* Styling a custom bullet */
li::before {
content: '► ';
color: dodgerblue;
margin-right: 8px;
/* Requires list-style: none on the li or ul */
}

::before and ::after can be styled almost like regular elements (background, border, padding, etc.), making them useful for various decorative effects.

Applies styles to the portion of an element that a user highlights (selects) with their mouse or keyboard.

Only a limited set of properties can be applied: color, background-color, text-shadow, text-decoration.

::selection {
color: white;
background-color: #FF4500; /* OrangeRed */
}

Pseudo-elements can be combined with other selectors, like classes, for more specific targeting.

p.important::first-letter {
color: red;
font-size: 1.5em;
}
.tooltip::after {
content: attr(data-tooltip); /* Display tooltip text from data-* attribute */
/* Additional styling for tooltip appearance */
position: absolute;
/* ... more styles ... */
}
  • ::placeholder: Styles the placeholder text in <input> and <textarea> elements.
  • ::marker: Styles the bullet point or number of a list item (<li>).
input::placeholder {
color: lightgray;
font-style: italic;
}
li::marker {
color: green;
font-size: 1.2em;
}
SelectorExampleDescription
::afterp::afterInsert content after the content of every

element.

::beforep::beforeInsert content before the content of every

element.

::first-letterp::first-letterSelects the first letter of every block-level element like

.

::first-linep::first-lineSelects the first line of every block-level element like

.

::markerli::markerSelects the marker (bullet/number) of a list item.
::placeholderinput::placeholderSelects the placeholder text in an input or textarea.
::selection::selectionSelects the portion of an element that is highlighted by the user.

Pseudo-classes select elements based on their state or position in the document tree.

SelectorExampleDescription
:activea:activeSelects an element (like a link) during the time it’s being activated (e.g., clicked).
:checkedinput:checkedSelects checkbox or radio button elements that are checked.
:disabledinput:disabledSelects form elements that are disabled.
:enabledinput:enabledSelects form elements that are enabled.
:emptyp:emptySelects elements that have no children (including text nodes).
:first-childli:first-childSelects an element that is the first child of its parent.
:last-childli:last-childSelects an element that is the last child of its parent.
:first-of-typep:first-of-typeSelects the first element of its type among siblings.
:last-of-typep:last-of-typeSelects the last element of its type among siblings.
:focusinput:focusSelects an element that currently has input focus.
:focus-visiblebutton:focus-visibleSelects an element that has focus and the browser determines focus should be visible (e.g., keyboard focus).
:focus-withindiv:focus-withinSelects an element if it or any of its descendants has focus.
:hovera:hoverSelects an element when the user hovers over it with a pointing device.
:invalidinput:invalidSelects form elements whose content fails validation.
:validinput:validSelects form elements whose content passes validation.
:linka:linkSelects unvisited links.
:visiteda:visitedSelects visited links (styling options are limited for privacy).
:not(selector)li:not(.special)Selects elements that do not match the provided selector.
:nth-child(n)li:nth-child(2)Selects an element based on its position among siblings (e.g., the 2nd child).
:nth-of-type(n)p:nth-of-type(odd)Selects an element based on its position among siblings of the same type (e.g., odd paragraphs).
:requiredinput:requiredSelects form elements that have the ‘required’ attribute.
:optionalinput:optionalSelects form elements that do not have the ‘required’ attribute.
:root:rootSelects the root element of the document (usually <html>). Often used for CSS Variables.
Explore pseudo-elements and pseudo-classes further on MDN.