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.