166 votes

L'effet de transition CSS rend l'image floue / déplace l'image de 1px, dans Chrome ?

J'ai un CSS qui, au survol, un effet de transition CSS déplace un div.

Le problème, comme vous pouvez le voir dans l'exemple, c'est que les translate La transition a l'horrible effet secondaire de faire bouger l'image dans le div de 1px vers le bas/droite (et éventuellement de la redimensionner très légèrement ?) de sorte qu'elle semble déplacée et mal cadrée...

Le problème semble s'appliquer pendant toute la durée de l'application de l'effet de survol et, après un processus d'essais et d'erreurs, je peux dire sans me tromper qu'il ne semble se produire que lorsque la transition de translation déplace la division (l'ombre de la boîte et l'opacité sont également appliquées mais ne font aucune différence pour l'erreur lorsqu'elles sont retirées).

Le problème ne semble se produire que lorsque la page comporte des barres de défilement. Ainsi, l'exemple avec une seule instance de la division fonctionne bien, mais si plusieurs divisions identiques sont ajoutées et que la page nécessite une barre de défilement, le problème se pose à nouveau...

273voto

sampoh Points 663

Mise à jour 2020

  • Si vous avez des problèmes avec les images floues, assurez-vous de vérifier les réponses ci-dessous également, en particulier les questions suivantes image-rendering Propriété CSS.
  • Pour des raisons d'accessibilité et de référencement, vous pourriez remplacer l'image d'arrière-plan par une image de type <img> en utilisant adapté à l'objet Propriété CSS.

Réponse originale

Essayez ceci dans votre CSS :

.your-class-name {
    /* ... */
    -webkit-backface-visibility: hidden;
    -webkit-transform: translateZ(0) scale(1, 1);
}

Cela permet à la division de se comporter "plus en 2D".

  • La face arrière est dessinée par défaut pour permettre de retourner les choses avec la rotation. et autres. Ce n'est pas nécessaire si vous vous contentez de vous déplacer à gauche, à droite, en haut, en bas, de changer d'échelle ou de tourner dans le sens (anti-)horaire.
  • Translate Z-axis to always have a zero value.
  • Chrome gère désormais backface-visibility y transform sans le -webkit- préfixe. Je ne sais pas actuellement comment cela affecte le rendu des autres navigateurs (FF, IE), donc utilisez les versions non préfixées avec prudence.

99voto

sol0mka Points 199

Vous devez appliquer une transformation 3D à l'élément, afin qu'il obtienne sa propre couche composite. Par exemple :

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

o

.element{
    -webkit-transform: translate3d(0,0,0);
    transform: translate3d(0,0,0);
}

Pour en savoir plus sur les critères de création des couches, cliquez ici : Rendu accéléré dans Chrome


Une explication :

Exemples (boîte verte au survol) :

Lorsque vous utilisez une transition sur un élément, le navigateur recalcule les styles, puis réorganise le contenu, même si la propriété de la transition est visuelle (dans mon exemple, il s'agit d'une opacité) et enfin peint l'élément :

screenshot

Le problème ici est la réorganisation du contenu qui peut produire un effet de "danse" ou de "clignotement" des éléments sur la page pendant la transition. Si vous allez dans les paramètres, cochez la case "Afficher les couches composites", puis appliquez une transformation 3D à un élément, vous verrez qu'il obtient sa propre couche, délimitée par une bordure orange.

screenshot

Une fois que l'élément a son propre calque, le navigateur doit simplement composer les calques lors de la transition sans avoir à refaire la mise en page ou même à effectuer des opérations de peinture :

screenshot

47voto

xb1itz Points 845

J'ai eu le même problème avec une iframe youtube intégrée (les traductions étaient utilisées pour centrer l'élément iframe). Aucune des solutions ci-dessus n'a fonctionné jusqu'à ce que j'essaie réinitialiser les filtres css et la magie a opéré.

Structure :

<div class="translate">
     <iframe/>
</div>

Style [avant]

.translate {
  transform: translateX(-50%);
  -webkit-transform: translateX(-50%);
}

Style [après]

.translate {
  transform: translateX(-50%);
  -webkit-transform: translateX(-50%);
  filter: blur(0);
  -webkit-filter: blur(0);
}

35voto

Felipez Points 458

J'ai recommandé un nouvel attribut CSS expérimental que j'ai testé sur le dernier navigateur et qui est bon :

image-rendering: optimizeSpeed;             /*                     */
image-rendering: -moz-crisp-edges;          /* Firefox             */
image-rendering: -o-crisp-edges;            /* Opera               */
image-rendering: -webkit-optimize-contrast; /* Chrome (and Safari) */
image-rendering: optimize-contrast;         /* CSS3 Proposed       */
-ms-interpolation-mode: nearest-neighbor;   /* IE8+                */

Grâce à cela, le navigateur connaîtra l'algorithme de rendu.

6voto

ashrobbins Points 63

Je viens de trouver une autre raison pour laquelle un élément devient flou lorsqu'il est transformé. J'utilisais transform: translate3d(-5.5px, -18px, 0); pour repositionner un élément une fois qu'il a été chargé, mais cet élément est devenu flou.

J'ai essayé toutes les suggestions ci-dessus, mais il s'est avéré que le problème était dû à l'utilisation d'une valeur décimale pour l'une des valeurs de traduction. Les nombres entiers ne provoquent pas le flou, et plus je m'éloigne du nombre entier, plus le flou s'aggrave.

c'est-à-dire 5.5px brouille le plus l'élément, 5.1px le moins.

J'ai juste pensé que je pourrais mettre ça ici au cas où ça aiderait quelqu'un.

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