Seleccionar y manipular pseudo-elementos CSS como :: before y :: after usando javascript (o jQuery)

¿Hay alguna forma de seleccionar / manipular pseudoelementos CSS como ::before y ::after (y la versión anterior con un punto y coma) usando jQuery?

Por ejemplo, mi hoja de estilo tiene la siguiente regla:

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

¿Cómo puedo cambiar 'foo' a 'bar' usando vanilla JS o jQuery?

preguntado el 18 de febrero de 11 a las 09:02

Hice algo que debería funcionar para ti: gist.github.com/yckart/5563717 -

Odio esos comentarios en stackoverflow que voy a escribir (donde el comentarista pregunta ¿Por qué no lo haces de una manera completamente opuesta?), pero: en algún momento uno debería darse cuenta del problema de diseño de código y reemplazar ese pseudo elemento con un intervalo o algo. Supongo que sabes a lo que estoy apuntando. -

La respuesta aceptada es excelente. Aunque si está tratando de lograr alguno de los siguientes puntos, la respuesta no funcionará: 1. cambie el estilo de: before por JS. 2. cambiar el contenido de: before por JS Por favor, vea mi respuesta si lo necesita. -

@Learner Ahora hay una respuesta para todos estos: stackoverflow.com/a/49618941/8620333 -

23 Respuestas

También puede pasar el contenido al pseudo elemento con un atributo de datos y luego usar jQuery para manipular eso:

En HTML:

<span>foo</span>

En jQuery:

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

En CSS:

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

Si desea evitar que aparezca el 'otro texto', puede combinar esto con la solución de seucolega de esta manera:

En HTML:

<span>foo</span>

En jQuery:

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

En CSS:

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

Respondido el 28 de Septiembre de 15 a las 16:09

¿Tiene un enlace en la especificación para usar ese attr función contra el content ¿propiedad? Me sorprende que nunca haya oído hablar de esto ... - Kevin Peno

+1 para attr(), lástima que no pude usarlo con otras propiedades que no sean content. Demo - Maksim Vi.

Eso es porque ningún navegador existente ha implementado attr() más allá de CSS2 todavía, mientras que en CSS2 en sí attr() solo se ha definido para el content propiedad. - BoltClock ♦

Enlace actualizado para referencias de atributos: w3.org/TR/css3-values/#attr-notación - usuario166560

Pensaría que esta sería una pregunta simple de responder, con todo lo demás que jQuery puede hacer. Desafortunadamente, el problema se reduce a un problema técnico: css: after y: before que las reglas no son parte del DOM, y, por lo tanto, no se puede modificar con los métodos DOM de jQuery.

Aún así, se encuentran las formas de manipular estos elementos usando JavaScript y / o soluciones CSS; cuál utilice depende de sus requisitos exactos.


Comenzaré con lo que se considera generalmente el "mejor" enfoque:

1) Agregar / eliminar una clase predeterminada

En este enfoque, ya ha creado una clase en su CSS con una :after or :before estilo. Coloque esta "nueva" clase más adelante en su hoja de estilo para asegurarse de que anule:

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

Luego, puede agregar o eliminar fácilmente esta clase usando jQuery (o JavaScript vanilla):

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

  • Pros: Fácil de implementar con jQuery; altera rápidamente varios estilos a la vez; impone la separación de preocupaciones (aislando su CSS y JS de su HTML)
  • Contras: CSS debe estar escrito previamente, por lo que el contenido de :before or :after no es completamente dinámico

2) Agregue nuevos estilos directamente a la hoja de estilo del documento

Es posible usar JavaScript para agregar estilos directamente a la hoja de estilo del documento, incluyendo :after y :before estilos. jQuery no proporciona un atajo conveniente, pero afortunadamente el JS no es tan complicado:

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() y la relacionada .insertRule() métodos están bastante bien respaldados en la actualidad.

Como variación, también puede usar jQuery para agregar una hoja de estilo completamente nueva al documento, pero el código necesario no es más limpio:

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>

