[javascript] Selecting and manipulating CSS pseudo-elements such as ::before and ::after using javascript (or jQuery)

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?

For example, my stylesheet has the following rule:

.span::after{ content:'foo' }

How can I change 'foo' to 'bar' using vanilla JS or jQuery?

This question is related to javascript jquery css jquery-selectors pseudo-element

The answer is


You may create a fake property or use an existing one and inherit it in the pseudo-element's stylesheet.

_x000D_
_x000D_
var switched = false;_x000D_
_x000D_
// Enable color switching_x000D_
setInterval(function () {_x000D_
    var color = switched ? 'red' : 'darkred';_x000D_
    var element = document.getElementById('arrow');_x000D_
    element.style.backgroundColor = color;_x000D_
    _x000D_
    // Managing pseudo-element's css_x000D_
    // using inheritance._x000D_
    element.style.borderLeftColor = color;_x000D_
    _x000D_
    switched = !switched;_x000D_
}, 1000);
_x000D_
.arrow {_x000D_
    /* SET FICTIONAL PROPERTY */_x000D_
    border-left-color:red;_x000D_
    _x000D_
    background-color:red;_x000D_
    width:1em;_x000D_
    height:1em;_x000D_
    display:inline-block;_x000D_
    position:relative;_x000D_
}_x000D_
.arrow:after {_x000D_
    border-top:1em solid transparent;_x000D_
    border-right:1em solid transparent;_x000D_
    border-bottom:1em solid transparent;_x000D_
    border-left:1em solid transparent;_x000D_
    _x000D_
    /* INHERIT PROPERTY */_x000D_
    border-left-color:inherit;_x000D_
    _x000D_
    content:"";_x000D_
    width:0;_x000D_
    height:0;_x000D_
    position:absolute;_x000D_
    left:100%;_x000D_
    top:-50%;_x000D_
}
_x000D_
<span id="arrow" class="arrow"></span>
_x000D_
_x000D_
_x000D_

It seems it doesn't work for "content" property :(


We can also rely on custom properties (aka CSS variables) in order to manipulate pseudo-element. We can read in the specification that:

Custom properties are ordinary properties, so they can be declared on any element, are resolved with the normal inheritance and cascade rules, can be made conditional with @media and other conditional rules, can be used in HTML’s style attribute, can be read or set using the CSSOM, etc.

Considering this, the idea is to define the custom property within the element and the pseudo-element will simply inherit it; thus we can easily modify it.

1) Using inline style:

_x000D_
_x000D_
.box:before {
  content:var(--content,"I am a before element");
  color:var(--color, red);
  font-size:25px;
}
_x000D_
<div class="box"></div>
<div class="box" style="--color:blue;--content:'I am a blue element'"></div>
<div class="box" style="--color:black"></div>
<div class="box" style="--color:#f0f;--content:'another element'"></div>
_x000D_
_x000D_
_x000D_

2) Using CSS and classes

_x000D_
_x000D_
.box:before {
  content:var(--content,"I am a before element");
  color:var(--color, red);
  font-size:25px;
}

.blue {
  --color:blue;
  --content:'I am a blue element';
}
.black {
  --color:black;
}
_x000D_
<div class="box"></div>
<div class="box black" ></div>
<div class="box blue"></div>
_x000D_
_x000D_
_x000D_

3) Using javascript

_x000D_
_x000D_
document.querySelectorAll('.box')[0].style.setProperty("--color", "blue");
document.querySelectorAll('.box')[1].style.setProperty("--content", "'I am another element'");
_x000D_
.box:before {
  content:var(--content,"I am a before element");
  color:var(--color, red);
  font-size:25px;
}
_x000D_
<div class="box"></div>
<div class="box"></div>
_x000D_
_x000D_
_x000D_

4) Using jQuery

_x000D_
_x000D_
$('.box').eq(0).css("--color", "blue");
/* the css() function with custom properties works only with a jQuery vesion >= 3.x
   with older version we can use style attribute to set the value. Simply pay
   attention if you already have inline style defined! 
*/
$('.box').eq(1).attr("style","--color:#f0f");
_x000D_
.box:before {
  content:"I am a before element";
  color:var(--color, red);
  font-size:25px;
}
_x000D_
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
_x000D_
_x000D_
_x000D_


It can also be used with complex values:

_x000D_
_x000D_
.box {
  --c:"content";
  --b:linear-gradient(red,blue);
  --s:20px;
  --p:0 15px;
}

.box:before {
  content: var(--c);
  background:var(--b);
  color:#fff;
  font-size: calc(2 * var(--s) + 5px);
  padding:var(--p);
}
_x000D_
<div class="box"></div>
_x000D_
_x000D_
_x000D_

You may notice that I am considering the syntax var(--c,value) where value is the default value and also called the fallback value.

From the same specification we can read:

The value of a custom property can be substituted into the value of another property with the var() function. The syntax of var() is:

var() = var( <custom-property-name> [, <declaration-value> ]? )

The first argument to the function is the name of the custom property to be substituted. The second argument to the function, if provided, is a fallback value, which is used as the substitution value when the referenced custom property is invalid.

