Sélection et manipulation de pseudo-éléments CSS tels que :: avant et :: après à l'aide de jQuery

943

Existe-t-il un moyen de sélectionner / manipuler des pseudo-éléments CSS tels que ::beforeet ::after(et l'ancienne version avec un point-virgule) en utilisant jQuery?

Par exemple, ma feuille de style a la règle suivante:

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

Comment puis-je changer 'foo' en 'bar' en utilisant jQuery?

JBradwell
la source
4
J'ai créé quelque chose qui devrait fonctionner pour vous: gist.github.com/yckart/5563717
yckart
1
Je déteste de tels commentaires sur stackoverflow que je vais écrire (où le commentateur demande pourquoi ne le faites-vous pas de manière complètement opposée? ), Mais: à un moment donné, il faut réaliser un problème de conception de code et remplacer ce pseudo-élément par un durée ou quelque chose. Je suppose que vous savez de quoi je parle.
zsitro
1
La réponse acceptée est excellente. Bien que si vous essayez d'atteindre l'un des points suivants, la réponse ne fonctionnera pas: 1. changer le style de: avant par JS. 2. changer le contenu de: avant par JS Veuillez voir ma réponse pour cela si vous en avez besoin.
Apprenant
@Learner Maintenant, il y a une réponse à tout cela: stackoverflow.com/a/49618941/8620333
Temani Afif

Réponses:

695

Vous pouvez également transmettre le contenu au pseudo-élément avec un attribut de données, puis utiliser jQuery pour manipuler cela:

En HTML:

<span>foo</span>

Dans jQuery:

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

En CSS:

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

Si vous souhaitez empêcher l'affichage de «l'autre texte», vous pouvez combiner cela avec la solution de seucolega comme ceci:

En HTML:

<span>foo</span>

Dans 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';
}
Nick Kline
la source
2
Avez-vous un lien dans la spécification pour utiliser cette attrfonction contre la contentpropriété? Je suis surpris de n'avoir jamais entendu parler de ça ...
Kevin Peno
95
+1 pour attr(), dommage que je n'ai pas pu l'utiliser avec d'autres propriétés que content. Démo
Maksim Vi.
28
C'est parce qu'aucun navigateur existant n'a encore été implémenté attr()au-delà de CSS2, alors que dans CSS2 lui-même attr()n'a été défini que pour la contentpropriété.
BoltClock
10
Lien mis à jour pour les références d'attribut: w3.org/TR/css3-values/#attr-notation
477

Vous penseriez que ce serait une question simple à répondre, avec tout le reste que jQuery peut faire. Malheureusement, le problème se résume à un problème technique: les règles css: after et: before ne font pas partie du DOM et ne peuvent donc pas être modifiées à l'aide des méthodes DOM de jQuery.

Il existe des moyens de manipuler ces éléments à l'aide de solutions de contournement JavaScript et / ou CSS; lequel vous utilisez dépend de vos besoins exacts.


Je vais commencer par ce qui est largement considéré comme la "meilleure" approche:

1) Ajouter / supprimer une classe prédéterminée

Dans cette approche, vous avez déjà créé une classe dans votre CSS avec un autre :afterou de :beforestyle. Placez cette "nouvelle" classe plus tard dans votre feuille de style pour vous assurer qu'elle remplace:

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

Ensuite, vous pouvez facilement ajouter ou supprimer cette classe en utilisant jQuery (ou JavaScript vanilla):

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

  • Avantages: Facile à implémenter avec jQuery; modifie rapidement plusieurs styles à la fois; impose la séparation des préoccupations (isoler votre CSS et JS de votre HTML)
  • Inconvénients: CSS doit être pré-écrit, donc le contenu de :beforeou :aftern'est pas complètement dynamique

2) Ajoutez de nouveaux styles directement à la feuille de style du document

Il est possible d'utiliser JavaScript pour ajouter des styles directement à la feuille de style du document, y compris les styles :afteret :before. jQuery ne fournit pas de raccourci pratique, mais heureusement, le JS n'est pas si compliqué:

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

.addRule()et les .insertRule()méthodes associées sont assez bien supportées aujourd'hui.

En variante, vous pouvez également utiliser jQuery pour ajouter une nouvelle feuille de style au document, mais le code nécessaire n'est pas plus propre:

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

Si nous parlons de "manipuler" les valeurs, pas seulement de les ajouter, nous pouvons également lire les styles existants :afterou en:before utilisant une approche différente:

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

