Selecionando e manipulando pseudoelementos CSS, como :: before e :: after using jQuery


943

Existe alguma maneira de selecionar / manipular pseudoelementos CSS como ::beforee ::after(e a versão antiga com um ponto e vírgula) usando o jQuery?

Por exemplo, minha folha de estilo tem a seguinte regra:

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

Como posso mudar 'foo' para 'bar' usando o jQuery?


4
Eu fiz algo que deve funcionar para você: gist.github.com/yckart/5563717
— yckart

1
Eu odeio esses comentários no stackoverflow que vou escrever (onde o comentarista pergunta por que você não faz isso de maneira totalmente oposta? ), Mas: em algum momento, deve-se perceber um problema de design de código e substituir esse pseudo-elemento por um extensão ou algo assim. Eu acho que você sabe para o que estou apontando.
— Zsitro 11/05

1
A resposta aceita é excelente. Embora se você estiver tentando obter algum dos seguintes pontos, a resposta não funcionará: 1. mude o estilo de: before pelo JS. 2. altere o conteúdo de: before by JS Por favor, veja minha resposta se você precisar.
— Learner


@Learner Agora há uma resposta tfor todos estes: stackoverflow.com/a/49618941/8620333
— temanitas Afif

Respostas:


695

Você também pode passar o conteúdo para o pseudo elemento com um atributo de dados e, em seguida, usar o jQuery para manipular isso:

Em HTML:

<span>foo</span>

No jQuery:

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

Em CSS:

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

Se você deseja impedir que o 'outro texto' apareça, você pode combinar isso com a solução da seucolega da seguinte maneira:

Em HTML:

<span>foo</span>

No jQuery:

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

Em CSS:

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

2
Você tem um link na especificação para usar essa attrfunção contra a contentpropriedade? Eu estou surpreso que eu nunca ouvi falar disso ...
— Kevin Peno

95
+1 por attr(), pena que não pude usá-lo com outras propriedades que não content. Demo
— Maksim Vi.

28
Isso ocorre porque nenhum navegador existente foi implementado attr()além do CSS2, enquanto no próprio CSS2 attr()foi definido apenas para a contentpropriedade.
— BoltClock

10
Link atualizado para referências de atributo: w3.org/TR/css3-values/#attr-notation


477

Você acha que essa seria uma pergunta simples de responder, com tudo o mais que o jQuery pode fazer. Infelizmente, o problema se resume a um problema técnico: regras de css: after e: before não fazem parte do DOM e , portanto, não podem ser alteradas usando os métodos DOM do jQuery.

Não são maneiras de manipular esses elementos usando JavaScript e / ou CSS soluções alternativas; qual você usa depende de seus requisitos exatos.


Vou começar com o que é amplamente considerado a "melhor" abordagem:

1) Adicionar / remover uma classe predeterminada

Nesta abordagem, você já criou uma classe em seu CSS com um estilo :afterou :beforeestilo diferente . Posicione essa classe "nova" posteriormente na folha de estilo para garantir que ela substitua:

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

Em seguida, você pode adicionar ou remover facilmente essa classe usando jQuery (ou vanilla JavaScript):

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

  • Prós: Fácil de implementar com jQuery; altera rapidamente vários estilos ao mesmo tempo; impõe a separação de preocupações (isolando seu CSS e JS do seu HTML)
  • Contras: o CSS deve ser pré-escrito, para que o conteúdo :beforeou :afternão seja completamente dinâmico

2) Adicione novos estilos diretamente à folha de estilo do documento

É possível usar o JavaScript para adicionar estilos diretamente à folha de estilo do documento, incluindo :aftere :beforeestilos. O jQuery não fornece um atalho conveniente, mas felizmente o JS não é tão complicado:

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

.addRule()e os .insertRule()métodos relacionados são razoavelmente bem suportados hoje.

Como variação, você também pode usar o jQuery para adicionar uma folha de estilo totalmente nova ao documento, mas o código necessário não é mais limpo:

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

Se estamos falando de "manipular" os valores, não apenas acrescentar a eles, podemos também ler os existentes :afterou :beforeestilos que utilizam uma abordagem diferente:

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

Podemos substituir document.querySelector('p')com $('p')[0]ao usar jQuery, para o código ligeiramente mais curto.

  • Prós: qualquer string pode ser inserida dinamicamente no estilo
  • Contras: os estilos originais não são alterados, apenas substituídos; O uso repetido (ab) pode fazer o DOM crescer arbitrariamente grande

3) Alterar um atributo DOM diferente