And later:

To substitute a var() in a property’s value:

  1. If the custom property named by the first argument to the var() function is animation-tainted, and the var() function is being used in the animation property or one of its longhands, treat the custom property as having its initial value for the rest of this algorithm.
  2. If the value of the custom property named by the first argument to the var() function is anything but the initial value, replace the var() function by the value of the corresponding custom property.
  3. Otherwise, if the var() function has a fallback value as its second argument, replace the var() function by the fallback value. If there are any var() references in the fallback, substitute them as well.
  4. Otherwise, the property containing the var() function is invalid at computed-value time.

If we don't set the custom property OR we set it to initial OR it contains an invalid value then the fallback value will be used. The use of initial can be helpful in case we want to reset a custom property to its default value.

Related

How to store inherit value inside a CSS variable (aka custom property)?

CSS custom properties (variables) for box model


I'm always adding my own utils function, which looks like this.

function setPseudoElContent(selector, value) {    
    document.styleSheets[0].addRule(selector, 'content: "' + value + '";');
}

setPseudoElContent('.class::after', 'Hello World!');

or make use of ES6 Features:

const setPseudoElContent = (selector, value) => {    
    document.styleSheets[0].addRule(selector, `content: "${value}";`);
}

setPseudoElContent('.class::after', 'Hello World!');

You'd think this would be a simple question to answer, with everything else that jQuery can do. Unfortunately, the problem comes down to a technical issue: css :after and :before rules aren't part of the DOM, and therefore can't be altered using jQuery's DOM methods.

There are ways to manipulate these elements using JavaScript and/or CSS workarounds; which one you use depends on your exact requirements.


I'm going to start with what's widely considered the "best" approach:

1) Add/remove a predetermined class

In this approach, you've already created a class in your CSS with a different :after or :before style. Place this "new" class later in your stylesheet to make sure it overrides:

p:before {
    content: "foo";
}
p.special:before {
    content: "bar";
}

Then you can easily add or remove this class using jQuery (or vanilla JavaScript):

$('p').on('click', function() {
    $(this).toggleClass('special');
});

_x000D_
_x000D_
    $('p').on('click', function() {_x000D_
      $(this).toggleClass('special');_x000D_
    });
_x000D_
p:before {_x000D_
  content: "foo";_x000D_
  color: red;_x000D_
  cursor: pointer;_x000D_
}_x000D_
p.special:before {_x000D_
  content: "bar";_x000D_
}
_x000D_
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>_x000D_
_x000D_
<p>This is a paragraph.</p>_x000D_
<p>This is another paragraph.</p>
_x000D_
_x000D_
_x000D_

  • Pros: Easy to implement with jQuery; quickly alters multiple styles at once; enforces separation of concerns (isolating your CSS and JS from your HTML)
  • Cons: CSS must be pre-written, so the content of :before or :after isn't completely dynamic

2) Add new styles directly to the document's stylesheet

It's possible to use JavaScript to add styles directly to the document stylesheet, including :after and :before styles. jQuery doesn't provide a convenient shortcut, but fortunately the JS isn't that complicated:

var str = "bar";
document.styleSheets[0].addRule('p.special:before','content: "'+str+'";');

_x000D_
_x000D_
var str = "bar";_x000D_
document.styleSheets[0].addRule('p.special:before', 'content: "' + str + '";');
_x000D_
p:before {_x000D_
  content: "foo";_x000D_
  color: red;_x000D_
}
_x000D_
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>_x000D_
_x000D_
<p class="special">This is a paragraph</p>_x000D_
<p>This is another paragraph</p>
_x000D_
_x000D_
_x000D_

.addRule() and the related .insertRule() methods are fairly well-supported today.

As a variation, you can also use jQuery to add an entirely new stylesheet to the document, but the necessary code isn't any cleaner:

var str = "bar";
$('<style>p.special:before{content:"'+str+'"}</style>').appendTo('head');

_x000D_
_x000D_
var str = "bar";_x000D_
$('<style>p.special:before{content:"' + str + '"}</style>').appendTo('head');
_x000D_
p:before {_x000D_
  content: "foo";_x000D_
  color: red;_x000D_
}
_x000D_
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>_x000D_
_x000D_
<p class="special">This is a paragraph</p>_x000D_
<p>This is another paragraph</p>
_x000D_
_x000D_
_x000D_

If we're talking about "manipulating" the values, not just adding to them, we can also read the existing :after or :before styles using a different approach:

var str = window.getComputedStyle(document.querySelector('p'), ':before') 
           .getPropertyValue('content');

_x000D_
_x000D_
var str = window.getComputedStyle($('p')[0], ':before').getPropertyValue('content');_x000D_
console.log(str);_x000D_
_x000D_
document.styleSheets[0].addRule('p.special:before', 'content: "' + str+str + '";');
_x000D_
p:before {_x000D_
    content:"foo";_x000D_
    color: red;_x000D_
}
_x000D_
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>_x000D_
_x000D_
<p class="special">This is a paragraph</p>_x000D_
<p>This is another paragraph</p>
_x000D_
_x000D_
_x000D_

