Выбор и управление псевдоэлементами CSS, такими как: до и: после использования jQuery

есть ли способ выбрать / манипулировать псевдоэлементами CSS, такими как ::before и ::after (и старая версия с одной запятой) с помощью jQuery?

моя таблица стилей имеет следующее правило:
.span::after{ content:'foo' }

как я могу изменить " foo " на " bar " с помощью jQuery?

21 ответов


вы также можете передать содержимое псевдо-элементу с атрибутом данных, а затем использовать jQuery для управления этим:

в HTML:

<span>foo</span>

в jQuery:

$('span').hover(function(){
    $(this).attr('data-content','bar');
});

в CSS:

span:after {
    content: attr(data-content) ' any other text you may want';
}

если вы хотите предотвратить появление "другого текста", вы можете объединить это с решением seucolega следующим образом:

в HTML:

<span>foo</span>

в jQuery:

$('span').hover(function(){
    $(this).addClass('change').attr('data-content','bar');
});

в CSS:

span.change:after {
    content: attr(data-content) ' any other text you may want';
}

вы думаете, что это будет простой вопрос для ответа, со всем остальным, что может сделать jQuery. К сожалению, проблема сводится к технической проблеме: css: after and: before правила не являются частью DOM, и поэтому не может быть изменен с помощью методов DOM jQuery.

здесь are способы манипулирования этими элементами с помощью JavaScript и / или CSS обходных путей; какой из них вы используете, зависит от вашего точного требования.


я собираюсь начать с того, что считается "лучшим" подход:

1) Добавить/удалить заданный класс

в этом подходе вы уже создали класс в своем CSS с другим :after или :before стиль. Поместите этот" новый " класс позже в таблицу стилей, чтобы убедиться, что он переопределяет:

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

затем вы можете легко добавить или удалить этот класс с помощью jQuery (или vanilla JavaScript-код):

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

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

<p>This is a paragraph.</p>
<p>This is another paragraph.</p>
  • плюсы: легко реализовать с помощью jQuery; быстро изменяет несколько стилей сразу; обеспечивает разделение проблем (изолируя CSS и JS от вашего HTML)
  • плюсы: CSS должен быть предварительно написан, поэтому содержание :before или :after не совсем динамический

2) Добавьте новые стили сразу к таблица стилей документа

можно использовать JavaScript для добавления стилей непосредственно в таблицу стилей документа, включая :after и :before стили. jQuery не предоставляет удобный ярлык, но, к счастью, JS не так сложен:

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

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

<p class="special">This is a paragraph</p>
<p>This is another paragraph</p>

.addRule() и связанные с .insertRule() методы сегодня довольно хорошо поддерживаются.

как вариант, вы также можете использовать jQuery для добавления совершенно новой таблицы стилей в документ, но необходимый код не чище:

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

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

<p class="special">This is a paragraph</p>
<p>This is another paragraph</p>

если мы говорим о "манипулировании" значениями, А не просто добавлении к ним, мы также можем читать существующей :after или :before стили используя другой подход:

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

var str = window.getComputedStyle($('p')[0], ':before').getPropertyValue('content');
console.log(str);

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

<p class="special">This is a paragraph</p>
<p>This is another paragraph</p>

мы можем заменить document.querySelector('p') С $('p')[0] когда с помощью jQuery, чуть короче код.

  • плюсы: любая строка может быть динамически вставляются в стиле
  • плюсы: оригинальные стили не изменяются, просто переопределяются; повторное использование (ab) может заставить DOM расти произвольно большим

3) Измените другой атрибут DOM

вы можете использовать attr() в вашей В CSS для чтения определенного атрибута DOM. (если браузер поддерживает :before, он поддерживает attr() как хорошо.), сочетая это с content: в некоторых тщательно подготовленных CSS мы можем изменить содержимое (но не другие свойства, как маржа или цвет):before и :after динамически:

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

JS:

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

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

<p>This is a paragraph.</p>
<p>This is another paragraph.</p>