Você também pode usar attr()em seu CSS para ler um atributo DOM específico. ( Se um navegador suporta :before, ele também suporta attr(). ) Ao combinar isso com content:algumas CSS cuidadosamente preparadas, podemos alterar o conteúdo (mas não outras propriedades, como margem ou cor) :beforee :afterdinamicamente:

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

JS:

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

Isso pode ser combinado com a segunda técnica se o CSS não puder ser preparado com antecedência:

var str = "bar";

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

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

  • Prós: Não cria infinitos estilos extras
  • Contras: attr no CSS, só se aplica a cadeias de conteúdo, não a URLs ou cores RGB

2
Eu estou tentando definir dinamicamente os valores de glyphicon (ou seja, através de seus valores hexadecimais) em :: after psedo. content: elemento (por exemplo, content: "\ e043";). parece não funcionar para mim, então estou assumindo que também não funciona com valores hexadecimais para glyphicons?
— user2101068

@ user2101068 Você deve postar isso como uma nova pergunta. Eu teria que ver todo o código que você está usando.
— Blazemonger

Blazemonger, obrigado pela resposta rápida .. infelizmente existe um pouco de código e seria necessário um pouco de esforço para extrair o código relevante. Eu já passei mais de 12 horas tentando fazer esse trabalho e esse foi meu último esforço para fazê-lo funcionar. Eu preciso cortar minhas perdas. Eu esperava que você fosse capaz de apenas verificar minha suposição de valores re: hex ao usar a técnica descrita em # 3 acima (antes do snippet de código). Eu posso inserir uma string hexadecimal no elemento content, mas ele exibe o texto para o valor hexadecimal do glifo em vez do glifo real. Impressão sem ver todo o código?
— user2101068

1
@ user2101068 Não use a cadeia hexadecimal; em vez disso, copie e cole o caractere Unicode real no atributo HTML. jsfiddle.net/mblase75/Lcsjkc5y
— Blazemonger

em relação à solução 2. e 3. na verdade, você pode impedir que a folha de estilo cresça (mais) se você usar: document.styleSheets [0] .insertRule (regra, índice); em seguida, usando esse índice, você poderá remover as regras quando não for necessário: document. styleSheets [0] .deleteRule (index)
— Picard

158

Embora eles sejam renderizados pelos navegadores por CSS como se fossem outros elementos DOM reais, os pseudoelementos em si não fazem parte do DOM, porque os pseudoelementos, como o nome indica, não são elementos reais e, portanto, não é possível selecione e manipule-os diretamente com o jQuery (ou qualquer API JavaScript, nesse caso, nem mesmo a API Selectors ). Isso se aplica a quaisquer pseudoelementos cujos estilos você está tentando modificar com um script, e não apenas ::beforee ::after.

Você só pode acessar estilos de pseudo-elementos diretamente em tempo de execução, via CSSOM (think window.getComputedStyle()), que não é exposto pelo jQuery além .css(), um método que também não suporta pseudo-elementos.

Você sempre pode encontrar outras maneiras de contornar isso, por exemplo:

  • Aplicando os estilos aos pseudo-elementos de uma ou mais classes arbitrárias e alternando entre as classes (veja a resposta da seucolega para um exemplo rápido) - esta é a maneira idiomática, pois utiliza seletores simples (os quais os pseudo-elementos não são) distinguir entre elementos e estados de elementos, a maneira como eles devem ser usados

  • Manipular os estilos que estão sendo aplicados aos referidos pseudo-elementos, alterando a folha de estilo do documento, que é muito mais um truque


78

Você não pode selecionar pseudo elementos no jQuery porque eles não fazem parte do DOM. Mas você pode adicionar uma classe específica ao elemento pai e controlar seus pseudo elementos no CSS.

EXEMPLO

No jQuery:

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

Em CSS:

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

48

Também podemos confiar em propriedades personalizadas (também conhecidas como variáveis ​​CSS) para manipular o pseudo-elemento. Podemos ler na especificação que:

Propriedades personalizadas são propriedades comuns, portanto podem ser declaradas em qualquer elemento, são resolvidas com as regras normais de herança e cascata , podem ser condicionadas pelo @media e outras regras condicionais, podem ser usadas no atributo de estilo do HTML , podem ser lidas ou definidas usando o CSSOM etc.

Considerando isso, a idéia é definir a propriedade customizada dentro do elemento e o pseudoelemento simplesmente a herdará; assim podemos modificá-lo facilmente.

1) Usando estilo embutido :

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

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


Também pode ser usado com valores complexos:

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