Si hablamos de "manipular" los valores, no solo de agregarlos, también podemos leer la existencia :after or :before estilos utilizando un enfoque diferente:

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>

Podemos reemplazar document.querySelector('p') con $('p')[0] cuando se usa jQuery, para un código un poco más corto.

  • Pros: cualquier cadena se puede insertar dinámicamente en el estilo
  • Contras: los estilos originales no se modifican, solo se anulan; El uso repetido (ab) puede hacer que el DOM crezca arbitrariamente grande

3) Modificar un atributo DOM diferente

También puedes utilizado attr() en tu CSS para leer un atributo DOM en particular. (Si un navegador admite :before, es compatible attr() también.) Combinando esto con content: en un CSS cuidadosamente preparado, podemos cambiar el contenido (pero no otras propiedades, como margen o color) de :before y :after dinamicamente:

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>

Esto se puede combinar con la segunda técnica si el CSS no se puede preparar con anticipación:

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>

  • Pros: No crea infinitos estilos adicionales
  • Contras: attr en CSS solo se puede aplicar a cadenas de contenido, no a URL o colores RGB

Respondido el 17 de junio de 15 a las 14:06

Estoy tratando de establecer dinámicamente valores de glyphicon (es decir, a través de sus valores hexadecimales) en :: after psedo. contenido: elemento (por ejemplo, contenido: "\ e043";). no parece funcionar para mí, así que supongo que tampoco funciona para valores hexadecimales para glifos. - user2101068

@ user2101068 Deberías publicar eso como una nueva pregunta. Tendría que ver todo el código que estás usando. - traficante de llamas

Blazemonger, gracias por la rápida respuesta ... desafortunadamente hay bastante código y tomaría un poco de esfuerzo eliminar el código relevante. Ya he pasado más de 12 horas tratando de hacer que esto funcione y este fue mi último esfuerzo para hacerlo funcionar. Necesito reducir mis pérdidas. Esperaba que pudiera verificar mi suposición re: valores hexadecimales al usar la técnica que describió en el n. ° 3 anterior (antes del fragmento de código). Puedo insertar una cadena hexadecimal en el elemento de contenido, pero muestra texto para el valor hexadecimal del glyphicon en lugar del glyphicon real. ¿Impresión sin ver todo el código? - user2101068

@ user2101068 No use la cadena hexadecimal; en su lugar, copie y pegue el carácter Unicode real en el atributo HTML. jsfiddle.net/mblase75/Lcsjkc5y - traficante de llamas

con respecto a la solución 2. y 3. en realidad puede evitar que la hoja de estilo crezca (en exceso) si usa: document.styleSheets [0] .insertRule (regla, índice), luego usando este índice puede eliminar las reglas cuando no las necesite: documento. styleSheets [0] .deleteRule (índice) - Picard

Aunque los navegadores los renderizan a través de CSS como si fueran otros elementos DOM reales, los pseudo-elementos en sí mismos no forman parte del DOM, porque los pseudo-elementos, como su nombre lo indica, no son elementos reales y, por lo tanto, no puede seleccionarlos y manipularlos directamente con jQuery (o cualquier API de JavaScript para el caso, ni siquiera el API de selectores). Esto se aplica a cualquier pseudoelemento cuyos estilos esté intentando modificar con un script, y no solo ::before y ::after.

Solo puede acceder a estilos de pseudoelementos directamente en tiempo de ejecución a través de CSSOM (piense window.getComputedStyle()), que no está expuesto por jQuery más allá de .css(), un método que tampoco admite pseudoelementos.

Sin embargo, siempre puede encontrar otras formas de evitarlo, por ejemplo:

  • Aplicar los estilos a los pseudo-elementos de una o más clases arbitrarias, luego alternar entre clases (ver la respuesta de seucolega para un ejemplo rápido): esta es la forma idiomática, ya que hace uso de selectores simples (que los pseudoelementos no lo son) para distinguir entre elementos y estados de elementos, la forma en que están destinados a ser usados

  • Manipular los estilos que se están aplicando a dichos pseudo-elementos, alterando la hoja de estilo del documento, que es mucho más un truco.

