Trasformazione CSS, bordi frastagliati in cromo


193

Sto usando CSS3 Transform per ruotare immagini e caselle di testo con bordi nel mio sito Web.

Il problema è che il bordo appare frastagliato in Chrome, come un gioco (a bassa risoluzione) senza anti-aliasing. In IE, Opera e FF sembra molto meglio perché viene utilizzato AA (che è ancora chiaramente visibile ma non così male). Non riesco a testare Safari perché non possiedo un Mac.

La foto e il testo ruotati sembrano a posto, è solo il bordo a sembrare frastagliato.

Il CSS che uso è questo:

.rotate2deg {
    transform: rotate(2deg);
    -ms-transform: rotate(2deg); /* IE 9 */
    -webkit-transform: rotate(2deg); /* Safari and Chrome */
    -o-transform: rotate(2deg); /* Opera */
    -moz-transform: rotate(2deg); /* Firefox */
}

Esiste un modo per risolvere questo problema, ad esempio forzando Chrome a utilizzare AA?

Esempio sotto:

Esempio di bordi frastagliati


Per chi lo leggerà in seguito: dovrebbe essere risolto in Chrome a partire dalla versione 15 (novembre 2011), ma Safari ha introdotto lo stesso identico problema in 5.1 per Mac, che al momento non è stato ancora risolto
dtech

E l'hanno risolto così bene, che tornare indietro è impossibile. Abbiamo casi in cui l'antialiasing è l'ultima cosa che vogliamo, ma ora Chrome / Chromium / Safari non ha alcun metodo per disattivare l'antialiasing nelle immagini trasformate sebbene siano immagini a 1 bit (ad esempio b / n gif). La sfocatura è così bella, così bella, più sfocatura è più bella, dicono! L'unico modo per garantire bordi nitidi è convertire tutto in tracciati o oggetti svg e aggiungere l'attributo shape-rendering = "crispEdges".
Timo Kähkönen,

Per me il problema riguarda i bordi trasparenti utilizzati per creare una freccia. Questo è in Chrome 40 su win e mac. Nessuna delle opzioni qui risolve il problema.
Gurnard,

Risposte:


389

Nel caso in cui qualcuno lo stia cercando in seguito, un bel trucco per sbarazzarsi di quei bordi frastagliati sulle trasformazioni CSS in Chrome è aggiungere la proprietà CSS -webkit-backface-visibilitycon un valore di hidden. Nei miei test, questo li ha completamente livellati. Spero che aiuti.

-webkit-backface-visibility: hidden;

7
Salvagente: questo trucco ci ha permesso di riattivare -webkit-transform su un numero di siti che in precedenza eravamo costretti a disattivare le trasformazioni a causa di problemi di anti-aliasing. Grazie!
Darren,


5
Funziona in Chrome, ma li rende nuovamente frastagliati in iOS 6!
lazd,

11
@lazd per aggiustarlo in iOS aggiungerepadding: 1px; -webkit-background-clip: content-box;
Rob Fletcher il

2
@RobFletcher ha aggiunto imbottitura e clip di sfondo che sembrano, per questo thread, essenziali per una soluzione cross-browser e cross-os. Questo risolve anche il mio problema OSX / Chrome, quindi ... Penso che una soluzione completa sarebbe qualcosa del tipo:padding: 1px;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-background-clip:content-box;background-clip:content-box;
Benjamin Luoma,

121

Se si utilizza transitioninvece di transform, -webkit-backface-visibility: hidden;non funziona. Un bordo frastagliato appare durante l'animazione per un file png trasparente.

Per risolverlo ho usato: outline: 1px solid transparent;


4
questo sembra dare una mano in situazioni in cui la proprietà web-kit-backface-visibilità ha perso.
dgibbs,

2
Funziona per me quando nessuno degli altri ha fatto. Prima di aggiungere questa proprietà, Chrome Android aveva dei problemi. Ora tutti i browser sembrano funzionare correttamente.
Bernie Sumption,

Funziona per me in Safari su iOS 8.
Moritz Friedrich,

Soluzione perfetta Gli altri non hanno funzionato. Ho quasi rinunciato e dubitavo che avrebbe funzionato. Ma lo fa!
Garconis,

1
Funziona perfettamente per le mie esigenze. Sto davvero usando la transizione, e le altre risposte stavano facendo diventare pixelato il mio PNG al suo stato predefinito. La tua risposta ha aiutato a rimuovere qualsiasi pixelizzazione, sia sullo stato predefinito che durante la transizione. Perfetto!
Garconis,

24

L'aggiunta di un bordo trasparente 1px attiverà l'anti-aliasing

outline: 1px solid transparent;

In alternativa, aggiungi un box-shadow trasparente 1px.

box-shadow: 0 0 1px rgba(255,255,255,0);

rgba (255, 255, 255, 0) è probabilmente migliore
mmm