это можно совместить со второй техникой, если CSS не может быть подготовлен заранее:

var str = "bar";

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

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

var str = "bar";
document.styleSheets[0].addRule('p:before', 'content: attr(data-before) !important;');

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

<p>This is a paragraph.</p>
<p>This is another paragraph.</p>
  • плюсы: не создает бесконечные дополнительные стили
  • плюсы: attr в CSS может применяться только к строкам контента, а не URL-адресам или цветам RGB

хотя они отображаются браузерами через CSS, как если бы они были похожи на другие реальные элементы DOM, псевдо-элементы сами по себе не являются частью DOM, потому что псевдо-элементы, как следует из названия, не являются реальными элементами, и поэтому вы не можете выбирать и манипулировать ими напрямую с помощью jQuery (или любой JavaScript API, если на то пошло, даже не селекторы API). Это относится к любым псевдо-элементам, стили которых вы пытаетесь изменить с помощью скрипта, а не просто ::before и ::after.

вы можете получить доступ только к стилям псевдо-элементов непосредственно во время выполнения через CSSOM (think window.getComputedStyle()), который не подвергается jQuery за пределами .css() - метод, который не поддерживает псевдо-элементы.

вы всегда можете найти другие способы обойти это, хотя, например:

  • применение стилей к псевдо-элементам одного или нескольких произвольных классов, а затем переключение между классами (см. seucolega по ответ для быстрого примера) - это идиоматический способ, поскольку он использует простые селекторы (которые псевдо-элементы не являются), чтобы различать элементы и состояния элементов, так как они предназначены для использования

  • манипулирование стилями, применяемыми к упомянутым псевдо-элементам, путем изменения таблицы стилей документа, которая является гораздо более взломанной


вы не можете выбрать псевдоэлементы в jQuery, потому что они не являются частью DOM. Но вы можете добавить определенный класс к элементу father и управлять его псевдоэлементами в CSS.

пример

в jQuery:

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

в CSS:

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

в строке того, что предлагает Кристиан, вы также можете сделать:

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

вот способ доступа: после и: перед свойствами стиля, определенными в 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');

Я ответил на этот вопрос здесь уже, но чтобы быть супер-крутым, я повторюсь для вас.

ответ должен быть Да / Нет. Вы не можете выбрать элемент с помощью псевдо-селектора, но вы можете добавить новое правило в таблицу стилей с помощью JavaScript.

Я сделал то, что должно работать для вас:

var addRule = function(sheet, selector, styles) {
    if (sheet.insertRule) return sheet.insertRule(selector + " {" + styles + "}", sheet.cssRules.length);
    if (sheet.addRule) return sheet.addRule(selector, styles);
};

addRule(document.styleSheets[0], "body:after", "content: 'foo'");

http://fiddle.jshell.net/MDyxg/1/


Если вы хотите манипулировать элементами ::before или:: after sudo полностью через CSS, вы можете сделать это JS. См. ниже;

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

обратите внимание, как <style> элемент имеет идентификатор, который вы можете использовать для его удаления и добавления к нему снова, если ваш стиль изменяется динамически.

таким образом, ваш элемент-это стиль, как вы хотите его через CSS, с помощью JS.


мы также можем положиться на пользовательские свойства CSS (переменные) для того, чтобы манипулировать псевдо-элемент. Мы можем прочитать в спецификация что:

пользовательские свойства являются обычными свойствами, поэтому они могут быть объявлены на любой элемент, разрешаются с помощью нормальный наследования и каскад правила, можно сделать условным с @media и другими условными правилами, можно использовать в атрибут стиля HTML, может быть чтение или установка с помощью CSSOM, etc.

учитывая это, идея в том, чтобы определить пользовательское свойство в элемент и псевдоэлемент просто унаследовать его; таким образом, мы можем легко изменить его.

обратите внимание, что переменные CSS могут быть доступны не во всех браузерах, которые вы считаете релевантными (например, IE 11): https://caniuse.com/#feat=css-variables