Respondido el 05 de junio de 18 a las 03:06

No puede seleccionar pseudo elementos en jQuery porque no son parte de DOM. Pero puede agregar una clase específica al elemento principal y controlar sus pseudo elementos en CSS.

EJEMPLO

En jQuery:

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

En CSS:

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

contestado el 18 de mayo de 21 a las 20:05

También podemos confiar en propiedades personalizadas (también conocidas como variables CSS) para manipular el pseudo-elemento. Podemos leer en el especificación que:

Las propiedades personalizadas son propiedades ordinarias, por lo que se pueden declarar en cualquier elemento, se resuelven con la herencia normal y cascadas reglas, se puede hacer condicional con @media y otras reglas condicionales, se puede usar en Atributo de estilo de HTML, puede ser leer o configurar usando el CSSOM, etc.

Considerando esto, la idea es definir la propiedad personalizada dentro del elemento y el pseudo-elemento simplemente lo heredará; así podemos modificarlo fácilmente.

1) Usar estilo en línea:

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

2) Usando CSS y clases

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

3) Usando javascript

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

4) Usando 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>


También se puede utilizar con valores complejos:

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

Puede notar que estoy considerando la sintaxis var(--c,value) dónde value es el valor predeterminado y también se denomina valor de reserva.

De la misma especificación podemos leer:

El valor de una propiedad personalizada se puede sustituir por el valor de otra propiedad con la función var (). La sintaxis de var () es:

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

El primer argumento de la función es el nombre de la propiedad personalizada que se sustituirá. El segundo argumento de la función, si se proporciona, es un valor de reserva, que se utiliza como valor de sustitución. cuando la propiedad personalizada a la que se hace referencia no es válida.

Y después:

Para sustituir una var () en el valor de una propiedad:

  1. Si la propiedad personalizada nombrada por el primer argumento de la var() función está teñida de animación, y la var() La función se está utilizando en la propiedad de animación o en una de sus longhands, trate la propiedad personalizada como si tuviera su valor inicial para el resto de este algoritmo.
  2. Si el valor de la propiedad personalizada nombrada por el primer argumento de la var() función es cualquier cosa menos el valor inicial, reemplace el var() función por el valor de la propiedad personalizada correspondiente.
  3. De lo contrario, si el var() función tiene un valor de reserva como segundo argumento, reemplace el var() función por el valor de reserva. Si hay alguno var() referencias en el respaldo, sustitúyalas también.
  4. De lo contrario, la propiedad que contiene el var() La función no es válida en el momento del valor calculado.

Si no configuramos la propiedad personalizada O la configuramos en initial O si contiene un valor no válido, se utilizará el valor de reserva. El uso de initial puede ser útil en caso de que queramos restablecer una propiedad personalizada a su valor predeterminado.

Relacionado:

¿Cómo almacenar el valor heredado dentro de una variable CSS (también conocida como propiedad personalizada)?

Propiedades personalizadas de CSS (variables) para el modelo de caja

Respondido el 24 de enero de 21 a las 12:01

@akalata sí, el código requiere una versión de jQuery 3.x .. Agregué más detalles y otra alternativa con jQuery;) - Temani Afif

¿Cómo funcionaría esto en IE 11? - conexo

@connexo como cualquier característica buena y moderna ... no es compatible y no funcionará caniuse.com/#feat=css-variables - Temani Afif

Ofc, lo sabía y, dado que IE 11 sigue siendo muy relevante, me perdí esa información en la parte introductoria de su respuesta. - conexo

Esta respuesta es un tutorial en profundidad sobre cómo relacionar y modificar pseudoelementos con JavaScript usando variables CSS. Muchas gracias por su tiempo y por compartir esta (s) técnica (s) extremadamente valiosa (s). - LebCit

En la línea de lo que sugiere Christian, también podría hacer:

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

Respondido 18 Oct 12, 11:10

Aquí debe agregarse un atributo id, para que el elemento pueda seleccionarse y eliminarse antes de agregar uno nuevo. De lo contrario, pueden aparecer muchos nodos de estilo innecesarios. - Kansas