4
Aggiungendo la parte superiore del CSS nella tua risposta e ha outline: 1px solid transparent;funzionato bene per me. Le altre soluzioni sopra non hanno funzionato abbastanza bene.
Timothy Zorn,

outline: 1px solid transparent;innescare l'antialiasing anche in Firefox 52 (che ha gli stessi problemi di Chrome)
Luca Detomi

18

Prova la trasformazione 3d. Funziona come un incantesimo!

/* Due to a bug in the anti-liasing*/
-webkit-transform-style: preserve-3d; 
-webkit-transform: rotateZ(2deg);

1
provando questo in Chrome ora (agosto 2013 su un Mac), la soluzione accettata non funziona, ma l'utilizzo di questo (in particolare preserve-3d; rotatepuò ancora essere usato senza cambiare in rotateZ) lo fa.
Dave,

Super hacky, ma ha funzionato per me. Prova anche un livello inferiore come 0,05 per evitare un disallineamento visibile.
cpursley,

preserv-3d mi ha salvato la vita.
Hannes Schneidermayer,

8

La risposta scelta (né nessuna delle altre risposte) non ha funzionato per me, ma questo ha fatto:

img {outline:1px solid transparent;}


2

Ho avuto un problema con un gradiente CSS3 con -45deg. L' backgroundinclinazione, era fortemente frastagliata simile ma peggiore del post originale. Quindi ho iniziato a giocare con entrambi background-size. Ciò allungherebbe il frastuono, ma era ancora lì. Inoltre, ho letto che anche altre persone hanno problemi con incrementi di 45 gradi, quindi mi sono adattato da -45dega -45.0001dege il mio problema è stato risolto.

Nel mio CSS sotto, background-sizeinizialmente era 30pxe il deggradiente di sfondo era esattamente -45deg, e tutti i fotogrammi chiave lo erano 30px 0.

    @-webkit-keyframes progressStripeLTR {
        to {
            background-position: 60px 0;
        };
    }

    @-moz-keyframes progressStripeLTR {
        to {
            background-position: 60px 0;
        };
    }

    @-ms-keyframes progressStripeLTR {
        to {
            background-position: 60px 0;
        };
    }

    @-o-keyframes progressStripeLTR {
        to {
            background-position: 60px 0;
        };
    }

    @keyframes progressStripeLTR {
        to {
            background-position: 60px 0;
        };
    }

    @-webkit-keyframes progressStripeRTL {
        to {
            background-position: -60px 0;
        };
    }

    @-moz-keyframes progressStripeRTL {
        to {
            background-position: -60px 0;
        };
    }

    @-ms-keyframes progressStripeRTL {
        to {
            background-position: -60px 0;
        };
    }

    @-o-keyframes progressStripeRTL {
        to {
            background-position: -60px 0;
        };
    }

    @keyframes progressStripeRTL {
        to {
            background-position: -60px 0;
        };
    }

    .pro-bar-candy {
        width: 100%;
        height: 15px;

        -webkit-border-radius:  3px;
        -moz-border-radius:     3px;
        border-radius:          3px;

        background: rgb(187, 187, 187);
        background: -moz-linear-gradient(
                        -45.0001deg,
                        rgba(187, 187, 187, 1.00) 25%,
                        transparent 25%,
                        transparent 50%,
                        rgba(187, 187, 187, 1.00) 50%,
                        rgba(187, 187, 187, 1.00) 75%,
                        transparent 75%,
                        transparent
                    );
        background: -webkit-linear-gradient(
                        -45.0001deg,
                        rgba(187, 187, 187, 1.00) 25%,
                        transparent 25%,
                        transparent 50%,
                        rgba(187, 187, 187, 1.00) 50%,
                        rgba(187, 187, 187, 1.00) 75%,
                        transparent 75%,
                        transparent
                    );
        background: -o-linear-gradient(
                        -45.0001deg,
                        rgba(187, 187, 187, 1.00) 25%,
                        transparent 25%,
                        transparent 50%,
                        rgba(187, 187, 187, 1.00) 50%,
                        rgba(187, 187, 187, 1.00) 75%,
                        transparent 75%,
                        transparent
                    );
        background: -ms-linear-gradient(
                        -45.0001deg,
                        rgba(187, 187, 187, 1.00) 25%,
                        transparent 25%,
                        transparent 50%,
                        rgba(187, 187, 187, 1.00) 50%,
                        rgba(187, 187, 187, 1.00) 75%,
                        transparent 75%,
                        transparent
                    );
        background: linear-gradient(
                        -45.0001deg,
                        rgba(187, 187, 187, 1.00) 25%,
                        transparent 25%,
                        transparent 50%,
                        rgba(187, 187, 187, 1.00) 50%,
                        rgba(187, 187, 187, 1.00) 75%,
                        transparent 75%,
                        transparent
                    );
        background: -webkit-gradient(
                        linear,
                        right bottom,
                        right top,
                        color-stop(
                            25%,
                            rgba(187, 187, 187, 1.00)
                        ),
                        color-stop(
                            25%,
                            rgba(0, 0, 0, 0.00)
                        ),
                        color-stop(
                            50%,
                            rgba(0, 0, 0, 0.00)
                        ),
                        color-stop(
                            50%,
                            rgba(187, 187, 187, 1.00)
                        ),
                        color-stop(
                            75%,
                            rgba(187, 187, 187, 1.00)
                        ),
                        color-stop(
                            75%,
                            rgba(0, 0, 0, 0.00)
                        ),
                        color-stop(
                            rgba(0, 0, 0, 0.00)
                        )
                    );

        background-repeat: repeat-x;
        -webkit-background-size:    60px 60px;
        -moz-background-size:       60px 60px;
        -o-background-size:         60px 60px;
        background-size:            60px 60px;
        }

    .pro-bar-candy.candy-ltr {
        -webkit-animation:  progressStripeLTR .6s linear infinite;
        -moz-animation:     progressStripeLTR .6s linear infinite;
        -ms-animation:      progressStripeLTR .6s linear infinite;
        -o-animation:       progressStripeLTR .6s linear infinite;
        animation:          progressStripeLTR .6s linear infinite;
        }

    .pro-bar-candy.candy-rtl {
        -webkit-animation:  progressStripeRTL .6s linear infinite;
        -moz-animation:     progressStripeRTL .6s linear infinite;
        -ms-animation:      progressStripeRTL .6s linear infinite;
        -o-animation:       progressStripeRTL .6s linear infinite;
        animation:          progressStripeRTL .6s linear infinite;
        }