Nous pouvons remplacer document.querySelector('p')par $('p')[0]lors de l'utilisation de jQuery, pour un code légèrement plus court.

  • Avantages: n'importe quelle chaîne peut être insérée dynamiquement dans le style
  • Inconvénients: les styles originaux ne sont pas modifiés, juste remplacés; l'utilisation répétée (ab) peut faire augmenter arbitrairement le DOM

3) Modifier un attribut DOM différent

Vous pouvez également utiliser attr()dans votre CSS pour lire un attribut DOM particulier. ( Si un navigateur prend en charge :before, il le prend attr()également en charge . ) En combinant cela avec content:du CSS soigneusement préparé, nous pouvons changer le contenu (mais pas d'autres propriétés, comme la marge ou la couleur) :beforeet :afterdynamiquement:

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

JS:

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

Cela peut être combiné avec la deuxième technique si le CSS ne peut pas être préparé à l'avance:

var str = "bar";

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

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

  • Avantages: ne crée pas de styles supplémentaires sans fin
  • Inconvénients: attr en CSS ne peut s'appliquer qu'aux chaînes de contenu, pas aux URL ou aux couleurs RVB
Blazemonger
la source
2
J'essaie de définir dynamiquement les valeurs de glyphicon (c'est-à-dire via leurs valeurs hexadécimales) dans :: after psedo. contenu: élément (par exemple, contenu: "\ e043";). cela ne semble pas fonctionner pour moi, donc je suppose que cela ne fonctionne pas non plus pour les valeurs hexadécimales pour les glyphicons?
user2101068
@ user2101068 Vous devez poster cela comme une nouvelle question. Je devrais voir tout le code que vous utilisez.
Blazemonger
Blazemonger, merci pour la réponse rapide ... malheureusement, il y a pas mal de code et il faudrait pas mal d'efforts pour extraire le code correspondant. J'ai déjà passé plus de 12 heures à essayer d'obtenir ce travail et ce fut mon dernier effort haletant pour le faire fonctionner. Je dois réduire mes pertes. J'espérais que vous pourriez simplement vérifier mon hypothèse concernant les valeurs hexadécimales lors de l'utilisation de la technique décrite au point 3 ci-dessus (avant l'extrait de code). Je peux insérer une chaîne hexadécimale dans l'élément de contenu, mais il affiche le texte de la valeur hexadécimale du glyphicon plutôt que le glyphicon réel. Impression sans voir tout le code?
user2101068
1
@ user2101068 N'utilisez pas la chaîne hexadécimale; à la place, copiez et collez le caractère Unicode réel dans l'attribut HTML. jsfiddle.net/mblase75/Lcsjkc5y
Blazemonger
en ce qui concerne les solutions 2. et 3. en fait, vous pouvez empêcher la croissance (excessive) de la feuille de style si vous utilisez: document.styleSheets [0] .insertRule (règle, index), puis en utilisant cet index, vous pouvez supprimer les règles lorsque vous n'en avez pas besoin: document. styleSheets [0] .deleteRule (index)
Picard
158

Bien qu'ils soient rendus par les navigateurs via CSS comme s'ils étaient comme d'autres éléments DOM réels, les pseudo-éléments eux-mêmes ne font pas partie du DOM, car les pseudo-éléments, comme leur nom l'indique, ne sont pas de vrais éléments, et donc vous ne pouvez pas sélectionnez-les et manipulez-les directement avec jQuery (ou n'importe quelle API JavaScript d'ailleurs, pas même l' API Selectors ). Cela s'applique à tous les pseudo-éléments dont vous essayez de modifier les styles avec un script, et pas seulement ::beforeet ::after.

Vous pouvez uniquement accéder aux styles de pseudo-éléments directement à l'exécution via le CSSOM (think window.getComputedStyle()), qui n'est pas exposé par jQuery au .css()- delà , une méthode qui ne prend pas en charge les pseudo-éléments non plus.

Vous pouvez toujours trouver d'autres moyens de le contourner, par exemple:

  • Appliquer les styles aux pseudo-éléments d'une ou plusieurs classes arbitraires, puis basculer entre les classes (voir la réponse de seucolega pour un exemple rapide) - c'est la manière idiomatique car elle utilise des sélecteurs simples (qui ne sont pas des pseudo-éléments) pour faire la distinction entre les éléments et les états des éléments, la façon dont ils sont destinés à être utilisés

  • Manipuler les styles appliqués auxdits pseudo-éléments, en modifiant la feuille de style du document, ce qui est beaucoup plus un hack

BoltClock
la source
78

Vous ne pouvez pas sélectionner de pseudo-éléments dans jQuery car ils ne font pas partie du DOM. Mais vous pouvez ajouter une classe spécifique à l'élément père et contrôler ses pseudo-éléments en CSS.

EXEMPLE

Dans jQuery:

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

En CSS:

span.change:after { content: 'bar' }
Gustavo Sousa
la source
48

Nous pouvons également compter sur des propriétés personnalisées (alias variables CSS) afin de manipuler le pseudo-élément. On peut lire dans la spécification que:

Les propriétés personnalisées sont des propriétés ordinaires, elles peuvent donc être déclarées sur n'importe quel élément, résolues avec les règles d' héritage et de cascade normales , peuvent être conditionnées avec @media et d'autres règles conditionnelles, peuvent être utilisées dans l'attribut de style HTML , peuvent être lues ou définies en utilisant le CSSOM , etc.

Compte tenu de cela, l'idée est de définir la propriété personnalisée au sein de l'élément et le pseudo-élément en héritera simplement; ainsi nous pouvons facilement le modifier.

1) Utilisation du style en ligne :

