53 votes

Obliger IE8 à rendre/peindre les pseudo-éléments :before/:after

Alors j'ai joué avec ce calendrier depuis un moment :

  • Grille de divs (imitation d'un tableau)
  • Le survol d'une cellule de tableau affiche une infobulle avec 2 icônes, chacune consistant en un div avec des éléments :before et :after.
  • Les icônes changent de couleur en fonction de la couleur de la cellule survolée et de celle de sa sœur précédente (la classe de couleur de la cellule est appliquée à l'icône).

Un violon démonté : http://jsfiddle.net/e9PkA/1/

Cela fonctionne bien dans tous les navigateurs sauf IE8 et moins (IE lte 7 et je ne l'aimerai jamais, mais IE8 serait agréable à avoir).

IE8 remarque le changement des noms de classe et met à jour la couleur des divs en conséquence, mais ignore complètement les changements de couleur impliqués par les déclarations :before et :after, par exemple :

.wbscal_icon_arrival:before {
    width: 12px;
    height: 4px;

    left: -8px;
    top: 6px;
    background-color: silver;
}

.wbscal_icon_arrival.wbscal_full:before {
    background-color: #ff0000 !important; 
}

Dans l'exemple ci-dessus, les éléments :before/:after sont colorés une seule fois : la première fois que l'infobulle est affichée.

Dans une autre version, elle se mettait à jour chaque fois que je déplaçais la souris hors de la division "table", mais pas si l'info-bulle est masquée lors du survol d'une bordure de division "cell".

J'ai essayé de forcer le déclenchement des repeints en ajoutant/supprimant d'autres classes à/de l'élément/de ses parents/du corps, en modifiant/accédant aux attributs de style et autres, donc je suppose que ce n'est pas un problème de repeint ordinaire.

Existe-t-il un hack JS qui corrige ce problème et qui force la mise à jour de :before/:after ?

131voto

lnrbob Points 8061

J'ai essayé de comprendre la même chose. En fait, IE8 ne redessine pas les pseudo-éléments à moins que vous n'apportiez un changement au contenu. J'ai donc modifié votre exemple ici (seulement CSS) : http://jsfiddle.net/lnrb0b/VWhv9/ . J'ai ajouté width:0 y overflow:hidden aux pseudo-éléments et a ensuite ajouté content:"x" à chaque option de couleur où x est un nombre incrémentiel d'espaces.

Cela fonctionne pour moi ; j'espère que cela vous aidera !

4 votes

Je suis à la fois choqué et étonné. Merci.

0 votes

Pas d'inquiétude - c'est assez bizarre !

6 votes

Pour ceux qui sont encore un peu confus -- vous devrez probablement ajouter un contenu : ' ' ; à chacune de vos déclarations, en veillant à ce que le nombre d'espaces soit différent pour les différents états d'un même élément.

2voto

Vinny Points 21

Ajout de content:"x" à chaque déclaration des psuedo-éléments et en incrémentant le nombre d'espaces pour chaque état différent de l'élément, cela résout DÉFINITIVEMENT le problème.

En gros, l'idée est de dire à IE8 que le contenu est légèrement différent dans chaque état, donc de redessiner le contenu pour chaque état. Ainsi, si le contenu est le même, nous le "simulons" avec des espaces vides. BRILLIANT !

1voto

Guntram Points 71

@lnrbob très belle réponse ! !!

J'ai rencontré le problème suivant : j'ai utilisé les pseudos avant et après d'une entrée de type checkbox, qui utilisent certains attributs parentaux pour afficher leur contenu (parce qu'il est facile d'y implémenter une traduction).

pour qu'ils ressemblent :

input:before {
    content: "" attr(data-on) "";
}

input:after {
    content: "" attr(data-off) "";
}

et le balisage ressemble à ça :

<div class="switch off" data-on="It is ON" data-off="It is OFF">
    <input id="switch" name="switch" type="checkbox" class="off">
</div>

et la modification que je fais dans jquery ressemble à ceci :

var mSwitch = $('div.switch'),
    on = $.trim(mSwitch.attr('data-on')),
    off = $.trim(mSwitch.attr('data-off'));
// remove any spaces due to trim
mSwitch .attr('data-on', on);
// add a space
mSwitch .attr('data-on', on + ' ');
mSwitch .attr('data-off', off);
mSwitch .attr('data-off', off + ' ');

et j'appelle cette modification après avoir mis/enlevé des classes pour changer le style de la "checkbox" qui est plutôt un bouton de commutation dans ce cas :D

de cette façon, vous n'aurez pas de débordement de pile à cause d'un trop grand nombre de caractères d'espace si certains testeurs hardcore cliquent automatiquement sur l'entrée pendant un temps infini ;)

comme ça :

<div class="switch on" data-on="ON" data-off="OFF                                                                                                                                                                                                                                                 ">

0voto

Sky Yip Points 777

En fait, IE8 ne redessine pas les pseudo-éléments à moins que vous ne modifiiez le contenu, ce qui vous permet de les modifier comme ci-dessous :

.wbscal_icon_arrival:before {
    width: 12px;
    height: 4px;
    left: -8px;
    top: 6px;
    background-color: silver;
    content: '';
}

.active .wbscal_icon_arrival:before {
    background-color: gold;
    content: ' ';
}

0voto

Manuel Graf Points 146

J'ai un problème similaire dans IE11 et Edge en ce moment.

au survol, j'essaie de changer le contenu de 'v' en 'V'. => Ne fonctionne sur aucun navigateur Microsoft.

Cependant, si je change la lettre en quelque chose d'autre ('w'/'W') ou en deux lettres ('vV'), l'icône change. Yay Microsoft.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X