0

I'm trying to access the CSS :before and :after selectors with jQuery. I have tried a few methods, but it seems that the CSS selectors can't be seen by the DOM. What I'm trying to manipulate is to give the element a dynamic background-color.

For example:

.className:before {background: red;}

At some point, I want to change this color to be dynamic:

$('.clasName:before').css('background-color', bgColor);   //this method doesn't work

Also tried this:

$('.clasName').addClass('change').attr('data-background', bgColor); 
//this method works only for content property

CSS

.className.change:before {
 background: attr(data-background);
}

It's not working as well. Are there any work around for this issue in particular?

Vadim Badea
  • 409
  • 2
  • 8
  • 21
  • You can't set pseudo elements styles with JavaScript. (There is [technically a way](http://stackoverflow.com/questions/4481485/changing-css-pseudo-element-styles-via-javascript/12207551#answer-8051488), but as [this answer](http://stackoverflow.com/questions/4481485/changing-css-pseudo-element-styles-via-javascript) says, don't do it.) – Jacob G Mar 09 '16 at 21:09
  • 1
    Unfortunately, :before and :after are not part of the DOM, so there's nothing to query select. If you need that level of control, you should not be using pseudo class content. – Mike 'Pomax' Kamermans Mar 09 '16 at 21:09
  • @Mike'Pomax'Kamermans Should be possible by changing `style` or `link` element text – guest271314 Mar 09 '16 at 21:41
  • @JacobGray _"You can't set pseudo elements styles with JavaScript"_ See post – guest271314 Mar 09 '16 at 21:41
  • @guest271314 sure, but very different from single property changes using `attr` or `css` calls in jQuery. That's literally inventing new CSS and then rebinding it (with the associated document reflow, which is expensive) – Mike 'Pomax' Kamermans Mar 09 '16 at 21:48
  • @Mike'Pomax'Kamermans _"That's literally inventing new CSS and then rebinding it"_ The approach actually attempts to replace existing `style` text instead of add new style, if element has `pseudo` element. The reason `js` at post appends new text at `style` element is due to parsing selector. If `val.tagName` is removed from `selector` variable, existing properties, values of `pseudo` element should be replaced with new properties , values . Note, could be improved – guest271314 Mar 09 '16 at 21:53
  • @guest271314 that comment should have read, You can't update pseudo elements rules with JavaScript. – Jacob G Mar 10 '16 at 02:40

2 Answers2

3

(function($) {
  jQuery.fn.extend({
    getPseudo: function(pseudo, prop) {
      var props = window.getComputedStyle(
        $(this.selector).get(0), pseudo
      ).getPropertyValue(prop);
      return String(props);
    },
    setPseudo: function(_pseudo, _prop, newprop) {
      var elem = $(this);
      var s = $("style");
      var p = elem.getPseudo(_pseudo, _prop);
      console.log(p)
      var r = p !== "" ? new RegExp(p) : false;
      var selector = $.map(elem, function(val, key) {
        return [val.tagName, val.id 
                ? "#" + val.id : null, val.className ? "." + val.className 
                : null]
      });
      var _setProp = "\n" + selector.join("")
        .concat(_pseudo)
        .concat("{")
        .concat(_prop + ":")
        .concat(newprop + "};");
      ((!!r ? r.test($(s).text()) : r) ? $(s).text(function(index, prop) {
        return prop.replace(r, newprop)
      }) : $(s).append(_setProp));
      return this
    }
  })
})(jQuery);

$(".className").setPseudo(":before", "background", "blue");
.className:before {
  background: red;
  content: "123";
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>

<div class="className">abc</div>
guest271314
  • 1
  • 15
  • 104
  • 177
1

You can't change the style of pseudo elements with javascript, but you could add a <span> inside of your .className and then target that.

$('.className span').css('background-color', bgColor);
kravse
  • 126
  • 1
  • 8