We can replace document.querySelector('p') with $('p')[0] when using jQuery, for slightly shorter code.

  • Pros: any string can be dynamically inserted into the style
  • Cons: original styles aren't altered, just overridden; repeated (ab)use can make the DOM grow arbitrarily large

3) Alter a different DOM attribute

You can also to use attr() in your CSS to read a particular DOM attribute. (If a browser supports :before, it supports attr() as well.) By combining this with content: in some carefully-prepared CSS, we can change the content (but not other properties, like margin or color) of :before and :after dynamically:

p:before {
    content: attr(data-before);
    color: red;
    cursor: pointer;
}

JS:

$('p').on('click', function () {
    $(this).attr('data-before','bar');
});

_x000D_
_x000D_
$('p').on('click', function () {_x000D_
    $(this).attr('data-before','bar');_x000D_
});
_x000D_
p:before {_x000D_
    content: attr(data-before);_x000D_
    color: red;_x000D_
    cursor: pointer;_x000D_
}
_x000D_
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>_x000D_
_x000D_
<p>This is a paragraph.</p>_x000D_
<p>This is another paragraph.</p>
_x000D_
_x000D_
_x000D_

This can be combined with the second technique if the CSS can't be prepared ahead of time:

var str = "bar";

document.styleSheets[0].addRule('p:before', 'content: attr(data-before);');

$('p').on('click', function () {
    $(this).attr('data-before', str);
});

_x000D_
_x000D_
var str = "bar";_x000D_
document.styleSheets[0].addRule('p:before', 'content: attr(data-before) !important;');_x000D_
_x000D_
$('p').on('click', function() {_x000D_
  $(this).attr('data-before', str);_x000D_
});
_x000D_
p:before {_x000D_
  content: "foo";_x000D_
  color: red;_x000D_
  cursor: pointer;_x000D_
}
_x000D_
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>_x000D_
_x000D_
<p>This is a paragraph.</p>_x000D_
<p>This is another paragraph.</p>
_x000D_
_x000D_
_x000D_

  • Pros: Doesn't create endless extra styles
  • Cons: attr in CSS can only apply to content strings, not URLs or RGB colors

Thank you all! i managed to do what i wanted :D http://jsfiddle.net/Tfc9j/42/ here take a look

i wanted to have the opacity of an outer div to be different from the opacity of the internal div and that change with a click somwewhere ;) Thanks!

   $('#ena').on('click', function () {
        $('head').append("<style>#ena:before { opacity:0.3; }</style>");
    });

$('#duop').on('click', function (e) {

        $('head').append("<style>#ena:before { opacity:0.8; }</style>");

     e.stopPropagation(); 
    });

#ena{
    width:300px;
    height:300px;
    border:1px black solid;
    position:relative;
}
#duo{
    opacity:1;
    position:absolute;
    top:50px;
  width:300px;
    height:100px;
      background-color:white;
}
#ena:before {
    content: attr(data-before);
    color: white;
    cursor: pointer;
    position: absolute;
    background-color:red;
    opacity:0.9;
    width:100%;
    height:100%;
}


<div id="ena">
    <div id="duo">
        <p>ena p</p>
        <p id="duop">duoyyyyyyyyyyyyyy p</p>

    </div>   


</div>

one working but not very efficient way is to add a rule to the document with the new content and reference it with a class. depending on what is needed the class might need an unique id for each value in content.

$("<style type='text/css'>span.id-after:after{content:bar;}</style>").appendTo($("head"));
$('span').addClass('id-after');

I have created a jQuery plugin to add css-pseudo rules like using .css() for specific elements.

  • plugin code and test case is here
  • use case as simple css image popup here

usage:

$('body')
  .css({
    backgroundColor: 'white'
  })
  .cssPseudo('after', {
    content: 'attr(title) ", you should try to hover the picture, then click it."',
    position: 'absolute',
    top: 20, left: 20  
  })
  .cssPseudo('hover:after', {
    content: '"Now hover the picture, then click it!"'
  });


I have something different stuff for you which is easy and effective.

    <style> 
    .case-after:after { // set your properties here like eg: 
        color:#3fd309 !important; 
     } 
     .case-before:before { // set your properties here like eg: 
        color:#151715 !important; 
     }
 </style>
  // case for after
    $('#button-id').on('click', function() {
        $(".target-div").toggleClass('case-after');
    });

     // case for before
    $('#button-id').on('click', function() {
        $(".target-div").toggleClass('case-before');
    });

Someone else commented on appending to the head element with a full style element and that's not bad if you're only doing it once but if you need to reset it more than once you'll end up with a ton of style elements. So to prevent that I created a blank style element in the head with an id and replace the innerHTML of it like this:

<style id="pseudo"></style>

Then the JavaScript would look like this:

var pseudo = document.getElementById("pseudo");

function setHeight() {
    let height = document.getElementById("container").clientHeight;
    pseudo.innerHTML = `.class:before { height: ${height}px; }`
}

setHeight()

Now in my case I needed this to set the height of a before element based on the height of another and it will change on resize so using this I can run setHeight() every time the window is resized and it will replace the <style> properly.