.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) Utilisation de CSS et de 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) Utilisation de 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) Utilisation de 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>


Il peut également être utilisé avec des valeurs complexes:

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

Vous remarquerez peut-être que je considère la syntaxe var(--c,value)valueest la valeur par défaut et également appelée la valeur de secours.

De la même spécification, nous pouvons lire:

La valeur d'une propriété personnalisée peut être remplacée par la valeur d'une autre propriété avec la fonction var (). La syntaxe de var () est:

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

Le premier argument de la fonction est le nom de la propriété personnalisée à remplacer. Le deuxième argument de la fonction, s'il est fourni, est une valeur de secours, qui est utilisée comme valeur de substitution lorsque la propriété personnalisée référencée n'est pas valide.

Et ensuite:

Pour remplacer un var () dans la valeur d'une propriété:

  1. Si la propriété personnalisée nommée par le premier argument de la var()fonction est entachée d'animation et que la var()fonction est utilisée dans la propriété d'animation ou l'un de ses raccourcis, traitez la propriété personnalisée comme ayant sa valeur initiale pour le reste de cet algorithme.
  2. Si la valeur de la propriété personnalisée nommée par le premier argument de la var()fonction est tout sauf la valeur initiale, remplacez la var()fonction par la valeur de la propriété personnalisée correspondante.
  3. Sinon, si la var()fonction a une valeur de secours comme deuxième argument, remplacez la var()fonction par la valeur de secours. S'il existe des var()références dans la solution de secours, remplacez-les également.
  4. Sinon, la propriété contenant la var()fonction n'est pas valide au moment de la valeur calculée.

Si nous ne définissons pas la propriété personnalisée OU nous la définissons sur initialOU elle contient une valeur non valide, la valeur de secours sera utilisée. L'utilisation de initialpeut être utile si nous voulons réinitialiser une propriété personnalisée à sa valeur par défaut.

en relation

Comment stocker la valeur héritée à l'intérieur d'une propriété personnalisée CSS (alias variables CSS)?

Propriétés personnalisées CSS (variables) pour le modèle de boîte


Veuillez noter que les variables CSS peuvent ne pas être disponibles dans tous les navigateurs que vous jugez pertinents (par exemple IE 11): https://caniuse.com/#feat=css-variables

Temani Afif
la source
@akalata oui, le code nécessite une version 3.x de jQuery. J'ai ajouté plus de détails et une autre alternative avec jQuery;)
Temani Afif
Comment cela fonctionnerait-il dans IE 11?
connexo
1
@connexo comme n'importe quelle fonctionnalité bonne et moderne .. elle n'est pas prise en charge et ne fonctionnera pas caniuse.com/#feat=css-variables
Temani Afif
Bien sûr, je le savais et comme IE 11 est toujours très pertinent, j'ai raté cette information dans la partie introductive de votre réponse.
connexo
1
Cette réponse est un didacticiel détaillé sur la mise en relation et la modification de pseudo-éléments avec JavaScript à l'aide de variables CSS. Merci beaucoup pour votre temps et pour le partage de cette technique extrêmement précieuse.
LebCit
37

Dans la lignée de ce que suggère Christian, vous pourriez également faire:

$('head').append("<style>.span::after{ content:'bar' }</style>");
Ivan Chaer
la source
2
Ici devrait être ajouté un attribut id, afin que l'élément puisse être sélectionné et supprimé avant qu'un nouveau ne soit ajouté. Sinon, il peut y avoir beaucoup de nœuds de style inutiles.
KS
24