Desafortunadamente, su muestra no funcionó, pero esto funcionó. const setPseudoElContent = (selector, valor) => {const style = document.createElement ('estilo'); style.innerHTML = ${selector} {${value}; }; document.head.appendChild (estilo); } - Egberto Nierop

Esta es la forma de acceder a las propiedades de estilo: after y: before, definidas en 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');

Respondido 15 Jul 14, 22:07

SI desea manipular los elementos sudo :: before o :: after completamente a través de CSS, puede hacerlo JS. Vea abajo;

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

Note como el <style> El elemento tiene un ID, que puede usar para eliminarlo y agregarlo nuevamente si su estilo cambia dinámicamente.

De esta manera, su elemento tiene el estilo exactamente como lo desea a través de CSS, con la ayuda de JS.

Respondido el 14 de junio de 14 a las 21:06

¡Gracias a todos! Me las arreglé para hacer lo que quería: D http://jsfiddle.net/Tfc9j/42/ aquí echa un vistazo

Quería que la opacidad de un div externo fuera diferente de la opacidad del div interno y que cambiara con un clic en algún lugar;) ¡Gracias!

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

Respondido 10 Jul 14, 16:07

No intentar append, Utilizar html es mejor prevenir - reyjinete

Cuidado: aquí está agregando una etiqueta de estilo al encabezado cada vez que se maneja uno de esos clics. Codificaría una forma de eliminar el anterior antes de agregar uno nuevo. - pupitetris

Una forma que funciona pero no es muy eficiente es agregar una regla al documento con el nuevo contenido y hacer referencia a él con una clase. dependiendo de lo que se necesite, la clase puede necesitar una identificación única para cada valor en el contenido.

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

Respondido el 12 de Septiembre de 12 a las 14:09

Aquí está el HTML:

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

El estilo calculado en "antes" era content: "VERIFY TO WATCH";

Aquí están mis dos líneas de jQuery, que usan la idea de agregar una clase adicional para hacer referencia específicamente a este elemento y luego agregar una etiqueta de estilo (con una etiqueta! Important) para cambiar el CSS del valor de contenido del elemento sudo:

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

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

respondido 18 mar '14, 23:03

Puede crear una propiedad falsa o utilizar una existente y heredar en la hoja de estilo del pseudoelemento.

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>

Parece que no funciona para la propiedad "contenido" :(

Respondido 13 Oct 14, 14:10

Esto no es práctico ya que no escribí esto para usos del mundo real, solo para darle un ejemplo de lo que se puede lograr.

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

este agregado actualmente a / o agrega un elemento de estilo que contiene los atributos necesarios que tendrán efecto en el elemento de destino después del pseudo elemento.

esto se puede utilizar como

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

y

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

como after: y before: los pseudo elementos no son directamente accesibles a través de DOM, actualmente no es posible editar los valores específicos del css libremente.

mi método fue solo un ejemplo y no es bueno para la práctica, puedes modificarlo, probar algunos de tus propios trucos y corregirlo para el uso en el mundo real.

¡Así que haz tus propios experimentos con este y otros!

saludos - Adarsh ​​Hegde.

Respondido 20 Abr '15, 12:04

Siempre estoy agregando mi propia función de utilidades, que se ve así.

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

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

o haga uso de las características de ES6:

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

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

Respondido el 13 de Septiembre de 18 a las 10:09

Hay muchas respuestas aquí, pero ninguna ayuda a manipular el CSS de :before or :after , ni siquiera el aceptado.

Así es como propongo hacerlo. Supongamos que su HTML es así:

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

Y luego está configurando su: before en CSS y diseñando como:

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

Tenga en cuenta que también configuro content atributo en el propio elemento para que pueda eliminarlo fácilmente más tarde. Ahora hay un button al hacer clic en el cual, desea cambiar el color de: before a verde y su tamaño de fuente a 30px. Puede lograrlo de la siguiente manera:

Defina un CSS con su estilo requerido en alguna clase .activeS :

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

Ahora puede cambiar el estilo: before agregando la clase a su elemento: before de la siguiente manera:

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

Si solo desea obtener contenido de :before, se puede hacer como:

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

En última instancia, si desea cambiar dinámicamente :before contenido por jQuery, puede lograrlo de la siguiente manera:

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

Al hacer clic en el botón "changeBefore" de arriba, cambiará :before contenido de #something en '22', que es un valor dinámico.

Espero que ayude

respondido 14 nov., 16:13

¿Por qué agregar clases o atributos cuando simplemente puede agregar un style a la cabeza

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

Respondido 09 ago 16, 07:08

Puede usar mi complemento para este propósito.

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>

Los valores deben especificarse, como en la función normal de jQuery.css

Además, también puede obtener el valor del parámetro pseudoelemento, como en la función normal de 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/

Respondido 05 ago 17, 12:08

He creado un complemento jQuery para agregar reglas css-pseudo como usar .css() para elementos específicos.

  • el código del complemento y el caso de prueba es aquí
  • caso de uso como simple ventana emergente de imagen CSS aquí

uso:

$('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!"'
  });