Hope that helps someone who was stuck trying to do the same thing.


Although they are rendered by browsers through CSS as if they were like other real DOM elements, pseudo-elements themselves are not part of the DOM, because pseudo-elements, as the name implies, are not real elements, and therefore you can't select and manipulate them directly with jQuery (or any JavaScript APIs for that matter, not even the Selectors API). This applies to any pseudo-elements whose styles you're trying to modify with a script, and not just ::before and ::after.

You can only access pseudo-element styles directly at runtime via the CSSOM (think window.getComputedStyle()), which is not exposed by jQuery beyond .css(), a method that doesn't support pseudo-elements either.

You can always find other ways around it, though, for example:

  • Applying the styles to the pseudo-elements of one or more arbitrary classes, then toggling between classes (see seucolega's answer for a quick example) — this is the idiomatic way as it makes use of simple selectors (which pseudo-elements are not) to distinguish between elements and element states, the way they're intended to be used

  • Manipulating the styles being applied to said pseudo-elements, by altering the document stylesheet, which is much more of a hack


Here is the HTML:

<div class="icon">
  <span class="play">
    ::before
  </span>
</div>

Computed style on 'before' was content: "VERIFY TO WATCH";

Here is my two lines of jQuery, which use the idea of adding an extra class to specifically reference this element and then appending a style tag (with an !important tag) to changes the CSS of the sudo-element's content value:

$("span.play:eq(0)").addClass('G');

$('body').append("<style>.G:before{content:'NewText' !important}</style>");


In the line of what Christian suggests, you could also do:

$('head').append("<style>.span::after{ content:'bar' }</style>");

There are many answers here but no answer helps to manipulate the css of :before or :after , not even the accepted one.

Here is how I propose to do it. Lets suppose your HTML is like this:

<div id="something">Test</div>

And then you are setting its :before in CSS and designing it like:

#something:before{
   content:"1st";
   font-size:20px;
   color:red;
}
#something{
  content:'1st';
}

Please notice I also set content attribute in element itself so that you can take it out easily later. Now there is a button clicking on which, you want to change the color of :before to green and its font-size to 30px. You can achieve that as follows:

Define a css with your required style on some class .activeS :

.activeS:before{
   color:green !important;
   font-size:30px !important;
 }

Now you can change :before style by adding the class to your :before element as follows:

<button id="changeBefore">Change</button>
<script>
    $('#changeBefore').click(function(){
        $('#something').addClass('activeS');
    });
</script>

If you just want to get content of :before, it can be done as:

<button id="getContent">Get Content</button>
<script>
    $('#getContent').click(function(){
        console.log($('#something').css('content'));//will print '1st'
    });
</script>

Ultimately if you want to dynamically change :before content by jQuery, You can achieve that as follows:

<button id="changeBefore">Change</button>
<script>
    var newValue = '22';//coming from somewhere
    var add = '<style>#something:before{content:"'+newValue+'"!important;}</style>';
    $('#changeBefore').click(function(){
        $('body').append(add);
    });
</script>

Clicking on above "changeBefore" button will change :before content of #something into '22' which is a dynamic value.

I hope it helps


Why adding classes or attributes when you can just append a style to head

$('head').append('<style>.span:after{ content:'changed content' }</style>')

Here is the way to access :after and :before style properties, defined in css:

// Get the color value of .element:before
var color = window.getComputedStyle(
    document.querySelector('.element'), ':before'
).getPropertyValue('color');

// Get the content value of .element:before
var content = window.getComputedStyle(
    document.querySelector('.element'), ':before'
).getPropertyValue('content');

I made use of variables defined in :root inside CSS to modify the :after (the same applies to :before) pseudo-element, in particular to change the background-color value for a styled anchor defined by .sliding-middle-out:hover:after and the content value for another anchor (#reference) in the following demo that generates random colors by using JavaScript/jQuery:

HTML

<a href="#" id="changeColor" class="sliding-middle-out" title="Generate a random color">Change link color</a>
<span id="log"></span>
<h6>
  <a href="https://stackoverflow.com/a/52360188/2149425" id="reference" class="sliding-middle-out" target="_blank" title="Stack Overflow topic">Reference</a>
</h6>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript" src="https://cdn.rawgit.com/davidmerfield/randomColor/master/randomColor.js"></script>

CSS

:root {
    --anchorsFg: #0DAFA4;
}
a, a:visited, a:focus, a:active {
    text-decoration: none;
    color: var(--anchorsFg);
    outline: 0;
    font-style: italic;

    -webkit-transition: color 250ms ease-in-out;
    -moz-transition: color 250ms ease-in-out;
    -ms-transition: color 250ms ease-in-out;
    -o-transition: color 250ms ease-in-out;
    transition: color 250ms ease-in-out;
}
.sliding-middle-out {
    display: inline-block;
    position: relative;
    padding-bottom: 1px;
}
.sliding-middle-out:after {
    content: '';
    display: block;
    margin: auto;
    height: 1px;
    width: 0px;
    background-color: transparent;

    -webkit-transition: width 250ms ease-in-out, background-color 250ms ease-in-out;
    -moz-transition: width 250ms ease-in-out, background-color 250ms ease-in-out;
    -ms-transition: width 250ms ease-in-out, background-color 250ms ease-in-out;
    -o-transition: width 250ms ease-in-out, background-color 250ms ease-in-out;
    transition: width 250ms ease-in-out, background-color 250ms ease-in-out;
}
.sliding-middle-out:hover:after {
    width: 100%;
    background-color: var(--anchorsFg);
    outline: 0;
}
#reference {
  margin-top: 20px;
}
.sliding-middle-out:before {
  content: attr(data-content);
  display: attr(data-display);
}