Voici comment accéder aux propriétés de style: after et: before, définies dans 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
la source
11

SI vous voulez manipuler entièrement les éléments sudo :: before ou :: after via CSS, vous pouvez le faire JS. Voir ci-dessous;

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

Remarquez comment l' <style>élément a un ID, que vous pouvez utiliser pour le supprimer et l'ajouter à nouveau si votre style change dynamiquement.

De cette façon, votre élément est un style exactement comme vous le souhaitez via CSS, avec l'aide de JS.


la source
6

une manière efficace mais pas très efficace consiste à ajouter une règle au document avec le nouveau contenu et à la référencer avec une classe. en fonction de ce qui est nécessaire, la classe peut avoir besoin d'un identifiant unique pour chaque valeur de contenu.

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

Voici le HTML:

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

Le style calculé sur «avant» était content: "VERIFY TO WATCH";

Voici mes deux lignes de jQuery, qui utilisent l'idée d'ajouter une classe supplémentaire pour référencer spécifiquement cet élément, puis d'ajouter une balise de style (avec une balise! Important) pour changer le CSS de la valeur de contenu de l'élément sudo:

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

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

Coyote
la source
5

Merci à tous! j'ai réussi à faire ce que je voulais: D http://jsfiddle.net/Tfc9j/42/ ici jetez un oeil

