Problem
Is there any way to select/manipulate CSS pseudo-elements such as ::before and ::after (and the old version with one semi-colon) using jQuery?
My CSS, for example, has the following rule:
.span::after{ content:'foo' }
Using vanilla JS or jQuery, how can I replace ‘foo’ to ‘bar’?
Asked by JBradwell
Solution #1
You could also use a data attribute to provide the content to the pseudo element and then edit it with jQuery:
In HTML:
<span>foo</span>
In jQuery:
$('span').hover(function(){
$(this).attr('data-content','bar');
});
In CSS:
span:after {
content: attr(data-content) ' any other text you may want';
}
You may use this in conjunction with seucolega’s approach to avoid the ‘other text’ from appearing:
In HTML:
<span>foo</span>
In jQuery:
$('span').hover(function(){
$(this).addClass('change').attr('data-content','bar');
});
In CSS:
span.change:after {
content: attr(data-content) ' any other text you may want';
}
Answered by Nick Kline
Solution #2
With all that jQuery can do, you’d think this would be a straightforward question to answer. Unfortunately, the issue is a technical one: css:after and:before rules aren’t part of the DOM, hence they can’t be changed with jQuery’s DOM methods.
There are JavaScript and/or CSS workarounds for manipulating these components; which one you use depends on your specific needs.
I’ll start with what is commonly regarded as the “best” approach:
You’ve already generated a class in your CSS with a different:after or:before style in this method. To ensure that this “new” class overrides, place it later in your stylesheet:
p:before {
content: "foo";
}
p.special:before {
content: "bar";
}
Then, using jQuery (or plain JavaScript), you can quickly add or remove this class:
$('p').on('click', function() {
$(this).toggleClass('special');
});
JavaScript can be used to directly add styles to the document stylesheet, such as the:after and:before styles. Although jQuery doesn’t provide a simple shortcut, the JS isn’t overly complex:
var str = "bar";
document.styleSheets[0].addRule('p.special:before','content: "'+str+'";');
.addRule() and the related . insertRule() methods are fairly well-supported today.
You may use jQuery to add an entirely new stylesheet to the document as a variant, but the required code isn’t much cleaner:
var str = "bar";
$('<style>p.special:before{content:"'+str+'"}</style>').appendTo('head');
We can also read the existing:after or:before styles using a different technique if we’re talking about “manipulating” the values rather than just adding to them:
var str = window.getComputedStyle(document.querySelector('p'), ':before')
.getPropertyValue('content');
When using jQuery, we may replace document.querySelector(‘p’) with $(‘p’)[0] for somewhat shorter code.
To read a specific DOM attribute, you can use attr() in your CSS. (If a browser supports:before, it will also support attr().) When you combine this with content, you get: We may dynamically modify the content (but not other characteristics like margin or color) of:before and:after using some well-prepared CSS:
p:before {
content: attr(data-before);
color: red;
cursor: pointer;
}
JS:
$('p').on('click', function () {
$(this).attr('data-before','bar');
});
If the CSS can’t be prepared ahead of time, this strategy can be paired with the second:
var str = "bar";
document.styleSheets[0].addRule('p:before', 'content: attr(data-before);');
$('p').on('click', function () {
$(this).attr('data-before', str);
});
Answered by Blazemonger
Solution #3
Pseudo-elements are not part of the DOM, despite the fact that they are rendered by browsers using CSS as if they were other genuine DOM components. Because pseudo-elements are not real elements, you can’t pick and modify them directly using jQuery (or any JavaScript APIs for that matter, not even the Selectors API). Not just::before and::after, but all pseudo-elements whose styles you’re trying to change using a script are affected.
The CSSOM (think window.getComputedStyle()) is the sole way to get pseudo-element styles directly at runtime, and it’s not provided by jQuery beyond. Neither does css(), which does not support pseudo-elements.
However, you can always find a method around it, such as:
Answered by BoltClock
Solution #4
Because pseudo items are not part of the DOM, you can’t select them with jQuery. However, you can give the parent element a special class and use CSS to govern its pseudo elements.
EXAMPLE
In jQuery:
<script type="text/javascript">
$('span').addClass('change');
</script>
In CSS:
span.change:after { content: 'bar' }
Answered by Gustavo Sousa
Solution #5
To manipulate pseudo-elements, we can use custom properties (also known as CSS variables). The following is taken from the specification:
In light of this, the concept is to define the custom attribute within the element, and the pseudo-element will simply inherit it, allowing us to edit it easily.
1) Make use of inline style:
2) Making use of CSS and classes
3) Using javascript
4) Using jQuery
It can also be applied to complex numbers:
As you can see, I’m using the syntax var(—c,value), where value is the default value, also known as the fallback value.
We may read the following from the same specification:
And later:
The fallback value will be used if the custom property is not set, is set to initial, or contains an invalid value. When we wish to reset a custom property to its default value, initial can be useful.
Related
How do I save an inherit value in a CSS variable (also known as a custom property)?
CSS box model custom properties (variables)
Answered by Temani Afif
Post is based on https://stackoverflow.com/questions/5041494/selecting-and-manipulating-css-pseudo-elements-such-as-before-and-after-usin