Coder Perfect

Using javascript to select and manipulate CSS pseudo-elements such as::before and::after (or jQuery)

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