Você pode perceber que estou considerando a sintaxe var(--c,value)onde valueestá o valor padrão e também chamado de valor de fallback.

Da mesma especificação, podemos ler:

O valor de uma propriedade customizada pode ser substituído no valor de outra propriedade com a função var (). A sintaxe de var () é:

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

O primeiro argumento para a função é o nome da propriedade customizada a ser substituída. O segundo argumento para a função, se fornecido, é um valor de fallback, usado como valor de substituição quando a propriedade customizada referenciada é inválida.

E depois:

Para substituir um var () no valor de uma propriedade:

  1. Se a propriedade customizada nomeada pelo primeiro argumento para a var()função estiver contaminada por animação e a var()função estiver sendo usada na propriedade de animação ou em uma de suas longhands, trate a propriedade customizada como tendo seu valor inicial para o restante deste algoritmo.
  2. Se o valor da propriedade customizada nomeada pelo primeiro argumento da var()função for qualquer coisa menos o valor inicial, substitua a var()função pelo valor da propriedade customizada correspondente.
  3. Caso contrário, se a var()função tiver um valor de fallback como seu segundo argumento, substitua a var()função pelo valor de fallback. Se houver alguma var()referência no fallback, substitua-a também.
  4. Caso contrário, a propriedade que contém a var()função é inválida no tempo do valor calculado.

Se não definirmos a propriedade customizada OU, definimos como initialOU ele contém um valor inválido, o valor de fallback será usado. O uso de initialpode ser útil caso desejemos redefinir uma propriedade customizada para seu valor padrão.

Relacionado

Como armazenar valor herdado dentro de uma propriedade customizada CSS (também conhecida como variáveis ​​CSS)?

Propriedades customizadas de CSS (variáveis) para modelo de caixa


Observe que as variáveis ​​CSS podem não estar disponíveis em todos os navegadores que você considera relevantes (por exemplo, IE 11): https://caniuse.com/#feat=css-variables


@akalata sim, o código requer uma versão 3.x jQuery .. eu adicionei mais detalhes e uma outra alternativa com jQuery;)
— temanitas Afif

Como isso funcionaria no IE 11?
— Connex 6/09

1
@connexo como qualquer bom e funcionalidade moderna .. não é suportado e não vai funcionar caniuse.com/#feat=css-variables
— temanitas Afif

Ofc eu sabia disso e como o IE 11 ainda é muito relevante, perdi essa informação diretamente na parte introdutória da sua resposta.
— Connex6 /

1
Esta resposta é um tutorial detalhado de como relacionar e modificar pseudoelementos com JavaScript usando variáveis ​​CSS. Muito obrigado pelo seu tempo e por compartilhar esta (s) técnica (s) extremamente valiosa (s).
— LebCit 19/07/19

37

Na linha do que Christian sugere, você também pode fazer:

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

2
Aqui deve ser adicionado um atributo id, para que o elemento possa ser selecionado e excluído antes que um novo seja adicionado. Caso contrário, podem surgir muitos nós de estilo desnecessários.
— KS

24

Aqui está o caminho para acessar: after e: before propriedades de estilo, definidas em 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');

11

Se você quiser manipular os elementos sudo :: before ou :: after inteiramente por meio do CSS, poderá fazê-lo JS. Ver abaixo;

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

Observe como o <style>elemento possui um ID, que você pode usar para removê-lo e anexá-lo novamente se o seu estilo mudar dinamicamente.

Dessa forma, seu elemento tem o estilo exatamente como você deseja através do CSS, com a ajuda de JS.


6

Uma maneira funcional, mas não muito eficiente, é adicionar uma regra ao documento com o novo conteúdo e referenciá-lo com uma classe. dependendo do necessário, a classe pode precisar de um ID exclusivo para cada valor no conteúdo.

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

5

Aqui está o HTML:

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

O estilo computado em 'antes' foi content: "VERIFY TO WATCH";

Aqui estão minhas duas linhas de jQuery, que usam a idéia de adicionar uma classe extra para referenciar especificamente esse elemento e, em seguida, anexar uma marca de estilo (com uma marca! Important) para alterar o CSS do valor do conteúdo do elemento sudo:

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

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


5

Obrigado a todos! eu consegui fazer o que eu queria: D http://jsfiddle.net/Tfc9j/42/ aqui, dê uma olhada

eu queria que a opacidade de uma div externa fosse diferente da opacidade da div interna e que mudasse com um clique em algum lugar;) Obrigado!

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

Não tente append, o htmlmelhor uso é evitar
— KingRider

