Question
How to Work with CSS Pseudo-Elements (::before and ::after) in JavaScript
Question
Is there a way to select or manipulate CSS pseudo-elements such as ::before and ::after using jQuery or plain JavaScript?
For example, suppose a stylesheet contains this rule:
.span::after {
content: 'foo';
}
How can the displayed content value be changed from 'foo' to 'bar' using vanilla JavaScript or jQuery?
Short Answer
By the end of this page, you will understand why ::before and ::after cannot be selected like normal DOM elements, how to read their computed styles, and the common ways developers effectively change their appearance or content using JavaScript and CSS.
Concept
CSS pseudo-elements like ::before and ::after are not real DOM nodes. They are generated by the browser when CSS is applied to an element.
That is the key reason you cannot do something like this:
$('.span::after')
or this:
document.querySelector('.span::after')
Those selectors work on actual elements in the document tree. A pseudo-element is more like a visual layer created from CSS, not an element you can grab and edit directly.
Why this matters
In real programming, this affects how you design dynamic UI behavior:
- You cannot directly attach events to
::beforeor::after - You cannot directly select them with jQuery or DOM APIs
- You usually change the parent element's class, inline style, or CSS variable instead
- You can read pseudo-element styles using
getComputedStyle()
If you need to change what a pseudo-element shows, the usual approach is:
- Change a class on the real element
- Update a CSS custom property (
--value)
Mental Model
Think of a pseudo-element like a shadow drawn by CSS next to a real element.
- The real element is the actual object you can hold
- The pseudo-element is a visual decoration painted by the browser
You can change the object so the shadow changes, but you cannot pick up the shadow itself.
So if ::after shows 'foo', you do not directly edit the ::after node, because there is no node. Instead, you change the CSS rule or change something on the parent element that the CSS rule depends on.
Syntax and Examples
Core idea
You cannot directly select ::before or ::after with jQuery or querySelector(), but you can:
- Read pseudo-element styles with
getComputedStyle() - Change classes on the parent element
- Use CSS variables to drive pseudo-element content
- Edit stylesheet rules in JavaScript
Reading pseudo-element content
const el = document.querySelector('.span');
const styles = getComputedStyle(el, '::after');
console.log(styles.content); // often returns '"foo"'
This reads the computed content of ::after.
Best beginner-friendly approach: toggle a class
<span class="span"></>
Step by Step Execution
Consider this example:
<span class="label"></span>
.label::after {
content: 'foo';
}
.label.updated::after {
content: 'bar';
}
const el = document.querySelector('.label');
el.classList.add('updated');
What happens step by step
-
The browser finds the
<span>with classlabel -
CSS applies this rule:
.label::after { content: 'foo'; }So the browser visually creates an pseudo-element showing
Real World Use Cases
Pseudo-elements are commonly used for decoration and lightweight UI labels. JavaScript often changes the parent element so the pseudo-element updates automatically.
Common use cases
- Notification badges
- Show a small label like
NeworSale
- Show a small label like
- Required form indicators
- Add a red
*after a label
- Add a red
- Status labels
- Display
Online,Offline, orDraft
- Display
- Icons before links or buttons
- Add arrows, bullets, or symbols using CSS
- Tooltips and visual markers
- Decorative arrows or helper text
Example: required field marker
label.required::after {
content: ' *';
color: red;
}
document.querySelector()..();
Real Codebase Usage
In real projects, developers usually avoid directly editing pseudo-element rules unless necessary. Instead, they use maintainable patterns.
Common patterns
1. Class-based state changes
This is the most common approach.
.message::after {
content: 'Pending';
}
.message.sent::after {
content: 'Sent';
}
messageEl.classList.add('sent');
Why teams like it:
- Easy to read
- Works well with CSS architecture
- Keeps style logic in CSS
- Easy to test
2. CSS custom properties for dynamic values
Useful when the displayed value changes often.
.tag::after {
content: var(--tag-text);
}
tagEl.style.setProperty('--tag-text', '"Featured"');
Common Mistakes
1. Trying to select a pseudo-element directly
Broken code:
document.querySelector('.span::after');
Why it is wrong:
::afteris not a real DOM element- DOM selectors return actual nodes only
Use instead:
const el = document.querySelector('.span');
Then change a class or CSS variable on el.
2. Forgetting that content needs quoted text
Broken code:
el.style.setProperty('--after-text', 'bar');
This may not work correctly for content.
Correct:
el.style.setProperty(, );
Comparisons
| Approach | Can directly select pseudo-element? | Good for dynamic updates | Easy to maintain | Notes |
|---|---|---|---|---|
jQuery selector like $('.x::after') | No | No | No | Does not work because pseudo-elements are not DOM nodes |
querySelector('.x::after') | No | No | No | Same limitation |
getComputedStyle(el, '::after') | Read only | Limited | Yes | Good for inspecting computed styles |
| Toggle classes on the parent | No | Yes | Yes | Best general-purpose solution |
Cheat Sheet
Quick rules
::beforeand::afterare not DOM elements- You cannot select them with jQuery or
querySelector() - You can read their computed styles with
getComputedStyle(el, '::after') - You usually change the parent element's class or set a CSS variable
- For important text, prefer a real HTML element
Read pseudo-element styles
const el = document.querySelector('.item');
const styles = getComputedStyle(el, '::after');
console.log(styles.content);
Change content by toggling a class
.item::after { content: 'foo'; }
.item.active::after { content: 'bar'; }
FAQ
Can JavaScript select ::before or ::after directly?
No. Pseudo-elements are not real DOM nodes, so they cannot be selected directly with DOM APIs or jQuery.
Can jQuery manipulate pseudo-elements?
Not directly. jQuery can manipulate the parent element, and that can indirectly change the pseudo-element through CSS.
How do I change content in ::after using JavaScript?
The usual methods are:
- add or remove a class
- set a CSS custom property
- edit a stylesheet rule
Can I read the current content value of a pseudo-element?
Yes, with getComputedStyle(element, '::after').content.
Why does setting el.style.content not work?
Because that affects the real element's inline style, not the pseudo-element. Pseudo-elements are controlled through CSS rules.
Should I use pseudo-elements for important text?
Usually no. If the text is meaningful content, use a real HTML element so it is easier to update, access, and test.
Is :after different from ::after?
They refer to the same concept in practice for this case. is the modern pseudo-element syntax, while is the older form.
Mini Project
Description
Build a small status label component that uses ::after to display a status message. The project demonstrates the correct way to change pseudo-element content from JavaScript without trying to select the pseudo-element itself.
Goal
Create a label whose ::after text changes between Pending, Processing, and Done when buttons are clicked.
Requirements
- Create one visible label element in HTML.
- Use a
::afterpseudo-element to show the current status text. - Add three buttons for
Pending,Processing, andDone. - Update the pseudo-element text using JavaScript.
- Do not try to directly select
::afterin JavaScript.
Keep learning
Related questions
Angular ngClass Conditional Class Binding Explained
Learn how to use Angular ngClass for conditional classes, fix common binding mistakes, and understand why this template error happens.
CSS :not() Selector for Elements Without a Class or Attribute
Learn how to use the CSS :not() selector to target elements that do not have a specific class or attribute, with examples and common pitfalls.
CSS Font Scaling Relative to Container Size: %, em, rem, vw, and Responsive Text
Learn how CSS font scaling really works and how to make text responsive using %, em, rem, vw, clamp(), and media queries.