JS/jQuery

var anchorsFg = randomColor();
$( ".sliding-middle-out" ).hover(function(){
    $( ":root" ).css({"--anchorsFg" : anchorsFg});
});

$( "#reference" ).hover(
 function(){
    $(this).attr("data-content", "Hello World!").attr("data-display", "block").html("");
 },
 function(){
    $(this).attr("data-content", "Reference").attr("data-display", "inline").html("");
 }
);

You can't select pseudo elements in jQuery because they are not part of DOM. But you can add an specific class to the father element and control its pseudo elements in CSS.

EXAMPLE

In jQuery:

<script type="text/javascript">
    $('span').addClass('change');
</script>

In CSS:

span.change:after { content: 'bar' }

_x000D_
_x000D_
 $('.span').attr('data-txt', 'foo');_x000D_
        $('.span').click(function () {_x000D_
         $(this).attr('data-txt',"any other text");_x000D_
        })
_x000D_
.span{_x000D_
}_x000D_
.span:after{ _x000D_
  content: attr(data-txt);_x000D_
 }
_x000D_
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>_x000D_
<div class='span'></div>
_x000D_
_x000D_
_x000D_


This is not practical as i did not write this for real world uses, just to give you a example of what can be achieved.

css = {
before: function(elem,attr){ 

if($("#cust_style") !== undefined){ 
$("body").append("<style> " + elem + ":before {"  + attr +  "} </style>"); 
} else {
 $("#cust_style").remove();
$("body").append("<style> " + elem + ":before {"  + attr +  "} </style>"); 
}

}, after: function(elem,attr){
if($("#cust_style") !== undefined){ 
$("body").append("<style> " + elem + ":after {"  + attr +  "} </style>"); 

} else { $("#cust_style").remove();
$("body").append("<style> " + elem + ":after {"  + attr +  "} </style>"); 
}
}
}

this currently add's a / or appends a Style element which contains your necessary attribute's which will take affect on the target element's after Pseudo element.

this can be used as

css.after("someElement"," content: 'Test'; position: 'absolute'; ") // editing / adding styles to :after

and

css.before( ... ); // to affect the before pseudo element.

as after: and before: pseudo elements are not directly accessible through DOM it is currently not possible to edit the Specific values of the css freely.

my way was just a example and its not good for practice, you can modify it try some of your own tricks and make it correct for real world usage.

so do your own experimentation's with this and others!

regards - Adarsh Hegde.


You can use my plugin for this purpose.

JQuery:

