css transform, bords dentelés en chrome

193

J'ai utilisé la transformation CSS3 pour faire pivoter des images et des zones de texte avec des bordures dans mon site Web.

Le problème est que la bordure est dentelée dans Chrome, comme un jeu (basse résolution) sans anti-crénelage. Dans IE, Opera et FF, cela semble beaucoup mieux car AA est utilisé (ce qui est toujours clairement visible mais pas si mal). Je ne peux pas tester Safari car je ne possède pas de Mac.

La photo pivotée et le texte lui-même ont l'air bien, seule la bordure est dentelée.

Le CSS que j'utilise est le suivant:

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

Existe-t-il un moyen de résoudre ce problème, par exemple en forçant Chrome à utiliser AA?

Exemple ci-dessous:

Exemple de bords dentelés

dtech
la source
Pour ceux qui le liront plus tard: il devrait être corrigé dans Chrome à partir de la version 15 (novembre 2011), mais Safari a introduit exactement le même problème dans 5.1 pour Mac qui n'est pas encore résolu pour le moment
dtech
Et ils l'ont si bien réparé, qu'il est impossible de revenir en arrière. Nous avons des cas où l'anticrénelage est la dernière chose que nous voulons, mais maintenant Chrome / Chromium / Safari n'a pas de méthode pour désactiver l'anticrénelage dans les images transformées, bien qu'il s'agisse d'images 1 bit (par exemple, b / w gif). Le flou est tellement cool, tellement cool, plus de flou est plus cool, disent-ils! Le seul moyen de garantir des bords nets est de tout convertir en chemins ou objets svg et d'ajouter l'attribut shape-render = "crispEdges".
Timo Kähkönen
Pour moi, le problème est avec les bordures transparentes utilisées pour créer une flèche. C'est dans Chrome 40 sur win et mac. Aucune des options ici ne résout le problème.
Gurnard

Réponses:

389

Au cas où quelqu'un chercherait cela plus tard, une bonne astuce pour se débarrasser de ces bords irréguliers sur les transformations CSS dans Chrome est d'ajouter la propriété CSS -webkit-backface-visibilityavec une valeur de hidden. Dans mes propres tests, cela les a complètement lissés. J'espère que cela pourra aider.

-webkit-backface-visibility: hidden;
Neven
la source
7
Lifesaver - cette astuce nous a permis de réactiver -webkit-transform sur un certain nombre de sites que nous étions auparavant obligés de désactiver les transformations en raison de problèmes d'anti-aliasing. Merci!
Darren
toute aide à ce sujet: stackoverflow.com/questions/9235342/… ?
abernier
5
Cela fonctionne dans Chrome, mais cela les rend à nouveau irréguliers dans iOS 6!
lezd
11
@lazd pour le corriger dans iOS ajouterpadding: 1px; -webkit-background-clip: content-box;
Rob Fletcher
2
@RobFletcher a ajouté un rembourrage et un clip d'arrière-plan qui semblent, par ce fil, essentiels à une solution cross-browser et cross-os. Cela corrige également mon problème OSX / Chrome ... Je pense qu'une solution complète serait quelque chose comme:padding: 1px;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-background-clip:content-box;background-clip:content-box;
Benjamin Luoma
120

Si vous utilisez transitionau lieu de transform, -webkit-backface-visibility: hidden;ne fonctionne pas. Un bord dentelé apparaît pendant l'animation pour un fichier png transparent.

Pour le résoudre, j'ai utilisé: outline: 1px solid transparent;

mhhorizon
la source
4
cela semble aider dans les situations où la propriété web-kit-backface-visibilité n'a pas été détectée.
dgibbs
2
Fonctionne pour moi quand aucun des autres ne l'a fait. Avant d'ajouter cette propriété, Chrome Android avait des problèmes. Maintenant, tous les navigateurs semblent fonctionner correctement.
Bernie Sumption
Fonctionne pour moi dans Safari sur iOS 8.
Moritz Friedrich
Solution parfaite. Les autres n'ont pas fonctionné. J'ai failli abandonner et je doutais que cela fonctionnerait. Mais c'est le cas!
Garconis
1
Fonctionne parfaitement pour mes besoins. J'utilise en effet la transition, et les autres réponses provoquaient la pixellisation de mon PNG à son état par défaut. Votre réponse a aidé à supprimer toute pixelisation - à la fois sur l'état par défaut et pendant la transition. Parfait!
Garconis
24

L'ajout d'une bordure transparente 1px déclenchera l'anti-aliasing

outline: 1px solid transparent;

Alternativement, ajoutez une ombre transparente transparente de 1px.

