css transform, postrzępione krawędzie w chromie


193

Używam transformacji CSS3 do obracania obrazów i pól tekstowych z ramkami na mojej stronie.

Problem polega na tym, że obramowanie wygląda na postrzępione w Chrome, jak gra (w niskiej rozdzielczości) bez wygładzania krawędzi. W IE, Operze i FF wygląda to znacznie lepiej, ponieważ używa się AA (co jest nadal wyraźnie widoczne, ale nie takie złe). Nie mogę przetestować Safari, ponieważ nie mam komputera Mac.

Obrócone zdjęcie i sam tekst wyglądają dobrze, tylko krawędź wygląda na postrzępioną.

Używam CSS:

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

Czy jest jakiś sposób, aby to naprawić, np. Zmuszając Chrome do używania AA?

Przykład poniżej:

Przykład postrzępionych krawędzi


Dla osób czytających to później: powinno zostać naprawione w Chrome od wersji 15 (listopad 2011), ale Safari wprowadziło dokładnie ten sam problem w 5.1 dla komputerów Mac, który nie jest jeszcze naprawiony
dtech

I naprawili to tak dobrze, że powrót jest niemożliwy. Mamy przypadki, w których antyaliasing jest ostatnią rzeczą, jakiej chcemy, ale teraz Chrome / Chromium / Safari nie ma metody wyłączania antyaliasingu w przekształconych obrazach, mimo że są to obrazy 1-bitowe (np. Czarno-biały gif). Rozmycie jest takie fajne, takie fajne, więcej rozmycia jest bardziej fajne, mówią! Jedynym sposobem, aby zapewnić ostre krawędzie, jest przekonwertowanie wszystkich na ścieżki lub obiekty SVG i dodanie atrybutu rendering-kształtu = "crispEdges".
Timo Kähkönen,

Dla mnie problemem są przezroczyste obramowania użyte do stworzenia strzałki. To jest w Chrome 40 na Win i Mac. Żadna z opcji tutaj nie rozwiązuje problemu.
Gurnard,

Odpowiedzi:


389

Na wypadek, gdyby ktoś szukał tego później, fajną sztuczką, aby pozbyć się tych postrzępionych krawędzi w transformacjach CSS w Chrome, jest dodanie właściwości CSS -webkit-backface-visibilityo wartości hidden. W moich własnych testach całkowicie je wygładziłem. Mam nadzieję, że to pomaga.

-webkit-backface-visibility: hidden;

7
Lifesaver - ta sztuczka pozwoliła nam ponownie włączyć -webkit-transform w wielu witrynach, które wcześniej musieliśmy wyłączyć z powodu problemów z wygładzaniem. Dzięki!
Darren,

jakakolwiek pomoc na ten temat: stackoverflow.com/questions/9235342/... ?
abernier

5
Działa to w przeglądarce Chrome, ale powoduje, że stają się one znowu poszarpane w systemie iOS 6!
lazd

11
@lazd naprawić to w iOS dodajpadding: 1px; -webkit-background-clip: content-box;
Rob Fletcher

2
@RobFletcher dodał dopełnienie i klip w tle, które wydają się, dla tego wątku, niezbędne w rozwiązaniach cross-browser i cross-os. To rozwiązuje również mój problem z OSX / Chrome, więc ... Myślę, że kompletne rozwiązanie mogłoby wyglądać tak:padding: 1px;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-background-clip:content-box;background-clip:content-box;
Benjamin Luoma

121

Jeśli używasz transitionzamiast transform, -webkit-backface-visibility: hidden;nie działa. Podczas animacji pojawia się postrzępiona krawędź przezroczystego pliku png.

Aby go rozwiązać, użyłem: outline: 1px solid transparent;


4
wydaje się, że pomaga to w sytuacjach, w których właściwość widoczności web-kit-backface-Visibility pominęła.
dgibbs

2
Działa dla mnie, gdy nie zrobił tego żaden inny. Przed dodaniem tej właściwości Chrome Android miał problemy. Teraz wszystkie przeglądarki wydają się działać poprawnie.
Bernie Sumption

Działa dla mnie w Safari na iOS 8.
Moritz Friedrich,

Idealne rozwiązanie. Inni nie działali. Prawie się poddałem i wątpiłem, czy to zadziała. Ale tak jest!
Garconis,

1
Działa idealnie dla moich potrzeb. Rzeczywiście używam przejścia, a inne odpowiedzi powodowały piksele mojego PNG w jego domyślnym stanie. Twoja odpowiedź pomogła usunąć pikselizację - zarówno w stanie domyślnym, jak i podczas przejścia. Idealny!
Garconis 21.04.16

24