1

Potresti riuscire a mascherare il frastuono usando le ombre sfocate . L'uso di -webkit-box-shadow anziché box-shadow farà in modo che non influisca sui browser non webkit. Tuttavia, potresti voler controllare Safari e i browser webkit mobili.

Il risultato è leggermente migliore, ma molto meno buono rispetto agli altri browser:

con scatola ombra (lato inferiore)


1

Ho pensato che avremmo inserito anche la nostra soluzione dato che avevamo lo stesso identico problema su Chrome / Windows.

Abbiamo provato la soluzione di @stevenWatkins sopra, ma abbiamo ancora avuto il "passo".

Invece di

-webkit-backface-visibility: hidden;

Abbiamo usato:

-webkit-backface-visibility: initial;

Per noi questo ha funzionato 🎉


1

L'aggiunta di quanto segue sul div che circonda l'elemento in questione ha risolto questo problema per me.

-webkit-transform-style: preserve-3d;

Nel mio caso i bordi frastagliati apparivano attorno alla finestra del video.


0

Per me è stata la proprietà CSS prospettica a fare il trucco:

-webkit-perspective: 1000;

Completamente illogico nel mio caso in quanto non utilizzo transizioni 3d, ma funziona comunque.


0

Per tela in Chrome (versione 52)

Tutte le risposte elencate riguardano le immagini. Ma il mio problema riguarda la tela in cromo (v.52) con trasformazione ruota. Sono diventati frastagliati e tutti questi metodi non possono essere d'aiuto.

Soluzione che funziona per me:

  1. Ingrandisci la tela su 1 px per ogni lato => +2 px per larghezza e altezza;
  2. Disegna l'immagine con offset + 1px (in posizione 1,1 anziché 0,0) e dimensioni fisse (la dimensione dell'immagine dovrebbe essere 2px inferiore alla dimensione della tela)
  3. Applicare la rotazione richiesta

Blocchi di codice così importanti:

// Unfixed version
ctx.drawImage(img, 0, 0, 335, 218);
// Fixed version
ctx.drawImage(img, 1, 1, 335, 218);
/* This style should be applied for fixed version */
canvas {
  margin-left: -1px;
  margin-top:-1px;
}        
<!--Unfixed version-->
<canvas width="335" height="218"></canvas>
<!--Fixed version-->
<canvas width="337" height="220"></canvas>

Esempio: https://jsfiddle.net/tLbxgusx/1/

Nota: ci sono molti div nidificati perché è una versione semplificata del mio progetto.


Questo problema è riprodotto anche per Firefox per me. Non esiste questo problema su Safari e FF con retina.

E un'altra soluzione fondata è quella di posizionare la tela in div della stessa dimensione e applicare i seguenti CSS a questo div:

overflow: hidden;
box-shadow: 0 0 1px rgba(255,255,255,0);
// Or
//outline:1px solid transparent;

E la rotazione dovrebbe essere applicata a questo div avvolgente. Quindi la soluzione elencata funziona ma con piccole modifiche.

Ed esempio modificato per tale soluzione è: https://jsfiddle.net/tLbxgusx/2/

Nota: vedi lo stile del div con la classe "terza".

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.