L'effetto di transizione CSS rende l'immagine sfocata / sposta l'immagine di 1 pixel, in Chrome?


150

Ho alcuni CSS che al passaggio del mouse, un effetto di transizione CSS sposta un div.

Il problema, come puoi vedere nell'esempio, è che la translatetransizione ha l'orribile effetto collaterale di far muovere l'immagine nel div di 1px in basso / a destra (e possibilmente ridimensionarla leggermente?) In modo che appaia fuori posto e sfocato...

Il glitch sembra applicarsi per tutto il tempo in cui viene applicato l'effetto hover, e da un processo di tentativi ed errori posso tranquillamente dire che sembra verificarsi solo quando la transizione di traduzione sposta il div (vengono applicate anche l'ombra della scatola e l'opacità, ma non fa differenza per l'errore quando rimosso).

Il problema sembra verificarsi solo quando la pagina ha barre di scorrimento. Quindi l'esempio con una sola istanza del div va bene, ma una volta aggiunti div più identici e la pagina richiede quindi una barra di scorrimento, il problema si ripresenta ...


1
Sono su Chrome 27 su OSX, e va bene. Credo che quando il contenuto viene inserito in un livello viene trasformato in bitmap durante l'animazione e che nelle versioni precedenti / schede grafiche più vecchie non sembra eccezionale. Prova una versione più recente e verifica se è stata risolta.
Rich Bradshaw,

Tutto bene su Chrome 25 OS X. A proposito: suggerirei un approccio diverso per la trama del gradiente di sfondo rispetto a un'immagine da 300 KB!
Paolo

E grazie @Paolo - l'immagine di sfondo era solo per la dimostrazione, non è l'immagine in uso sul sito reale!
Lewis,

2
Il problema sorge quando l'animazione è gestita dalla GPU, sembra che gli arrotondamenti della bitmap siano un po 'fuori. Viene riprodotto alle Canarie, ma funziona bene se si disattiva l'accelerazione GPU
val

Puoi provare questa soluzione ogni frame ... stackoverflow.com/a/42256897/1834212
Miguel

Risposte:


247

Aggiornamento 2020

  • Se hai problemi con le immagini sfocate, assicurati di controllare anche le risposte dal basso, in particolare la image-renderingproprietà CSS.
  • Per l'accessibilità delle migliori pratiche e per quanto riguarda la SEO, puoi sostituire l'immagine di sfondo con un <img>tag usando la proprietà CSS adatta all'oggetto .

Risposta originale

Prova questo nel tuo CSS :

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

Ciò che fa è rendere la divisione comportarsi "più 2D".

  • Backface è disegnato come predefinito per consentire di capovolgere le cose con Ruota e così via. Non è necessario se si sposta solo a sinistra, a destra, in alto, in basso, in scala o in senso antiorario.
  • Traduci l'asse Z per avere sempre un valore zero.
  • Chrome ora gestisce backface-visibilitye transformsenza il -webkit-prefisso. Al momento non so come questo influisca sul rendering di altri browser (FF, IE), quindi usa le versioni senza prefisso con cautela.

27
Potrebbe non aver spiegato nulla, ma ha spiegato abbastanza per risolvere questo problema per me.
McNab,

@Class Stacker: cosa spiegare? Basta copiare incollare il codice sull'elemento problematico. A proposito funziona molto bene!
Easwee,

1
suggerisco questa soluzione stackoverflow.com/a/42256897/1834212 im pubblicando il link per evitare duplicazioni
Miguel

1
Qualcuno può confermare se funziona ancora, perché ogni volta che aggiungo `-webkit-backface-visible` e -webkit-transform, non riesco davvero a vedere un cambiamento, e quando apro la console di sviluppo di chromes. Vedo che le proprietà di 2 CSS sono barrate, come se fossero sovrascritte, ma non lo sono (CSS vuoto e HTML). È come se Chrome non li accettasse più.
Kevin M,

1
@KevinM prova senza i prefissi -webkit-, ora sono CSS standard.
sampoh

91

È necessario applicare la trasformazione 3d all'elemento, in modo da ottenere il proprio livello composito. Per esempio:

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

o

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

Ulteriori informazioni sui criteri di creazione dei livelli sono disponibili qui: Rendering accelerato in Chrome