Dodanie przezroczystej ramki 1px uruchomi wygładzanie

outline: 1px solid transparent;

Ewentualnie dodaj przezroczysty cień pola o wielkości 1 piksela.

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

rgba (255, 255, 255, 0) jest prawdopodobnie lepszy
mmm

4
Dodanie górnej części CSS w twojej odpowiedzi i outline: 1px solid transparent;zadziałało dobrze dla mnie. Inne powyższe rozwiązania nie działały wystarczająco dobrze.
Timothy Zorn

outline: 1px solid transparent;
włącza

18

Wypróbuj transformację 3d. To działa jak urok!

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

1
próbując tego teraz w chrome (sierpień 2013 na komputerze Mac), zaakceptowane rozwiązanie nie działa, ale korzystanie z tego (a konkretnie preserve-3d; rotatenadal można go używać bez zmiany na rotateZ).
Dave

Super zuchwały, ale pracował dla mnie. Spróbuj nawet mniejszego stopnia, jak 0,05, aby uniknąć widocznego braku wyrównania.
cpursley

preserve-3d uratowało mi życie.
Hannes Schneidermayer

8

Wybrana odpowiedź (ani żadna inna odpowiedź) nie działała dla mnie, ale to:

img {outline:1px solid transparent;}


2

Mam problem z gradientem CSS3 z -45deg. backgroundPochyły, był źle postrzępione podobna, ale gorzej niż oryginalny post. Więc zacząłem grać z obu background-size. To wydłużyłoby postrzępienie, ale wciąż tam było. Wtedy oprócz Czytałem, że inni ludzie mają problemy także w przyrostach 45deg więc regulować od -45degdo-45.0001deg i mój problem został rozwiązany.

W moim CSS poniżej, background-sizepoczątkowo był, 30pxa degdla gradientu tła był dokładnie -45deg, i wszystkie klatki kluczowe były 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

Być może będziesz w stanie maskować postrzępienie za pomocą rozmytych cieni . Użycie opcji -webkit-box-shadow zamiast box-shadow sprawi, że nie wpłynie to na przeglądarki inne niż Webkit. Możesz jednak sprawdzić Safari i mobilne przeglądarki internetowe.

Wynik jest nieco lepszy, ale wciąż znacznie mniej dobry niż w przypadku innych przeglądarek:

z cieniem w ramce (spód)


1

Pomyślałem, że wrzucimy również nasze rozwiązanie, ponieważ mieliśmy dokładnie ten sam problem w Chrome / Windows.

Wypróbowaliśmy rozwiązanie @stevenWatkins powyżej, ale nadal mieliśmy „krok”.

Zamiast

-webkit-backface-visibility: hidden;

Użyliśmy:

-webkit-backface-visibility: initial;

Dla nas to załatwiło sprawę 🎉


1

Dodanie następującego elementu na div otaczającego dany element naprawiło to dla mnie.

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

W moim przypadku poszarpane krawędzie pojawiały się wokół okna wideo.


0

Dla mnie to właśnie perspektywa CSS załatwiła sprawę:

-webkit-perspective: 1000;

Całkowicie nielogiczne w moim przypadku, ponieważ nie używam żadnych przejść 3D, ale mimo to działa.


0

Do płótna w Chrome (wersja 52)

Wszystkie wymienione odpowiedzi dotyczą obrazów. Ale mój problem dotyczy płótna w chromie (wer. 52) z obracaniem transformacji. Stały się postrzępione i wszystkie te metody nie mogą pomóc.

Rozwiązanie, które działa dla mnie:

  1. Powiększ płótno o 1 piksel z każdej strony => +2 px dla szerokości i wysokości;
  2. Narysuj obraz z przesunięciem + 1px (w pozycji 1,1 zamiast 0,0) i stałym rozmiarem (rozmiar obrazu powinien być o 2px mniejszy niż rozmiar płótna)
  3. Zastosuj wymagany obrót

Tak ważne bloki kodu:

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

Przykład: https://jsfiddle.net/tLbxgusx/1/

Uwaga: istnieje wiele zagnieżdżonych div, ponieważ jest to uproszczona wersja mojego projektu.


Ten problem został odtworzony również dla Firefoksa . Nie ma takiego problemu w Safari i FF z siatkówką.

I inne rozwiązanie założony jest umieszczenie płótna do div samej wielkości i mają zastosowanie następujące css do tego div:

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

I obrót należy zastosować do tego zawijającego div. Tak wymienione rozwiązanie działa, ale z niewielką modyfikacją.

Zmodyfikowanym przykładem takiego rozwiązania jest: https://jsfiddle.net/tLbxgusx/2/

Uwaga: Zobacz styl div z klasą „trzecią”.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.