Respondido 03 Feb 19, 06:02

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

Respondido el 28 de junio de 17 a las 12:06

Alguien más comentó sobre agregar al elemento principal con un elemento de estilo completo y eso no está mal si solo lo hace una vez, pero si necesita restablecerlo más de una vez, terminará con una tonelada de elementos de estilo. Entonces, para evitar eso, creé un elemento de estilo en blanco en la cabeza con una identificación y reemplacé el HTML interno de esta manera:

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

Entonces el JavaScript se vería así:

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

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

setHeight()

Ahora, en mi caso, necesitaba esto para establecer la altura de un elemento anterior en función de la altura de otro y cambiará al cambiar el tamaño, por lo que puedo ejecutar setHeight() cada vez que se cambia el tamaño de la ventana y reemplazará el <style> correctamente.

Espero que ayude a alguien que estaba atascado tratando de hacer lo mismo.

Respondido el 22 de Septiembre de 17 a las 12:09

Hice uso de variables definidas en :root dentro CSS Para modificar el :after (lo mismo se aplica a :before) pseudo-elemento, en particular para cambiar el background-color valor para un estilo anchor definido por .sliding-middle-out:hover:after y content valor para otro anchor (#reference) en el siguiente manifestación que genera colores aleatorios usando 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>

CO

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

Respondido el 17 de Septiembre de 18 a las 17:09

Apoyo a attr() excepto en content, es realmente escaso. Puede consultar caniuse.com. :root y el soporte de css-variables es mejor, pero aún no tan extendido ya que el soporte es bastante nuevo. (también verifique el soporte en caniuse.com) - PlátanoÁcido

Tengo algo diferente para ti que es fácil y efectivo.

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

respondido 12 nov., 19:09

La siguiente solución le dice cómo puede actualizar pseudo-elementos con javascript attr atributo.

agregue un atributo en HTML que puede manipular con javascript con setAttribute.

<div 
 id="inputBoxParent" 
 count="0">
      ...
</div>

actualizar con js

inputBoxParent.setAttribute('count', value.length)

CSS: en pseudoelemento, agregue contenido como attr (attributeName)

.input-box-container::after{
  content: attr(count);
}

¡¡¡Y ya está !!!

const inputBoxParent = document.getElementById("inputBoxParent");
const handleOnChange = (value) => {
  inputBoxParent.setAttribute('count', value.length)
}
.input-box-container {
  position: relative;
  width: 200px;
}
.input-box-container::after{
  position: absolute;
  bottom: 8px;
  right: 10px;
  height: 10px;
  width: 20px;
  content: attr(count);
}
<h4> Type some text inside the box and click outside to see resule i.e. pseudo element content change</h4>
<div 
  id="inputBoxParent" 
  class="input-box-container" 
  count="0">
  <input 
    type="text" 
    id="inputBox" 
    placeholder="type some thing" 
    onchange="handleOnChange(this.value)" />
</div>

respondido 20 mar '21, 10:03

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.