Una spiegazione:

Esempi (hover box verde):

Quando usi una transizione sul tuo elemento, il browser ricalcola gli stili, quindi ridimensiona il tuo contenuto anche se la proprietà di transizione è visiva (nei miei esempi è un'opacità) e infine dipinge un elemento:

immagine dello schermo

Il problema qui è il ridimensionamento del contenuto che può avere l'effetto di "ballare" o "sbattere le palpebre" elementi sulla pagina durante la transizione. Se andrai alle impostazioni, seleziona la casella di controllo "Mostra livelli compositi" e quindi applica la trasformazione 3d a un elemento, vedrai che ottiene il proprio livello delineato con un bordo arancione.

immagine dello schermo

Dopo che l'elemento ha ottenuto il proprio livello, il browser deve solo comporre i livelli durante la transizione senza ricollocamento o persino operazioni di disegno, quindi il problema deve essere risolto:

immagine dello schermo


bella roba! ho ottenuto una causa puntuale di quanto fosse dettagliata la tua risposta! quale software stai usando per catturare schermo / freccia?
kroe,

Spot on mate !! Mi ha salvato un sacco di problemi lì.

Questo ha fatto il trucco per me. Inizialmente stavo usando translateZ sul genitore che stavo animando, ma gli sprite all'interno dell'immagine erano ancora sfocati. Sto usando Velocity.js per ridimensionare ancora un altro contenitore al suo interno e ho applicato qualcosa come translateZ: 0.000001(un numero infinitesimale) e voilà! Immagini di sfondo nitide ancora una volta!
notacouch

Grazie compagno. Questo ha funzionato sul mio problema. a proposito, il mio problema è che ho un elemento che viene ruotato di 90 gradi e ha una transizione di dissolvenza che utilizza l'opacità. quando si attiva la transizione, il contenuto dell'elemento si sposta di 1 pixel da sinistra.
Lloyd aaron,

42

Aveva lo stesso problema con iframe incorporato di YouTube (le traduzioni venivano usate per centrare l'elemento iframe). Nessuna delle soluzioni sopra ha funzionato fino a quando non si è verificato il ripristino dei filtri CSS e la magia.

Struttura:

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

Stile [prima]

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

Stile [dopo]

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

9
filter: blur(0)fatto per me!
Nick,

3
Incredibile O_o WTF con la sfocatura? Perché è attivo per impostazione predefinita?
Yuriy Polezhayev il

Questa è stata la soluzione anche per me. La risposta accettata potrebbe funzionare per le persone che non utilizzano altre funzioni di "traduzione" nelle loro proprietà di trasformazione, ma non funzionava per me.
Edward Coyle Jr.

Il -webkit-prefisso non dovrebbe venire prima? Ulteriori informazioni
Trevor Nestman,

32

Ho raccomandato un nuovo attributo sperimentale CSS che ho testato sull'ultimo browser ed è buono:

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+                */

Con questo il browser conoscerà l'algoritmo per il rendering


Ciò ha risolto le mie immagini ruotate sfocate mentre la visibilità della faccia posteriore, la sfocatura (0), translateZ non ha funzionato per me. Grazie.
Louis Ameline,

Risolto il problema con le immagini in alcuni casi d'uso, reso orribilmente peggiore in altri :-) Interessante in ogni caso!
Simon Steinberger,

Scavato più a fondo: image-rendering: -webkit-optimize-contrast;risolve il problema su Chrome. Tuttavia, le immagini su altri browser, ad esempio Firefox, vengono rese molto, molto peggio con l'opzione di rendering impostata. Pertanto, utilizzo solo la direttiva WebKit, che funziona anche sul motore Blink. Grazie!
Simon Steinberger,

In alcuni casi, le immagini risultano notevolmente irregolari. Non riesco a trovare un punto debole tra il risultato più sfocato e questo ~ sospiro ~
bigp

4

Ho appena trovato un altro motivo per cui un elemento diventa sfocato quando viene trasformato. Stavo usando transform: translate3d(-5.5px, -18px, 0);per riposizionare un elemento una volta che era stato caricato, tuttavia quell'elemento è diventato sfocato.

Ho provato tutti i suggerimenti sopra ma ho scoperto che era dovuto a me usare un valore decimale per uno dei valori di traduzione. Numeri interi non causano la sfocatura, e più mi allontanavo da tutto il numero, peggiore diventava la sfocatura.

cioè 5.5pxsfoca l'elemento di più, 5.1pxil meno.

Ho pensato di buttarlo qui nel caso in cui fosse d'aiuto a qualcuno.


Grazie, questo è stato il problema nel mio caso: stavo usando translateY (-50%) che doveva aver valutato un valore decimale in pixel.
1818

3

Ho imbrogliato il problema usando la transizione per passaggi, non uniformemente

transition-timing-function: steps(10, end);

Non è una soluzione, è un imbroglio e non può essere applicato ovunque.

Non posso spiegarlo, ma funziona per me. Nessuna altra risposta mi aiuta (OSX, Chrome 63, display non Retina).

https://jsfiddle.net/tuzae6a9/6/


Nel tuo violino trema come il Parkinson, ma nel mio caso ha funzionato.
Tárcio Zemel,

2

Ridimensionare per raddoppiare e ridurre della metà con zoomlavorato per me.

transform: scale(2);
zoom: 0.5;

questo sembra funzionare in Chrome per le immagini. sfortunatamente modifica anche qualsiasi HTML che lo metti in giro.
Jack Davidson,

2

Ho provato circa 10 possibili soluzioni. Li ho mescolati e ancora non funzionavano correttamente. Alla fine c'era sempre un frullato di 1px.

Trovo la soluzione riducendo il tempo di transizione sul filtro.

Questo non ha funzionato:

.elem {
  filter: blur(0);
  transition: filter 1.2s ease;
}
.elem:hover {
  filter: blur(7px);
}

Soluzione:

.elem {
  filter: blur(0);
  transition: filter .7s ease;
}
.elem:hover {
  filter: blur(7px);
}

Prova questo nel violino:

.blur {
  border: none;
  outline: none;
  width: 100px; height: 100px;
  background: #f0f;
  margin: 30px;
  -webkit-filter: blur(10px);
  transition: all .7s ease-out;
  /* transition: all .2s ease-out; */
}
.blur:hover {
  -webkit-filter: blur(0);
}

.blur2 {
  border: none;
  outline: none;
  width: 100px; height: 100px;
  background: tomato;
  margin: 30px;
  -webkit-filter: blur(10px);
  transition: all .2s ease-out;
}
.blur2:hover {
  -webkit-filter: blur(0);
}
<div class="blur"></div>

<div class="blur2"></div>

Spero che questo aiuti qualcuno.


1

Provare filter: blur(0);

Ha funzionato per me


Ha funzionato anche per me, Chrome 63, 64 e Vivaldi 1.13
GTCrais

1

Per me, ora nel 2018. L'unica cosa che ha risolto il mio problema (una linea bianca tremolante sfarfallio che attraversa un'immagine al passaggio del mouse) è stata applicare questo al mio elemento di collegamento che contiene l'elemento di immagine che ha transform: scale(1.05)

a {
   -webkit-backface-visibility: hidden;
   backface-visibility: hidden;
   -webkit-transform: translateZ(0) scale(1.0, 1.0);
   transform: translateZ(0) scale(1.0, 1.0);
   -webkit-filter: blur(0);
   filter: blur(0);
}
a > .imageElement {
   transition: transform 3s ease-in-out;
}

Sì! 'blur (0)' lo risolve per me in Chrome. Rende l'immagine leggermente sfocata al ridimensionamento, ma è meno evidente del salto / ridimensionamento
00-BBB

0
filter: blur(0)
transition: filter .3s ease-out
transition-timing-function: steps(3, end) // add this string with steps equal duration

Sono stato aiutato impostando il valore della durata della transizione in modo .3suguale per i tempi di transizione.3s


-7

Ho appena avuto lo stesso problema. Prova a impostare la posizione: relativa all'elemento genitore, che ha funzionato per me.


5
Hai una demo di questo lavoro? Non ho idea di come ciò possa aiutare
Zach Saucier,

2
Se potessi, per favore, modifica la tua risposta e spiega cosa fa il codice che stai mostrando e perché / come quel codice risponde alla domanda, potrebbe davvero aiutare. I blocchi di codice da soli non sono generalmente risposte utili.
Lea Cohen,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.