_x000D_
_x000D_
(function() {_x000D_
  $.pseudoElements = {_x000D_
    length: 0_x000D_
  };_x000D_
_x000D_
  var setPseudoElement = function(parameters) {_x000D_
    if (typeof parameters.argument === 'object' || (parameters.argument !== undefined && parameters.property !== undefined)) {_x000D_
      for (var element of parameters.elements.get()) {_x000D_
        if (!element.pseudoElements) element.pseudoElements = {_x000D_
          styleSheet: null,_x000D_
          before: {_x000D_
            index: null,_x000D_
            properties: null_x000D_
          },_x000D_
          after: {_x000D_
            index: null,_x000D_
            properties: null_x000D_
          },_x000D_
          id: null_x000D_
        };_x000D_
_x000D_
        var selector = (function() {_x000D_
          if (element.pseudoElements.id !== null) {_x000D_
            if (Number(element.getAttribute('data-pe--id')) !== element.pseudoElements.id) element.setAttribute('data-pe--id', element.pseudoElements.id);_x000D_
            return '[data-pe--id="' + element.pseudoElements.id + '"]::' + parameters.pseudoElement;_x000D_
          } else {_x000D_
            var id = $.pseudoElements.length;_x000D_
            $.pseudoElements.length++_x000D_
_x000D_
              element.pseudoElements.id = id;_x000D_
            element.setAttribute('data-pe--id', id);_x000D_
_x000D_
            return '[data-pe--id="' + id + '"]::' + parameters.pseudoElement;_x000D_
          };_x000D_
        })();_x000D_
_x000D_
        if (!element.pseudoElements.styleSheet) {_x000D_
          if (document.styleSheets[0]) {_x000D_
            element.pseudoElements.styleSheet = document.styleSheets[0];_x000D_
          } else {_x000D_
            var styleSheet = document.createElement('style');_x000D_
_x000D_
            document.head.appendChild(styleSheet);_x000D_
            element.pseudoElements.styleSheet = styleSheet.sheet;_x000D_
          };_x000D_
        };_x000D_
_x000D_
        if (element.pseudoElements[parameters.pseudoElement].properties && element.pseudoElements[parameters.pseudoElement].index) {_x000D_
          element.pseudoElements.styleSheet.deleteRule(element.pseudoElements[parameters.pseudoElement].index);_x000D_
        };_x000D_
_x000D_
        if (typeof parameters.argument === 'object') {_x000D_
          parameters.argument = $.extend({}, parameters.argument);_x000D_
_x000D_
          if (!element.pseudoElements[parameters.pseudoElement].properties && !element.pseudoElements[parameters.pseudoElement].index) {_x000D_
            var newIndex = element.pseudoElements.styleSheet.rules.length || element.pseudoElements.styleSheet.cssRules.length || element.pseudoElements.styleSheet.length;_x000D_
_x000D_
            element.pseudoElements[parameters.pseudoElement].index = newIndex;_x000D_
            element.pseudoElements[parameters.pseudoElement].properties = parameters.argument;_x000D_
          };_x000D_
_x000D_
          var properties = '';_x000D_
_x000D_
          for (var property in parameters.argument) {_x000D_
            if (typeof parameters.argument[property] === 'function')_x000D_
              element.pseudoElements[parameters.pseudoElement].properties[property] = parameters.argument[property]();_x000D_
            else_x000D_
              element.pseudoElements[parameters.pseudoElement].properties[property] = parameters.argument[property];_x000D_
          };_x000D_
_x000D_
          for (var property in element.pseudoElements[parameters.pseudoElement].properties) {_x000D_
            properties += property + ': ' + element.pseudoElements[parameters.pseudoElement].properties[property] + ' !important; ';_x000D_
          };_x000D_
_x000D_
          element.pseudoElements.styleSheet.addRule(selector, properties, element.pseudoElements[parameters.pseudoElement].index);_x000D_
        } else if (parameters.argument !== undefined && parameters.property !== undefined) {_x000D_
          if (!element.pseudoElements[parameters.pseudoElement].properties && !element.pseudoElements[parameters.pseudoElement].index) {_x000D_
            var newIndex = element.pseudoElements.styleSheet.rules.length || element.pseudoElements.styleSheet.cssRules.length || element.pseudoElements.styleSheet.length;_x000D_
_x000D_
            element.pseudoElements[parameters.pseudoElement].index = newIndex;_x000D_
            element.pseudoElements[parameters.pseudoElement].properties = {};_x000D_
          };_x000D_
_x000D_
          if (typeof parameters.property === 'function')_x000D_
            element.pseudoElements[parameters.pseudoElement].properties[parameters.argument] = parameters.property();_x000D_
          else_x000D_
            element.pseudoElements[parameters.pseudoElement].properties[parameters.argument] = parameters.property;_x000D_
_x000D_
          var properties = '';_x000D_
_x000D_
          for (var property in element.pseudoElements[parameters.pseudoElement].properties) {_x000D_
            properties += property + ': ' + element.pseudoElements[parameters.pseudoElement].properties[property] + ' !important; ';_x000D_
          };_x000D_
_x000D_
          element.pseudoElements.styleSheet.addRule(selector, properties, element.pseudoElements[parameters.pseudoElement].index);_x000D_
        };_x000D_
      };_x000D_
_x000D_
      return $(parameters.elements);_x000D_
    } else if (parameters.argument !== undefined && parameters.property === undefined) {_x000D_
      var element = $(parameters.elements).get(0);_x000D_
_x000D_
      var windowStyle = window.getComputedStyle(_x000D_
        element, '::' + parameters.pseudoElement_x000D_
      ).getPropertyValue(parameters.argument);_x000D_
_x000D_
      if (element.pseudoElements) {_x000D_
        return $(parameters.elements).get(0).pseudoElements[parameters.pseudoElement].properties[parameters.argument] || windowStyle;_x000D_
      } else {_x000D_
        return windowStyle || null;_x000D_
      };_x000D_
    } else {_x000D_
      console.error('Invalid values!');_x000D_
      return false;_x000D_
    };_x000D_
  };_x000D_
_x000D_
  $.fn.cssBefore = function(argument, property) {_x000D_
    return setPseudoElement({_x000D_
      elements: this,_x000D_
      pseudoElement: 'before',_x000D_
      argument: argument,_x000D_
      property: property_x000D_
    });_x000D_
  };_x000D_
  $.fn.cssAfter = function(argument, property) {_x000D_
    return setPseudoElement({_x000D_
      elements: this,_x000D_
      pseudoElement: 'after',_x000D_
      argument: argument,_x000D_
      property: property_x000D_
    });_x000D_
  };_x000D_
})();_x000D_
_x000D_
$(function() {_x000D_
  $('.element').cssBefore('content', '"New before!"');_x000D_
});
_x000D_
.element {_x000D_
  width: 480px;_x000D_
  margin: 0 auto;_x000D_
  border: 2px solid red;_x000D_
}_x000D_
_x000D_
.element::before {_x000D_
  content: 'Old before!';_x000D_
}
_x000D_
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>_x000D_
_x000D_
<div class="element"></div>
_x000D_
_x000D_
_x000D_