1
Cuidado: aqui você anexa uma tag de estilo à cabeça toda vez que um desses cliques é manipulado. Eu codificaria uma maneira de remover a antiga antes de adicionar uma nova.
— pupitetris

3

Você pode criar uma propriedade falsa ou usar uma existente e herdá- la na folha de estilo do pseudo-elemento.

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 não funciona para a propriedade "content" :(


3

Isso não é prático, pois eu não escrevi isso para usos no mundo real, apenas para dar um exemplo do que pode ser alcançado.

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

atualmente, este add é um / ou anexa um elemento Style que contém os atributos necessários, que terão efeito nos elementos alvo após o Pseudo elemento.

isso pode ser usado como

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

e

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

como depois: e antes: pseudoelementos não são acessíveis diretamente através do DOM, atualmente não é possível editar os valores específicos do css livremente.

do meu jeito era apenas um exemplo e não é bom para a prática, você pode modificá-lo, experimentar alguns de seus próprios truques e corrigi-lo para o uso no mundo real.

assim como suas próprias experiências com isso e com outros!

cumprimentos - Adarsh ​​Hegde.


3

Estou sempre adicionando minha própria função de utilitários, que se parece com isso.

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

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

ou faça uso dos recursos do ES6:

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

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

2

Por que adicionar classes ou atributos quando você pode simplesmente adicionar um styleà cabeça

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

2

Há muitas respostas aqui, mas nenhuma resposta ajuda a manipular o css :beforeou :after, nem mesmo o aceito.

Aqui está como eu proponho fazê-lo. Vamos supor que seu HTML seja assim:

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

E então você está configurando seu: before em CSS e projetando-o como:

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

Observe também que eu defino o contentatributo no próprio elemento para que você possa removê-lo facilmente mais tarde. Agora há um buttonclique no qual você deseja alterar a cor de: before para verde e o tamanho da fonte para 30px. Você pode conseguir isso da seguinte maneira:

Defina um css com o estilo necessário em alguma classe .activeS:

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

Agora você pode alterar o estilo: before adicionando a classe ao seu: before elemento da seguinte maneira:

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

Se você deseja apenas obter conteúdo :before, isso pode ser feito da seguinte forma:

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

Por fim, se você deseja alterar dinamicamente o :beforeconteúdo pelo jQuery, é possível fazer o seguinte:

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

Clicar no botão "changeBefore" acima mudará o :beforeconteúdo #somethingpara '22', que é um valor dinâmico.

Espero que ajude


1

Usei variáveis ​​definidas :rootdentro CSSpara modificar o pseudo-elemento:after (o mesmo se aplica a :before) , em particular para alterar o valor de um estilo definido por e o valor de outro ( ) na demonstração a seguir que gera cores aleatórias usando JavaScript / jQuery:background-coloranchor.sliding-middle-out:hover:aftercontentanchor#reference

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

O suporte para attr()exceto em content, é realmente escasso. Você pode consultar o site caniuse.com. :roote o suporte a variáveis ​​css é melhor, mas ainda não é tão amplo, pois o suporte é bastante novo. (verifique, também, suporte para ele no caniuse.com)
— BananaAcid

1

Eu criei um plugin jQuery para adicionar regras css-pseudo, como usar .css()para elementos específicos.

  • o código do plug-in e o caso de teste estão aqui
  • caso de uso como imagem pop-up css simples aqui

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

0

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


0

Você pode usar meu plugin para esse fim.

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>

Os valores devem ser especificados, como na função normal do jQuery.css

Além disso, você também pode obter o valor do parâmetro pseudoelemento, como na função normal do jQuery.css:

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

JS:


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


0

Alguém comentou sobre o acréscimo ao elemento head com um elemento de estilo completo e isso não é ruim se você estiver fazendo isso apenas uma vez, mas se precisar redefini-lo mais de uma vez, você terá uma tonelada de elementos de estilo. Portanto, para impedir que eu criei um elemento de estilo em branco na cabeça com um id e substitua oHTML interno assim:

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

Em seguida, o JavaScript ficaria assim:

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

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

setHeight()

Agora, no meu caso, eu precisava disso para definir a altura de um elemento anterior com base na altura de outro e ele será alterado no redimensionamento, portanto, usando isso, eu posso executar setHeight()toda vez que a janela for redimensionada e substituirá <style>corretamente.

Espero que ajude alguém que estava preso tentando fazer a mesma coisa.


-1

Tenho algo diferente para você que é fácil e eficaz.

    <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');
    });
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.