1) использование встроенного стиля:

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

2) использование CSS и классов

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

.blue {
  --color:blue;
}
.black {
  --color:black;
}
<div class="box"></div>
<div class="box black" ></div>
<div class="box blue"></div>

3) использование javascript

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

4) Используя в jQuery

$('.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");
.box:before {
  content:"I am a before element";
  color:var(--color, red);
  font-size:25px;
}
<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>

он также может использоваться со сложными значениями:

.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);
}
<div class="box"></div>

вот HTML:

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

вычисленный стиль на " ДО " был content: "VERIFY TO WATCH";

вот мои две строки jQuery, которые используют идею добавления дополнительного класса для конкретной ссылки на этот элемент, а затем добавления тега стиля (с!важный тег) для изменения CSS значения содержимого sudo-элемента:

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

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


один рабочий, но не очень эффективный способ-добавить правило в документ с новым содержимым и ссылаться на него с классом. в зависимости от необходимости классу может потребоваться уникальный идентификатор для каждого значения в содержимом.

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

спасибо всем! мне удалось сделать то, что я хотел :Д http://jsfiddle.net/Tfc9j/42/ вот посмотрите

Я хотел, чтобы непрозрачность внешнего div отличалась от непрозрачности внутреннего div, и это изменение с помощью щелчка somwewhere ;) Спасибо!

   $('#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>

это не практично, так как я не писал это для использования в реальном мире, просто чтобы дать вам пример того, что может быть достигнуто.

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>"); 
}
}
}

В настоящее время это добавление a / или добавляет элемент стиля, который содержит необходимый атрибут, который будет влиять на целевой элемент после псевдо-элемента.

Это можно использовать как

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

и

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

как после: и до: псевдо-элементы не доступны напрямую через DOM it в настоящее время невозможно свободно редактировать определенные значения css.

мой путь был просто примером, и его не хорошо для практики, вы можете изменить его попробовать некоторые из ваших собственных трюков и сделать его правильным для использования в реальном мире.

Так что ваши собственные эксперименты с этим и другими!

С уважением - Адарш Хегде.


вы можете создать поддельное свойство или использовать существующий и наследование это в таблице стилей псевдо-элемента.

var switched = false;

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