The values should be specified, as in the normal function of jQuery.css

In addition, you can also get the value of the pseudo-element parameter, as in the normal function of jQuery.css:

console.log( $(element).cssBefore(parameter) );

JS:

_x000D_
_x000D_
(function() {_x000D_
  document.pseudoElements = {_x000D_
    length: 0_x000D_
  };_x000D_
_x000D_
  var setPseudoElement = function(parameters) {_x000D_
    if (typeof parameters.argument === 'object' || (parameters.argument !== undefined && parameters.property !== undefined)) {_x000D_
      if (!parameters.element.pseudoElements) parameters.element.pseudoElements = {_x000D_
        styleSheet: null,_x000D_
        before: {_x000D_
          index: null,_x000D_
          properties: null_x000D_
        },_x000D_
        after: {_x000D_
          index: null,_x000D_
          properties: null_x000D_
        },_x000D_
        id: null_x000D_
      };_x000D_
_x000D_
      var selector = (function() {_x000D_
        if (parameters.element.pseudoElements.id !== null) {_x000D_
          if (Number(parameters.element.getAttribute('data-pe--id')) !== parameters.element.pseudoElements.id) parameters.element.setAttribute('data-pe--id', parameters.element.pseudoElements.id);_x000D_
          return '[data-pe--id="' + parameters.element.pseudoElements.id + '"]::' + parameters.pseudoElement;_x000D_
        } else {_x000D_
          var id = document.pseudoElements.length;_x000D_
          document.pseudoElements.length++_x000D_
_x000D_
            parameters.element.pseudoElements.id = id;_x000D_
          parameters.element.setAttribute('data-pe--id', id);_x000D_
_x000D_
          return '[data-pe--id="' + id + '"]::' + parameters.pseudoElement;_x000D_
        };_x000D_
      })();_x000D_
_x000D_
      if (!parameters.element.pseudoElements.styleSheet) {_x000D_
        if (document.styleSheets[0]) {_x000D_
          parameters.element.pseudoElements.styleSheet = document.styleSheets[0];_x000D_
        } else {_x000D_
          var styleSheet = document.createElement('style');_x000D_
_x000D_
          document.head.appendChild(styleSheet);_x000D_
          parameters.element.pseudoElements.styleSheet = styleSheet.sheet;_x000D_
        };_x000D_
      };_x000D_
_x000D_
      if (parameters.element.pseudoElements[parameters.pseudoElement].properties && parameters.element.pseudoElements[parameters.pseudoElement].index) {_x000D_
        parameters.element.pseudoElements.styleSheet.deleteRule(parameters.element.pseudoElements[parameters.pseudoElement].index);_x000D_
      };_x000D_
_x000D_
      if (typeof parameters.argument === 'object') {_x000D_
        parameters.argument = (function() {_x000D_
          var cloneObject = typeof parameters.argument.pop === 'function' ? [] : {};_x000D_
_x000D_
          for (var property in parameters.argument) {_x000D_
            cloneObject[property] = parameters.argument[property];_x000D_
          };_x000D_
_x000D_
          return cloneObject;_x000D_
        })();_x000D_
_x000D_
        if (!parameters.element.pseudoElements[parameters.pseudoElement].properties && !parameters.element.pseudoElements[parameters.pseudoElement].index) {_x000D_
          var newIndex = parameters.element.pseudoElements.styleSheet.rules.length || parameters.element.pseudoElements.styleSheet.cssRules.length || parameters.element.pseudoElements.styleSheet.length;_x000D_
_x000D_
          parameters.element.pseudoElements[parameters.pseudoElement].index = newIndex;_x000D_
          parameters.element.pseudoElements[parameters.pseudoElement].properties = parameters.argument;_x000D_
        };_x000D_
_x000D_
        var properties = '';_x000D_
_x000D_
        for (var property in parameters.argument) {_x000D_
          if (typeof parameters.argument[property] === 'function')_x000D_
            parameters.element.pseudoElements[parameters.pseudoElement].properties[property] = parameters.argument[property]();_x000D_
          else_x000D_
            parameters.element.pseudoElements[parameters.pseudoElement].properties[property] = parameters.argument[property];_x000D_
        };_x000D_
_x000D_
        for (var property in parameters.element.pseudoElements[parameters.pseudoElement].properties) {_x000D_
          properties += property + ': ' + parameters.element.pseudoElements[parameters.pseudoElement].properties[property] + ' !important; ';_x000D_
        };_x000D_
_x000D_
        parameters.element.pseudoElements.styleSheet.addRule(selector, properties, parameters.element.pseudoElements[parameters.pseudoElement].index);_x000D_
      } else if (parameters.argument !== undefined && parameters.property !== undefined) {_x000D_
        if (!parameters.element.pseudoElements[parameters.pseudoElement].properties && !parameters.element.pseudoElements[parameters.pseudoElement].index) {_x000D_
          var newIndex = parameters.element.pseudoElements.styleSheet.rules.length || parameters.element.pseudoElements.styleSheet.cssRules.length || parameters.element.pseudoElements.styleSheet.length;_x000D_
_x000D_
          parameters.element.pseudoElements[parameters.pseudoElement].index = newIndex;_x000D_
          parameters.element.pseudoElements[parameters.pseudoElement].properties = {};_x000D_
        };_x000D_
_x000D_
        if (typeof parameters.property === 'function')_x000D_
          parameters.element.pseudoElements[parameters.pseudoElement].properties[parameters.argument] = parameters.property();_x000D_
        else_x000D_
          parameters.element.pseudoElements[parameters.pseudoElement].properties[parameters.argument] = parameters.property;_x000D_
_x000D_
        var properties = '';_x000D_
_x000D_
        for (var property in parameters.element.pseudoElements[parameters.pseudoElement].properties) {_x000D_
          properties += property + ': ' + parameters.element.pseudoElements[parameters.pseudoElement].properties[property] + ' !important; ';_x000D_
        };_x000D_
_x000D_
        parameters.element.pseudoElements.styleSheet.addRule(selector, properties, parameters.element.pseudoElements[parameters.pseudoElement].index);_x000D_
      };_x000D_
    } else if (parameters.argument !== undefined && parameters.property === undefined) {_x000D_
      var windowStyle = window.getComputedStyle(_x000D_
        parameters.element, '::' + parameters.pseudoElement_x000D_
      ).getPropertyValue(parameters.argument);_x000D_
_x000D_
      if (parameters.element.pseudoElements) {_x000D_
        return parameters.element.pseudoElements[parameters.pseudoElement].properties[parameters.argument] || windowStyle;_x000D_
      } else {_x000D_
        return windowStyle || null;_x000D_
      };_x000D_
    } else {_x000D_
      console.error('Invalid values!');_x000D_
      return false;_x000D_
    };_x000D_
  };_x000D_
_x000D_
  Object.defineProperty(Element.prototype, 'styleBefore', {_x000D_
    enumerable: false,_x000D_
    value: function(argument, property) {_x000D_
      return setPseudoElement({_x000D_
        element: this,_x000D_
        pseudoElement: 'before',_x000D_
        argument: argument,_x000D_
        property: property_x000D_
      });_x000D_
    }_x000D_
  });_x000D_
  Object.defineProperty(Element.prototype, 'styleAfter', {_x000D_
    enumerable: false,_x000D_
    value: function(argument, property) {_x000D_
      return setPseudoElement({_x000D_
        element: this,_x000D_
        pseudoElement: 'after',_x000D_
        argument: argument,_x000D_
        property: property_x000D_
      });_x000D_
    }_x000D_
  });_x000D_
})();_x000D_
_x000D_
document.querySelector('.element').styleBefore('content', '"New before!"');
_x000D_
.element {_x000D_
  width: 480px;_x000D_
  margin: 0 auto;_x000D_
  border: 2px solid red;_x000D_
}_x000D_
_x000D_
.element::before {_x000D_
  content: 'Old before!';_x000D_
}
_x000D_
<div class="element"></div>
_x000D_
_x000D_
_x000D_


