CSS-Transformation, gezackte Kanten in Chrom


193

Ich habe die CSS3-Transformation verwendet, um Bilder und Textfelder mit Rahmen auf meiner Website zu drehen.

Das Problem ist, dass der Rand in Chrome gezackt aussieht, wie bei einem Spiel (mit niedriger Auflösung) ohne Anti-Aliasing. In IE, Opera und FF sieht es viel besser aus, weil AA verwendet wird (was immer noch deutlich sichtbar ist, aber nicht so schlecht). Ich kann Safari nicht testen, da ich keinen Mac besitze.

Das gedrehte Foto und der Text selbst sehen gut aus, nur der Rand sieht gezackt aus.

Das CSS, das ich benutze, ist folgendes:

.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 */
}

Gibt es eine Möglichkeit, dies zu beheben, z. B. indem ich Chrome zur Verwendung von AA zwinge?

Beispiel unten:

Beispiel für gezackte Kanten


Für diejenigen, die es später lesen: Es sollte in Chrome ab Version 15 (November 2011) behoben sein, aber Safari hat in 5.1 für Mac genau das gleiche Problem eingeführt, das
derzeit

Und sie haben es so gut repariert, dass ein Zurückgehen unmöglich ist. Wir haben Fälle, in denen Antialiasing das letzte ist, was wir wollen, aber jetzt hat Chrome / Chromium / Safari keine Methode, um Antialiasing in transformierten Bildern zu deaktivieren, obwohl es sich um 1-Bit-Bilder handelt (z. B. s / w-GIF). Unschärfe ist so cool, so cool, mehr Unschärfe ist cooler, sagen sie! Die einzige Möglichkeit, scharfe Kanten sicherzustellen, besteht darin, alle in SVG-Pfade oder -Objekte zu konvertieren und das Attribut shape-rendering = "crispEdges" hinzuzufügen.
Timo Kähkönen

Für mich geht es um transparente Ränder, mit denen ein Pfeil erstellt wird. Dies ist in Chrome 40 auf Win und Mac. Keine der hier aufgeführten Optionen behebt das Problem.
Gurnard

Antworten:


389

Falls jemand später danach sucht, besteht ein guter Trick, um diese gezackten Kanten bei CSS-Transformationen in Chrome zu beseitigen, darin, die CSS-Eigenschaft -webkit-backface-visibilitymit dem Wert von hinzuzufügen hidden. In meinen eigenen Tests hat dies sie vollständig geglättet. Hoffentlich hilft das.

-webkit-backface-visibility: hidden;

7
Lebensretter - Mit diesem Trick konnten wir -webkit-transform auf einer Reihe von Websites wieder aktivieren, die wir zuvor aufgrund von Anti-Aliasing-Problemen deaktivieren mussten. Vielen Dank!
Darren


5
Dies funktioniert in Chrome, macht sie jedoch in iOS 6 wieder gezackt!
Lazd

11
@lazd, um es in iOS zu beheben hinzufügenpadding: 1px; -webkit-background-clip: content-box;
Rob Fletcher

2
@RobFletcher hat Padding und Hintergrund-Clip hinzugefügt, die laut diesem Thread für eine browser- und cross-übergreifende Lösung unerlässlich zu sein scheinen. Dies behebt auch mein OSX / Chrome-Problem, also ... Ich denke, eine vollständige Lösung wäre ungefähr so:padding: 1px;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-background-clip:content-box;background-clip:content-box;
Benjamin Luoma

119

Wenn Sie transitionanstelle von verwenden transform, -webkit-backface-visibility: hidden;funktioniert nicht. Während der Animation wird eine gezackte Kante für eine transparente PNG-Datei angezeigt.

Um es zu lösen, benutzte ich: outline: 1px solid transparent;


4
Dies scheint in Situationen hilfreich zu sein, in denen die Eigenschaft "Web-Kit-Backface-Sichtbarkeit" übersehen wurde.
Dgibbs

2
Funktioniert für mich, wenn keiner der anderen es tat. Vor dem Hinzufügen dieser Eigenschaft hatte Chrome Android Probleme. Jetzt scheinen alle Browser richtig zu funktionieren.
Bernie Sumption

Funktioniert für mich in Safari unter iOS 8.
Moritz Friedrich

Perfekte Lösung. Die anderen haben nicht funktioniert. Ich hätte fast aufgegeben und bezweifelte, dass dies funktionieren würde. Aber es tut!
Garconis

1
Funktioniert perfekt für meine Bedürfnisse. Ich verwende in der Tat den Übergang, und die anderen Antworten haben dazu geführt, dass mein PNG im Standardzustand pixelig wurde. Ihre Antwort hat dazu beigetragen, jegliche Pixelbildung zu beseitigen - sowohl im Standardzustand als auch während des Übergangs. Perfekt!
Garconis

24

Das Hinzufügen eines transparenten 1px-Rahmens löst ein Anti-Aliasing aus

outline: 1px solid transparent;

Alternativ können Sie einen 1px transparenten Kastenschatten hinzufügen.

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