je voulais que l'opacité d'un div externe soit différente de l'opacité du div interne et que ça change d'un clic quelque part;) Merci!

   $('#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
la source
N'essayez pas append, il htmlvaut mieux éviter
KingRider
1
Attention: ici, vous ajoutez une balise de style à la tête chaque fois qu'un de ces clics est traité. Je coderais un moyen de supprimer l'ancien avant d'en ajouter un nouveau.
pupitetris
3

Vous pouvez créer une fausse propriété ou utiliser une propriété existante et l' hériter dans la feuille de style du pseudo-élément.

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>

Il semble que cela ne fonctionne pas pour la propriété "content" :(

Alexander Shutau
la source
3

Ce n'est pas pratique car je n'ai pas écrit ceci pour des utilisations réelles, juste pour vous donner un exemple de ce qui peut être réalisé.

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

cet ajout actuel a / ou ajoute un élément Style qui contient vos attributs nécessaires qui prendront effet sur l'élément cible après l'élément Pseudo.

cela peut être utilisé comme

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

et

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

comme après: et avant: les pseudo-éléments ne sont pas directement accessibles via DOM il n'est actuellement pas possible d'éditer librement les valeurs spécifiques du css.

ma façon n'était qu'un exemple et ce n'est pas bon pour la pratique, vous pouvez le modifier essayer quelques-unes de vos propres astuces et le rendre correct pour une utilisation réelle.

faites ainsi votre propre expérimentation avec ceci et d'autres!

salutations - Adarsh ​​Hegde.

Adarsh ​​Hegde
la source
3

J'ajoute toujours ma propre fonction utils, qui ressemble à ceci.

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

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

ou utilisez les fonctionnalités ES6:

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

setPseudoElContent('.class::after', 'Hello World!');
Orlandster
la source
2

Pourquoi ajouter des classes ou des attributs lorsque vous pouvez simplement ajouter un styleà la tête

$('head').append('<style>.span:after{ content:'changed content' }</style>')
Gaurav Aggarwal
la source
2

Il existe de nombreuses réponses ici, mais aucune réponse ne permet de manipuler le CSS de :beforeou:after , même pas celui qui est accepté.

Voici comment je propose de le faire. Supposons que votre HTML soit comme ceci:

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

Et puis vous définissez son: avant en CSS et le concevez comme:

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

Veuillez noter que j'ai également défini l' contentattribut dans l'élément lui-même afin que vous puissiez le retirer facilement plus tard. Il y a maintenant unbutton clic sur lequel, vous voulez changer la couleur de: avant en vert et sa taille de police en 30 px. Vous pouvez y parvenir comme suit:

Définissez un CSS avec votre style requis sur une classe .activeS:

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

Vous pouvez maintenant modifier le style: avant en ajoutant la classe à votre élément: avant comme suit:

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

Si vous voulez simplement obtenir du contenu :before, cela peut être fait comme:

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

En fin de compte, si vous souhaitez modifier dynamiquement le :beforecontenu par jQuery, vous pouvez y parvenir comme suit:

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

Cliquer sur le bouton "changeBefore" ci-dessus changera le :beforecontenu de #something"22" qui est une valeur dynamique.

J'espère que ça aide

Apprenant
la source
1

J'ai utilisé des variables définies à l' :rootintérieur CSSpour modifier le :after(le même s'applique à :before) pseudo-élément , en particulier pour changer la background-colorvaleur d'un style anchordéfini par .sliding-middle-out:hover:afteret la contentvaleur d'un autre anchor( #reference) dans la démo suivante qui génère des couleurs aléatoires en utilisant JavaScript / jQuery:

HTML

<a href="#" id="changeColor" class="sliding-middle-out" title="Generate a random color">Change link color</a>
<span id="log"></span>
<h6>
  <a href="https://stackoverflow.com/a/52360188/2149425" id="reference" class="sliding-middle-out" target="_blank" title="Stack Overflow topic">Reference</a>
</h6>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript" src="https://cdn.rawgit.com/davidmerfield/randomColor/master/randomColor.js"></script>

CSS

:root {
    --anchorsFg: #0DAFA4;
}
a, a:visited, a:focus, a:active {
    text-decoration: none;
    color: var(--anchorsFg);
    outline: 0;
    font-style: italic;

    -webkit-transition: color 250ms ease-in-out;
    -moz-transition: color 250ms ease-in-out;
    -ms-transition: color 250ms ease-in-out;
    -o-transition: color 250ms ease-in-out;
    transition: color 250ms ease-in-out;
}
.sliding-middle-out {
    display: inline-block;
    position: relative;
    padding-bottom: 1px;
}
.sliding-middle-out:after {
    content: '';
    display: block;
    margin: auto;
    height: 1px;
    width: 0px;
    background-color: transparent;

    -webkit-transition: width 250ms ease-in-out, background-color 250ms ease-in-out;
    -moz-transition: width 250ms ease-in-out, background-color 250ms ease-in-out;
    -ms-transition: width 250ms ease-in-out, background-color 250ms ease-in-out;
    -o-transition: width 250ms ease-in-out, background-color 250ms ease-in-out;
    transition: width 250ms ease-in-out, background-color 250ms ease-in-out;
}
.sliding-middle-out:hover:after {
    width: 100%;
    background-color: var(--anchorsFg);
    outline: 0;
}
#reference {
  margin-top: 20px;
}
.sliding-middle-out:before {
  content: attr(data-content);
  display: attr(data-display);
}

JS / jQuery

var anchorsFg = randomColor();
$( ".sliding-middle-out" ).hover(function(){
    $( ":root" ).css({"--anchorsFg" : anchorsFg});
});

$( "#reference" ).hover(
 function(){
    $(this).attr("data-content", "Hello World!").attr("data-display", "block").html("");
 },
 function(){
    $(this).attr("data-content", "Reference").attr("data-display", "inline").html("");
 }
);
Riccardo Volpe
la source
Le support pour attr()except in content, est vraiment rare. Vous pouvez consulter caniuse.com pour cela. :rootet la prise en charge des variables css est meilleure, mais pas encore si répandue, car la prise en charge est assez récente. (consultez également le support sur caniuse.com)
BananaAcid
1

J'ai créé un plugin jQuery pour ajouter des règles css-pseudo comme l'utilisation .css()pour des éléments spécifiques.

  • le code du plugin et le cas de test est ici
  • cas d'utilisation comme simple popup d'image css ici

usage:

$('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
la source
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
la source
0

Vous pouvez utiliser mon plugin à cet effet.

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>

Les valeurs doivent être spécifiées, comme dans la fonction normale de jQuery.css

De plus, vous pouvez également obtenir la valeur du paramètre pseudo-élément, comme dans la fonction normale de jQuery.css:

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

JS:


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

Yuri
la source
0

Quelqu'un d'autre a commenté l'ajout à l'élément head avec un élément de style complet et ce n'est pas mal si vous ne le faites qu'une seule fois, mais si vous devez le réinitialiser plus d'une fois, vous vous retrouverez avec une tonne d'éléments de style. Donc, pour éviter que j'ai créé un élément de style vide dans la tête avec un identifiant et remplacez le innerHTML de celui-ci comme ceci:

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

Ensuite, le JavaScript ressemblerait à ceci:

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

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

setHeight()

Maintenant, dans mon cas, j'avais besoin de cela pour définir la hauteur d'un élément avant en fonction de la hauteur d'un autre et il changera lors du redimensionnement.En utilisant cela, je peux exécuter setHeight()chaque fois que la fenêtre est redimensionnée et il remplacera <style>correctement.

J'espère que cela aide quelqu'un qui était coincé à essayer de faire la même chose.

zfb
la source
-1

J'ai quelque chose de différent pour vous, simple et efficace.

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