web-dev-qa-db-fra.com

Transformation CSS3 provoquant un scintillement du texte dans Safari et Firefox Mac Yosemite

Je rencontre un problème étrange sur Safari et Firefox (Mac/Yosemite) qui fait scintiller presque tout le texte de la page lors du survol de l’élément de transformation.

Exemple gif: (Firefox, Yosemite)

enter image description here

.usp {
   //USP has an icon that is defined below
    opacity: .4;
    @include transition(all .3s ease-in-out);


    &:hover { 
        opacity: 1;
        @include transition(all .3s ease-in-out);


        .icon {
            @include transform(scale(1.1));
            @include transition(all 1.7s ease-in-out);
        }
    } // :hover
} 

.usp .icon {
    display: block;
    height: 75px;
    width: 75px;
    // Insert background-image Sprite (removed from this example)
    @include transition(all .3s ease-in-out); 
    @include transform(scale(1.0));
}

J'ai essayé les choses suivantes:

Ajoutez toutes les combinaisons possibles de ces styles au corps, à l’élément transformant et/ou à son parent

-webkit-transform-style:preserve-3d;
-webkit-backface-visibility: hidden;
-moz-backface-visibility: hidden;
-ms-backface-visibility: hidden;
 backface-visibility: hidden;
-webkit-filter: opacity(.9999);
-webkit-font-smoothing: antialiased;
-webkit-transform: translate3d(0, 0, 0);
-moz-transform: translate3d(0, 0, 0);
-webkit-transform: translate3d(0, 0, 0);
 transform: translate3d(0, 0, 0);
-webkit-font-smoothing: subpixel-antialiased;
-webkit-text-stroke: 0.35px;

Si (les styles ci-dessous) sont appliqués au corps, le problème est résolu dans Safari mais pas dans Firefox car ce n'est pas un navigateur Webkit.

-webkit-transform: translate3d(0, 0, 0);
-webkit-text-stroke: 0.35px;

Je n'ai littéralement aucune idée de ce qui le cause et comment je peux le réparer!

14
Rick Doesburg

Bien!

Après une semaine de tests, de suppression et d’ajout de règles CSS, j’ai enfin trouvé la solution à mon problème. A l'origine, j'avais ce problème dans Firefox 39 et Safari 9, mais Firefox s'est mystérieusement résolu avec la dernière mise à jour. Safari cependant, n'a pas. Le problème concerne le rendu 3D des éléments de la page. L'élément que j'ai essayé de redimensionner a dû être transformé en contexte 3D, les éléments vacillants de la page étant basculés entre 2D et 3D, comme l'explique @ Woodrow-Barlow dans les autres réponses. 

En ajoutant

-webkit-transform: translate3d(0, 0, 0);

aux éléments scintillants, et les rendant ainsi en 3D au chargement de la page, ils n’ont plus à changer!

EDIT 1 : pour les personnes confrontées à ce problème dans d'autres navigateurs, consultez la propriété CSS 'will-change': https://dev.opera.com/articles/css-will-change-property/

18
Rick Doesburg

Note à OP: vous semblez au moins au courant de la plupart de ces concepts, mais j'ai inclus beaucoup de détails dans cette réponse pour ceux qui pourraient avoir un problème similaire.

Dans les navigateurs modernes fonctionnant sur un ordinateur doté d'un GPU (processeur de rendu des graphiques) dédié, le navigateur transfère parfois la tâche de restitution de la page Web de votre CPU (le processeur "normal") vers le GPU. La CPU et le GPU ont chacun leurs forces et leurs faiblesses. La nature du GPU est qu'il peut effectuer des transformations en 3 dimensions de manière très efficace, mais peut ne pas être en mesure de restituer le texte brut aussi clairement que le CPU.

Votre effet de survol utilise une transformation que votre navigateur a jugée appropriée pour le rendu accéléré par le processeur graphique (probablement déclenchée par la transformation scale(1.1)). Il est donc temporairement passé au rendu du GPU pendant le déroulement de l'animation/transition en survol. Une fois l’animation terminée, la CPU reprend le rendu. En raison des stratégies de rendu différentes utilisées par les différents éléments matériels, le texte est différent (moins net) pendant que le GPU est en charge.

Malheureusement, nous n'avons pas (encore) de contrôle explicite de l'accélération matérielle via CSS - le navigateur le définit à tout moment. Ce que nous pouvons faire, cependant, est de définir certaines propriétés que nous suspectons mettrons le navigateur en mode GPU à accélération matérielle. La théorie ici est que nous allons garder le navigateur en mode GPU même lorsque l'animation ne se produit pas, de sorte que nous ne voyons pas de "scintillement".

Cette stratégie présente certains inconvénients: les utilisateurs qui visitent votre site Web connaîtront une légère augmentation de l'utilisation de la mémoire RAM lorsque votre page est ouverte, tandis que les utilisateurs de téléphones portables/ordinateurs portables connaîtront une consommation de batterie légèrement accrue. Sur les appareils sans GPU dédié, l'accélération matérielle ne sera pas déclenchée (mais encore une fois, ces appareils ne verront pas le "scintillement" que vous voyez de toute façon).

Il semblerait que vous ayez déjà essayé de le faire en ajoutant la propriété scale(1.0) à l'élément non survolé. Mon meilleur choix est que votre (vos) navigateur (s) a (ont) été "malin" et a détecté que cette règle ne fait rien et l'ignore. Le moyen le plus sûr de déclencher une accélération matérielle est généralement une transformation sur l'axe Z. Essayez de changer votre transformation comme suit:

@include transform(scale(1.00001), translateZ(0.00001));

Plutôt que d'utiliser les valeurs "1" et "0", j'utilise des valeurs infinitésimales proches; j'espère que cela empêchera le navigateur de devenir "malin" et d'ignorer la règle.

Je suppose que votre Sass inclut qu'il est en train de préfixer le vendeur. Vérifiez à nouveau que la sortie finale comprend non seulement les -webkit-transform: et -moz-transform:, mais également la syntaxe transform: sans préfixe. Si vous voulez être certain (aux fins du débogage), il suffit de les taper manuellement:

.usp .icon {
  transform: scale(1.00001), translateZ(0.00001);
  -webkit-transform: scale(1.00001), translateZ(0.00001);
  -moz-transform: scale(1.00001), translateZ(0.00001);
}

De mon côté, je n’ai pas eu de scintillement pour commencer avec votre violon (je soupçonne que la configuration de mon navigateur/système d’exploitation/matériel ne pense pas qu’une échelle à 2 dimensions est appropriée pour le GPU), je suis donc incapable. pour tester ce code. Cependant, j'ai utilisé des techniques similaires pour résoudre des problèmes similaires assez souvent.

8
Woodrow Barlow

Ahhh, mais as-tu essayé

.usp .icon {
    -webkit-transform: translateZ(0);
    transform: translateZ(0);
}

http://jsfiddle.net/j04mayvb/4/

 enter image description here

Honnêtement, je ne sais vraiment pas pourquoi cela fonctionne, mais je peux le voir arrêter le scintillement de votre Fiddle dans Safari. 

2
MattDiamant

D'ACCORD!

Donc, le problème que j'ai rencontré était dans un popup personnalisé où j'avais un effet de roue sur le bouton en croix en utilisant la transition CSS. Mais cela a provoqué un problème de scintillement dans le popup.

Après avoir visité divers portails en ligne, j'ai appris à connaître cette propriété de transition:

webkit-backface-visibility: hidden;

sur l'élément en transition fonctionne vraiment et arrête le scintillement. Mais en utilisant cette propriété, le composant entier (popup) s'estompait dans mon cas et pour arrêter cela, je devais utiliser une autre propriété sur l'élément racine du composant:

webkit-transform: translate3d(0, 0, 0);

mais comme je l'utilisais dans un popup personnalisé qui était déjà traduit à -50% pour le garder au centre, j'étais obligé de ne pas l'utiliser.

Après avoir joué avec les propriétés css pendant plusieurs jours et essayé différentes solutions, je suis parvenu à la conclusion que la hauteur totale du composant dans lequel l'élément transitionné est utilisé doit êtreMÊMEet que, dans le cas de données dynamiques, les marges et les rembourrages de telle sorte que la hauteur totale resteMÊME.

Cela a résolu mon problème. Assurez-vous simplement que la hauteur totale resteMÊMEet ajustez les marges et les rembourrages en conséquence.

J'espère que cela aidera aussi les personnes dans le besoin. :)

1
Avaneesh Tripathi

Cela fait également des semaines que nous cherchons à résoudre ce problème. Vous pouvez utiliser toutes sortes d’astuces comme celles mentionnées ci-dessus pour placer l’élément dans sa propre couche GPU. Mais cela fera en sorte que le texte soit transformé en bitmap et donc flou.

Dans notre cas, le problème est dû à un même pixel. Lorsque vous centrez un modal à l’aide de la traduction -50% ou éventuellement de% tailles. Les éléments enfants à l'intérieur de ce conteneur peuvent prendre plusieurs positions (en fonction de la largeur/hauteur du modal). En chrome, vous pouvez simplement vérifier ceci sur un élément de l'onglet calculé. S'il y a des positions uniques, vous pouvez les voir «sauter» lorsque vous survolez un élément différent, comme un bouton CSS animé. 

Lorsque vous survolez le bouton css, il ne s'agit pas uniquement de restituer l'élément lui-même, mais également d'autres éléments de la page. En raison des positions oneven, vous pouvez voir l’élément sauter. 

Échelle Dans notre cas, nous avions un deuxième problème: nous voulions réduire la totalité de la page lorsqu'un utilisateur visitait la page avec un écran plus petit. Au début, nous avons utilisé une translation (échelle). Une échelle sur un parent crée également une seule et même position d'éléments enfants. Disons que votre échelle est 0.8343493. Dans ce cas, les éléments enfants sont recalculés et peuvent simplement être ajoutés. Avec une animation CSS3, vous obtenez le même problème que décrit ci-dessus. 

Après des semaines de recherche, la réponse pour Chrome était assez simple. Nous utilisons maintenant l’ancienne option zoom: 1.0 au lieu de traduire: (échelle 1.0). Le résultat est que nous avons maintenant une page nette et non scintillante.

Exemple de résultat final avec des touches et des transitions d'échelle & non scintillantes:

0
Berry van Elk

J'ai trouvé que cela se produit principalement sur des éléments qui ont été transformés (c'est-à-dire: un modal qui se glisse dans). Existe-t-il une transformation sur l'un des éléments parents? 

Il y a une tonne de corrections sur le Web pour les navigateurs Webkit, mais rien pour Firefox.

0
Westley Mon
-webkit-transform: translate3d(0, 0, 0);
-webkit-text-stroke: 0.35px;

Ces codes sont écrits pour supporter plusieurs navigateurs. Essayez ceci pour mozila

-moz-transform: translate3d(0, 0, 0);
-moz-text-stroke: 0.35px;
0
Satrughna