GitHub: https://github.com/yuri-spivak/managing-the-properties-of-pseudo-elements/


IF you want to to manipulate the ::before or ::after sudo elements entirely through CSS, you could do it JS. See below;

jQuery('head').append('<style id="mystyle" type="text/css"> /* your styles here */ </style>');

Notice how the <style> element has an ID, which you can use to remove it and append to it again if your style changes dynamically.

This way, your element is style exactly how you want it through CSS, with the help of JS.


Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to jquery

How to make a variable accessible outside a function? Jquery assiging class to th in a table Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Getting all files in directory with ajax Bootstrap 4 multiselect dropdown Cross-Origin Read Blocking (CORB) bootstrap 4 file input doesn't show the file name Jquery AJAX: No 'Access-Control-Allow-Origin' header is present on the requested resource how to remove json object key and value.?

Examples related to css

need to add a class to an element Using Lato fonts in my css (@font-face) Please help me convert this script to a simple image slider Why there is this "clear" class before footer? How to set width of mat-table column in angular? Center content vertically on Vuetify bootstrap 4 file input doesn't show the file name Bootstrap 4: responsive sidebar menu to top navbar Stylesheet not loaded because of MIME-type Force flex item to span full row width

Examples related to jquery-selectors

Why is my JQuery selector returning a n.fn.init[0], and what is it? How to use placeholder as default value in select2 framework Access the css ":after" selector with jQuery jQuery: using a variable as a selector Check if any ancestor has a class using jQuery jQuery selector first td of each row Select element by exact match of its content jQuery selector to get form by name jQuery : select all element with custom attribute Set select option 'selected', by value

Examples related to pseudo-element

CSS pseudo elements in React Add line break to ::after or ::before pseudo-element content Using CSS :before and :after pseudo-elements with inline CSS? Combine :after with :hover Can I have multiple :before pseudo-elements for the same element? :after and :before pseudo-element selectors in Sass Creating a border like this using :before And :after Pseudo-Elements In CSS? css rotate a pseudo :after or :before content:"" Can I change the height of an image in CSS :before/:after pseudo-elements? Using :before CSS pseudo element to add image to modal