rgba (255, 255, 255, 0) ist wahrscheinlich besser
mmm

4
Das Hinzufügen des oberen Teils von CSS zu Ihrer Antwort und das outline: 1px solid transparent;hat für mich gut funktioniert. Die anderen oben genannten Lösungen funktionierten nicht gut genug.
Timothy Zorn

outline: 1px solid transparent;Anti-Aliasing auch in Firefox 52 auslösen (das hat die gleichen Probleme wie Chrome)
Luca Detomi

18

Versuchen Sie 3D-Transformation. Das funktioniert wie ein Zauber!

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

1
Wenn Sie dies jetzt in Chrome versuchen (August 2013 auf einem Mac), funktioniert die akzeptierte Lösung nicht, aber wenn Sie dies verwenden (insbesondere preserve-3d; rotatekann immer noch verwendet werden, ohne zu wechseln rotateZ).
Dave

Super hacky, hat aber bei mir funktioniert. Versuchen Sie es mit einem noch kleineren Grad wie 0,05, um eine sichtbare Fehlausrichtung zu vermeiden.
Cpursley

Bewahren-3d hat mein Leben gerettet.
Hannes Schneidermayer

8

Die gewählte Antwort (noch eine der anderen Antworten) hat bei mir nicht funktioniert, aber das hat funktioniert:

img {outline:1px solid transparent;}


2

Ich habe ein Problem mit einem CSS3-Gradienten mit -45 Grad. Der backgroundschräge, war stark gezackt ähnlich, aber schlimmer als der ursprüngliche Pfosten. Also fing ich an mit beiden zu spielen background-size. Dies würde die Zackigkeit ausdehnen, aber es war immer noch da. Dann habe ich zusätzlich gelesen, dass andere Leute ebenfalls Probleme in Schritten von 45 Grad haben, also habe ich mich von angepasst-45deg auf-45.0001deg und mein Problem wurde gelöst.

In meinem CSS unten background-sizewar anfangs 30pxund der degfür den Hintergrund Gradient war genau -45degund alle Keyframes waren 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

Möglicherweise können Sie das Zacken mit unscharfen Kastenschatten maskieren . Durch die Verwendung von -webkit-box-shadow anstelle von box-shadow wird sichergestellt, dass keine Nicht-Webkit-Browser betroffen sind. Möglicherweise möchten Sie jedoch Safari und die Browser des mobilen Webkits überprüfen.

Das Ergebnis ist etwas besser, aber immer noch viel weniger gut als bei den anderen Browsern:

mit Kastenschatten (Unterseite)


1

Ich dachte nur, wir würden auch unsere Lösung einwerfen, da wir unter Chrome / Windows genau das gleiche Problem hatten.

Wir haben die Lösung von @stevenWatkins oben ausprobiert, hatten aber immer noch das "Stepping".

Anstatt

-webkit-backface-visibility: hidden;

Wir verwendeten:

-webkit-backface-visibility: initial;

Für uns hat das den Trick gemacht 🎉


1

Das Hinzufügen des Folgenden zu dem Div, das das betreffende Element umgibt, hat dies für mich behoben.

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

In meinem Fall erschienen die gezackten Kanten um das Videofenster.


0

Für mich war es die perspektivische CSS-Eigenschaft, die den Trick machte:

-webkit-perspective: 1000;

In meinem Fall völlig unlogisch, da ich keine 3D-Übergänge verwende, aber trotzdem funktioniert.


0

Für Leinwand in Chrome (Version 52)

Alle aufgelisteten Antworten beziehen sich auf Bilder. Aber mein Problem ist über Leinwand in Chrom (v.52) mit Transformation drehen. Sie wurden gezackt und all diese Methoden können nicht helfen.

Lösung, die für mich funktioniert:

  1. Vergrößern Sie die Leinwand auf 1 Pixel für jede Seite => +2 Pixel für Breite und Höhe;
  2. Zeichnen Sie ein Bild mit einem Versatz von + 1 Pixel (in Position 1,1 anstelle von 0,0) und einer festen Größe (die Bildgröße sollte 2 Pixel kleiner sein als die Leinwandgröße).
  3. Wenden Sie die erforderliche Drehung an

So wichtige Codeblöcke:

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

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

Hinweis: Es gibt viele verschachtelte Divs, da es sich um eine vereinfachte Version aus meinem Projekt handelt.


Dieses Problem wird reproduziert auch für Firefox für mich . Bei Safari und FF mit Netzhaut gibt es kein solches Problem.

Eine andere fundierte Lösung besteht darin, Canvas in Div gleicher Größe zu platzieren und folgendes CSS auf dieses Div anzuwenden:

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

Und Rotation sollte auf dieses Wickel-Div angewendet werden. So gelistete Lösung funktioniert aber mit kleinen Modifikationen.

Ein modifiziertes Beispiel für eine solche Lösung lautet: https://jsfiddle.net/tLbxgusx/2/

Hinweis: Siehe Stil von div mit Klasse 'dritter'.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.