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?

JBradwell
fonte
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';
}
Nick Kline
fonte
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
Blazemonger
fonte
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

BoltClock
fonte
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' }
Gustavo Sousa
fonte
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

Temani Afif
fonte
@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>");
Ivan Chaer
fonte
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');
Nedudi
fonte
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.


fonte
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');
cristão
fonte
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>");

Coiote
fonte
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>
aimiliano
fonte
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" :(

Alexander Shutau
fonte
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.

Adarsh ​​Hegde
fonte
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!');
Orlandster
fonte
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>')
Gaurav Aggarwal
fonte
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

Aprendiz
fonte
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("");
 }
);
Riccardo Volpe
fonte
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!"'
  });
BananaAcid
fonte
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>

Tariq Javed
fonte
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/

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

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