похоже, что это не работает для свойства "content": (


зачем добавлять классы или атрибуты, когда можно просто добавить style в голову

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

здесь много ответов, но никакой ответ не помогает манипулировать css :before или :after , даже не принят.

вот как я предлагаю это сделать. Предположим, ваш HTML выглядит так:

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

и затем вы устанавливаете его: раньше в CSS и конструируете его как:

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

обратите внимание, что я также установил content атрибут в самом элементе, так что вы можете взять его легко позже. Теперь есть button нажав на которую, вы хотите изменить цвет: до зеленого и его размер шрифта на 30px. Вы можете добиться этого следующим образом:

определите css с вашим требуемым стилем на некотором классе .activeS :

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

теперь вы можете изменить :перед стилем, добавив класс в свой: перед элементом следующим образом:

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

если вы просто хотите сделать контент :before, это можно сделать так:

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

в конечном счете, если вы хотите динамически изменять :before содержимое jQuery, вы можете достичь этого следующим образом:

<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>

нажатие на кнопку выше "changeBefore" изменится :before контент #something в '22', который является динамическим значением.

надеюсь, это поможет


Я всегда добавляю свою собственную функцию utils, которая выглядит так.

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

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

или использовать функции ES6:

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

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

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

вы можете использовать свой плагин для этой цели.

JQuery:

(function() {
  $.pseudoElements = {
    length: 0
  };

  var setPseudoElement = function(parameters) {
    if (typeof parameters.argument === 'object' || (parameters.argument !== undefined && parameters.property !== undefined)) {
      for (var element of parameters.elements.get()) {
        if (!element.pseudoElements) element.pseudoElements = {
          styleSheet: null,
          before: {
            index: null,
            properties: null
          },
          after: {
            index: null,
            properties: null
          },
          id: null
        };

        var selector = (function() {
          if (element.pseudoElements.id !== null) {
            if (Number(element.getAttribute('data-pe--id')) !== element.pseudoElements.id) element.setAttribute('data-pe--id', element.pseudoElements.id);
            return '[data-pe--id="' + element.pseudoElements.id + '"]::' + parameters.pseudoElement;
          } else {
            var id = $.pseudoElements.length;
            $.pseudoElements.length++

              element.pseudoElements.id = id;
            element.setAttribute('data-pe--id', id);

            return '[data-pe--id="' + id + '"]::' + parameters.pseudoElement;
          };
        })();

        if (!element.pseudoElements.styleSheet) {
          if (document.styleSheets[0]) {
            element.pseudoElements.styleSheet = document.styleSheets[0];
          } else {
            var styleSheet = document.createElement('style');

            document.head.appendChild(styleSheet);
            element.pseudoElements.styleSheet = styleSheet.sheet;
          };
        };

        if (element.pseudoElements[parameters.pseudoElement].properties && element.pseudoElements[parameters.pseudoElement].index) {
          element.pseudoElements.styleSheet.deleteRule(element.pseudoElements[parameters.pseudoElement].index);
        };

        if (typeof parameters.argument === 'object') {
          parameters.argument = $.extend({}, parameters.argument);

          if (!element.pseudoElements[parameters.pseudoElement].properties && !element.pseudoElements[parameters.pseudoElement].index) {
            var newIndex = element.pseudoElements.styleSheet.rules.length || element.pseudoElements.styleSheet.cssRules.length || element.pseudoElements.styleSheet.length;

            element.pseudoElements[parameters.pseudoElement].index = newIndex;
            element.pseudoElements[parameters.pseudoElement].properties = parameters.argument;
          };

          var properties = '';

          for (var property in parameters.argument) {
            if (typeof parameters.argument[property] === 'function')
              element.pseudoElements[parameters.pseudoElement].properties[property] = parameters.argument[property]();
            else
              element.pseudoElements[parameters.pseudoElement].properties[property] = parameters.argument[property];
          };

          for (var property in element.pseudoElements[parameters.pseudoElement].properties) {
            properties += property + ': ' + element.pseudoElements[parameters.pseudoElement].properties[property] + ' !important; ';
          };

          element.pseudoElements.styleSheet.addRule(selector, properties, element.pseudoElements[parameters.pseudoElement].index);
        } else if (parameters.argument !== undefined && parameters.property !== undefined) {
          if (!element.pseudoElements[parameters.pseudoElement].properties && !element.pseudoElements[parameters.pseudoElement].index) {
            var newIndex = element.pseudoElements.styleSheet.rules.length || element.pseudoElements.styleSheet.cssRules.length || element.pseudoElements.styleSheet.length;

            element.pseudoElements[parameters.pseudoElement].index = newIndex;
            element.pseudoElements[parameters.pseudoElement].properties = {};
          };

          if (typeof parameters.property === 'function')
            element.pseudoElements[parameters.pseudoElement].properties[parameters.argument] = parameters.property();
          else
            element.pseudoElements[parameters.pseudoElement].properties[parameters.argument] = parameters.property;

          var properties = '';

          for (var property in element.pseudoElements[parameters.pseudoElement].properties) {
            properties += property + ': ' + element.pseudoElements[parameters.pseudoElement].properties[property] + ' !important; ';
          };

          element.pseudoElements.styleSheet.addRule(selector, properties, element.pseudoElements[parameters.pseudoElement].index);
        };
      };

      return $(parameters.elements);
    } else if (parameters.argument !== undefined && parameters.property === undefined) {
      var element = $(parameters.elements).get(0);

      var windowStyle = window.getComputedStyle(
        element, '::' + parameters.pseudoElement
      ).getPropertyValue(parameters.argument);

      if (element.pseudoElements) {
        return $(parameters.elements).get(0).pseudoElements[parameters.pseudoElement].properties[parameters.argument] || windowStyle;
      } else {
        return windowStyle || null;
      };
    } else {
      console.error('Invalid values!');
      return false;
    };
  };

  $.fn.cssBefore = function(argument, property) {
    return setPseudoElement({
      elements: this,
      pseudoElement: 'before',
      argument: argument,
      property: property
    });
  };
  $.fn.cssAfter = function(argument, property) {
    return setPseudoElement({
      elements: this,
      pseudoElement: 'after',
      argument: argument,
      property: property
    });
  };
})();

$(function() {
  $('.element').cssBefore('content', '"New before!"');
});
.element {
  width: 480px;
  margin: 0 auto;
  border: 2px solid red;
}

.element::before {
  content: 'Old before!';
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>

<div class="element"></div>

значения должны быть указаны, как в нормальной функции в jQuery.в CSS

кроме того, вы также можете получить значение параметра псевдо-элемента, как в нормальной функции jQuery.css:

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

JS:

(function() {
  document.pseudoElements = {
    length: 0
  };

  var setPseudoElement = function(parameters) {
    if (typeof parameters.argument === 'object' || (parameters.argument !== undefined && parameters.property !== undefined)) {
      if (!parameters.element.pseudoElements) parameters.element.pseudoElements = {
        styleSheet: null,
        before: {
          index: null,
          properties: null
        },
        after: {
          index: null,
          properties: null
        },
        id: null
      };

      var selector = (function() {
        if (parameters.element.pseudoElements.id !== null) {
          if (Number(parameters.element.getAttribute('data-pe--id')) !== parameters.element.pseudoElements.id) parameters.element.setAttribute('data-pe--id', parameters.element.pseudoElements.id);
          return '[data-pe--id="' + parameters.element.pseudoElements.id + '"]::' + parameters.pseudoElement;
        } else {
          var id = document.pseudoElements.length;
          document.pseudoElements.length++

            parameters.element.pseudoElements.id = id;
          parameters.element.setAttribute('data-pe--id', id);

          return '[data-pe--id="' + id + '"]::' + parameters.pseudoElement;
        };
      })();

      if (!parameters.element.pseudoElements.styleSheet) {
        if (document.styleSheets[0]) {
          parameters.element.pseudoElements.styleSheet = document.styleSheets[0];
        } else {
          var styleSheet = document.createElement('style');

          document.head.appendChild(styleSheet);
          parameters.element.pseudoElements.styleSheet = styleSheet.sheet;
        };
      };

      if (parameters.element.pseudoElements[parameters.pseudoElement].properties && parameters.element.pseudoElements[parameters.pseudoElement].index) {
        parameters.element.pseudoElements.styleSheet.deleteRule(parameters.element.pseudoElements[parameters.pseudoElement].index);
      };

      if (typeof parameters.argument === 'object') {
        parameters.argument = (function() {
          var cloneObject = typeof parameters.argument.pop === 'function' ? [] : {};

          for (var property in parameters.argument) {
            cloneObject[property] = parameters.argument[property];
          };

          return cloneObject;
        })();

        if (!parameters.element.pseudoElements[parameters.pseudoElement].properties && !parameters.element.pseudoElements[parameters.pseudoElement].index) {
          var newIndex = parameters.element.pseudoElements.styleSheet.rules.length || parameters.element.pseudoElements.styleSheet.cssRules.length || parameters.element.pseudoElements.styleSheet.length;

          parameters.element.pseudoElements[parameters.pseudoElement].index = newIndex;
          parameters.element.pseudoElements[parameters.pseudoElement].properties = parameters.argument;
        };

        var properties = '';

        for (var property in parameters.argument) {
          if (typeof parameters.argument[property] === 'function')
            parameters.element.pseudoElements[parameters.pseudoElement].properties[property] = parameters.argument[property]();
          else
            parameters.element.pseudoElements[parameters.pseudoElement].properties[property] = parameters.argument[property];
        };

        for (var property in parameters.element.pseudoElements[parameters.pseudoElement].properties) {
          properties += property + ': ' + parameters.element.pseudoElements[parameters.pseudoElement].properties[property] + ' !important; ';
        };

        parameters.element.pseudoElements.styleSheet.addRule(selector, properties, parameters.element.pseudoElements[parameters.pseudoElement].index);
      } else if (parameters.argument !== undefined && parameters.property !== undefined) {
        if (!parameters.element.pseudoElements[parameters.pseudoElement].properties && !parameters.element.pseudoElements[parameters.pseudoElement].index) {
          var newIndex = parameters.element.pseudoElements.styleSheet.rules.length || parameters.element.pseudoElements.styleSheet.cssRules.length || parameters.element.pseudoElements.styleSheet.length;

          parameters.element.pseudoElements[parameters.pseudoElement].index = newIndex;
          parameters.element.pseudoElements[parameters.pseudoElement].properties = {};
        };

        if (typeof parameters.property === 'function')
          parameters.element.pseudoElements[parameters.pseudoElement].properties[parameters.argument] = parameters.property();
        else
          parameters.element.pseudoElements[parameters.pseudoElement].properties[parameters.argument] = parameters.property;

        var properties = '';

        for (var property in parameters.element.pseudoElements[parameters.pseudoElement].properties) {
          properties += property + ': ' + parameters.element.pseudoElements[parameters.pseudoElement].properties[property] + ' !important; ';
        };

        parameters.element.pseudoElements.styleSheet.addRule(selector, properties, parameters.element.pseudoElements[parameters.pseudoElement].index);
      };
    } else if (parameters.argument !== undefined && parameters.property === undefined) {
      var windowStyle = window.getComputedStyle(
        parameters.element, '::' + parameters.pseudoElement
      ).getPropertyValue(parameters.argument);

      if (parameters.element.pseudoElements) {
        return parameters.element.pseudoElements[parameters.pseudoElement].properties[parameters.argument] || windowStyle;
      } else {
        return windowStyle || null;
      };
    } else {
      console.error('Invalid values!');
      return false;
    };
  };

  Object.defineProperty(Element.prototype, 'styleBefore', {
    enumerable: false,
    value: function(argument, property) {
      return setPseudoElement({
        element: this,
        pseudoElement: 'before',
        argument: argument,
        property: property
      });
    }
  });
  Object.defineProperty(Element.prototype, 'styleAfter', {
    enumerable: false,
    value: function(argument, property) {
      return setPseudoElement({
        element: this,
        pseudoElement: 'after',
        argument: argument,
        property: property
      });
    }
  });
})();

document.querySelector('.element').styleBefore('content', '"New before!"');
.element {
  width: 480px;
  margin: 0 auto;
  border: 2px solid red;
}

.element::before {
  content: 'Old before!';
}
<div class="element"></div>

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


кто-то еще прокомментировал добавление к элементу head с полным элементом стиля, и это неплохо, если вы делаете это только один раз, но если вам нужно сбросить его более одного раза, вы получите тонну элементов стиля. Чтобы предотвратить это, я создал пустой элемент стиля в голове с идентификатором и заменил его innerHTML следующим образом:

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

тогда JavaScript будет выглядеть так:

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

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

setHeight()

теперь в моем случае мне нужно было это, чтобы установить высоту перед элементом, основанным на высоте другого, и он изменится при изменении размера, поэтому с помощью этого я могу запустить setHeight() каждый раз, когда окно изменяется, и оно заменит <style> правильно.

надеюсь, что это поможет кому-то, кто застрял, пытаясь сделать то же самое.


я использовал переменные, определенные в :root внутри CSS изменить :after (то же самое относится к :before) псевдо-элемент в частности, чтобы изменить background-color значение для стиля anchor определено .sliding-middle-out:hover:after и content значение для другого anchor (#reference) по следующим демо что генерирует случайные цвета с помощью 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("");
 }
);