box-shadow: 0 0 1px rgba(255,255,255,0);
Callam
la source
rgba (255, 255, 255, 0) est probablement mieux
mmm
4
L'ajout de la section supérieure de CSS dans votre réponse et cela outline: 1px solid transparent;a bien fonctionné pour moi. Les autres solutions ci-dessus ne fonctionnaient pas assez bien.
Timothy Zorn
outline: 1px solid transparent;déclencher l'anti-aliasing également dans Firefox 52 (qui a les mêmes problèmes que Chrome)
Luca Detomi
18

Essayez la transformation 3D. Ça fonctionne super bien!

/* Due to a bug in the anti-liasing*/
-webkit-transform-style: preserve-3d; 
-webkit-transform: rotateZ(2deg);
Zypherone
la source
1
en essayant cela dans Chrome maintenant (août 2013 sur Mac), la solution acceptée ne fonctionne pas, mais son utilisation (en particulier preserve-3d; rotatepeut toujours être utilisée sans passer à rotateZ) le fait.
Dave
Super hacky, mais a fonctionné pour moi. Essayez même un degré plus petit comme 0,05 pour éviter un mauvais alignement visible.
cpursley
préserv-3d m'a sauvé la vie.
Hannes Schneidermayer
8

La réponse choisie (ni aucune des autres réponses) n'a pas fonctionné pour moi, mais cela a:

img {outline:1px solid transparent;}

chris
la source
2

J'ai eu un problème avec un gradient CSS3 avec -45deg. Le backgroundslanted, était mal dentelé similaire mais pire que le poste d'origine. J'ai donc commencé à jouer avec les deux background-size. Cela étirerait la déchirure, mais elle était toujours là. Ensuite, en plus, j'ai lu que d'autres personnes avaient également des problèmes à des incréments de 45 degrés, j'ai donc ajusté de -45degà -45.0001deget mon problème a été résolu.

Dans mon CSS ci-dessous, background-sizeétait initialement 30pxet le degdégradé d'arrière-plan était exactement -45deg, et toutes les images clés l'étaient 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;
        }
Pegues
la source
1

Vous pourrez peut-être masquer les irrégularités en utilisant des ombres de boîte floues . L'utilisation de -webkit-box-shadow au lieu de box-shadow garantira que cela n'affectera pas les navigateurs non-webkit. Vous voudrez peut-être vérifier Safari et les navigateurs Webkit mobiles.

Le résultat est un peu meilleur, mais toujours beaucoup moins bon qu'avec les autres navigateurs:

avec ombre de boîte (dessous)

dtech
la source
1

Je pensais juste que nous jetterions aussi notre solution car nous avions exactement le même problème sur Chrome / Windows.

Nous avons essayé la solution de @stevenWatkins ci-dessus, mais nous avons toujours eu le "stepping".

Au lieu de

-webkit-backface-visibility: hidden;

Nous avons utilisé:

-webkit-backface-visibility: initial;

Pour nous, cela a fait l'affaire 🎉

Nicholas McCreath
la source
1

L'ajout de ce qui suit sur le div entourant l'élément en question a corrigé cela pour moi.

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

Les bords dentelés apparaissaient autour de la fenêtre vidéo dans mon cas.

chaser7016
la source
0

Pour moi, c'est la propriété CSS en perspective qui a fait l'affaire:

-webkit-perspective: 1000;

Complètement illogique dans mon cas car je n'utilise pas de transitions 3D, mais fonctionne quand même.

Aron
la source
0

Pour canvas en Chrome (Version 52)

Toutes les réponses répertoriées concernent les images. Mais mon problème concerne le canevas en chrome (v.52) avec transformation rotation. Ils sont devenus irréguliers et toutes ces méthodes ne peuvent pas aider.

Solution qui fonctionne pour moi:

  1. Agrandir la toile sur 1 px pour chaque côté => +2 px pour la largeur et la hauteur;
  2. Dessinez une image avec un décalage + 1px (en position 1,1 au lieu de 0,0) et une taille fixe (la taille de l'image doit être 2px inférieure à la taille du canevas)
  3. Appliquer la rotation requise

Blocs de code si importants:

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

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

Remarque: il y a beaucoup de divs imbriqués car c'est une version simplifiée de mon projet.


Ce problème est également reproduit pour Firefox pour moi. Il n'y a pas un tel problème sur Safari et FF avec rétine.

Et une autre solution fondée consiste à placer le canevas dans un div de même taille et à appliquer le CSS suivant à ce div:

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

Et la rotation doit être appliquée à cette div enveloppante. La solution listée est donc travaillée mais avec de petites modifications.

Et l'exemple modifié d'une telle solution est: https://jsfiddle.net/tLbxgusx/2/

Remarque: Voir le style de div avec la classe «troisième».

Kiryl
la source