css transform, bordes dentados en cromo

193

He estado usando CSS3 transform para rotar imágenes y cuadros de texto con bordes en mi sitio web.

El problema es que el borde parece irregular en Chrome, como un juego (de baja resolución) sin Anti-Aliasing. En IE, Opera y FF se ve mucho mejor porque se usa AA (que todavía es claramente visible pero no está tan mal). No puedo probar Safari porque no tengo una Mac.

La foto girada y el texto en sí se ven bien, solo el borde se ve irregular.

El CSS que uso es este:

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

¿Hay alguna forma de solucionar esto, por ejemplo, forzando a Chrome a usar AA?

Ejemplo a continuación:

Ejemplo de bordes dentados

dtech
fuente
Para aquellos que lo lean más tarde: debería corregirse en Chrome a partir de la versión 15 (noviembre de 2011), pero Safari introdujo exactamente el mismo problema en 5.1 para Mac que aún no está solucionado
dtech
Y lo arreglaron tan bien, que retroceder es imposible. Tenemos casos en los que el antialiasing es lo último que queremos, pero ahora Chrome / Chromium / Safari no tiene ningún método para desactivar el antialiasing en las imágenes transformadas, aunque son imágenes de 1 bit (por ejemplo, b / w gif). ¡El desenfoque es tan genial, tan genial, más borroso es más genial, dicen! La única forma de garantizar bordes nítidos es convertirlos a rutas u objetos svg y agregar el atributo shape-rendering = "crispEdges".
Timo Kähkönen
Para mí, el problema es con bordes transparentes utilizados para crear una flecha. Esto está en Chrome 40 en win y mac. Ninguna de las opciones aquí soluciona el problema.
Gurnard

Respuestas:

389

En caso de que alguien busque esto más adelante, un buen truco para deshacerse de esos bordes irregulares en las transformaciones CSS en Chrome es agregar la propiedad CSS -webkit-backface-visibilitycon un valor de hidden. En mis propias pruebas, esto los ha suavizado por completo. Espero que ayude.

-webkit-backface-visibility: hidden;
Neven
fuente
77
Salvavidas: este truco nos ha permitido volver a habilitar -webkit-transform en varios sitios que anteriormente nos veíamos obligados a desactivar las transformaciones debido a problemas de suavizado. ¡Gracias!
Darren
alguna ayuda en esto: stackoverflow.com/questions/9235342/… ?
abernier
55
Esto funciona en Chrome, ¡pero los hace irregulares nuevamente en iOS 6!
Lazd
11
@lazd para arreglarlo en iOS agregarpadding: 1px; -webkit-background-clip: content-box;
Rob Fletcher
2
@RobFletcher agregó relleno y clip de fondo que parecen, según este hilo, esenciales para una solución de navegador cruzado y cruce. Esto también soluciona mi problema de OSX / Chrome, así que ... Creo que una solución completa sería algo como:padding: 1px;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-background-clip:content-box;background-clip:content-box;
Benjamin Luoma
120

Si está utilizando en transitionlugar de transform, -webkit-backface-visibility: hidden;no funciona. Aparece un borde irregular durante la animación para un archivo png transparente.

Para resolverlo utilicé: outline: 1px solid transparent;

mhhorizon
fuente
44
Esto parece ayudar en situaciones en las que se perdió la propiedad web-kit-backface-visibilidad.
dgibbs
2
Funciona para mí cuando ninguno de los otros lo hizo. Antes de agregar esta propiedad, Chrome Android tenía problemas. Ahora todos los navegadores parecen funcionar correctamente.
Bernie Sumption
Funciona para mí en Safari en iOS 8.
Moritz Friedrich
Solución perfecta. Los otros no funcionaron. Casi me rendí, y dudaba que esto funcionara. Pero lo hace!
Garconis
1
Funciona perfectamente para mis necesidades. De hecho, estoy usando la transición, y las otras respuestas estaban causando que mi PNG se pixelara en su estado predeterminado. Su respuesta ayudó a eliminar cualquier pixelización, tanto en el estado predeterminado como durante la transición. ¡Perfecto!
Garconis
24

Agregar un borde transparente de 1 px activará el suavizado

outline: 1px solid transparent;

Alternativamente, agregue una sombra de cuadro transparente de 1px.

box-shadow: 0 0 1px rgba(255,255,255,0);
Callam
fuente
rgba (255, 255, 255, 0) es probablemente mejor
mmm
44
Agregar la sección superior de CSS en su respuesta y outline: 1px solid transparent;funcionó bien para mí. Las otras soluciones anteriores no funcionaron lo suficientemente bien.
Timothy Zorn
outline: 1px solid transparent;desencadenar anti-aliasing también en Firefox 52 (que tiene los mismos problemas de Chrome)
Luca Detomi
18

Prueba la transformación 3d. Esto funciona como un encanto!

/* Due to a bug in the anti-liasing*/
-webkit-transform-style: preserve-3d; 
-webkit-transform: rotateZ(2deg);
Zypherone
fuente
1
Al intentar esto en Chrome ahora (agosto de 2013 en una Mac), la solución aceptada no funciona, pero usar esto (específicamente preserve-3d; rotatetodavía se puede usar sin cambiar a rotateZ) sí.
Dave
Súper hacky, pero funcionó para mí. Pruebe incluso un grado menor como 0.05 para evitar una alineación errónea visible.
cpursley
preserve-3d me salvó la vida.
Hannes Schneidermayer
8

La respuesta elegida (ni ninguna de las otras respuestas) no funcionó para mí, pero esto sí:

img {outline:1px solid transparent;}

Chris
fuente
2

He tenido un problema con un gradiente CSS3 con -45deg. El backgroundinclinado, era muy irregular, similar pero peor que la publicación original. Entonces comencé a jugar con ambos background-size. Esto alargaría la irregularidad, pero todavía estaba allí. A continuación, además leí que otras personas están teniendo problemas también a 45 grados incrementos por lo ajusté a partir -45degde -45.0001degy mi problema fue resuelto.

En mi CSS a continuación, background-sizeestaba inicialmente 30pxy el deggradiente de fondo era exactamente -45deg, y todos los fotogramas clave eran 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
fuente
1

Es posible que pueda enmascarar las irregularidades con sombras de cuadro borrosas . El uso de -webkit-box-shadow en lugar de box-shadow se asegurará de que no afecte a los navegadores que no sean webkit. Sin embargo, es posible que desee consultar Safari y los navegadores webkit móviles.

El resultado es algo mejor, pero aún mucho menos bueno que con los otros navegadores:

con sombra de caja (parte inferior)

dtech
fuente
1

Pensé que también incluiríamos nuestra solución, ya que teníamos exactamente el mismo problema en Chrome / Windows.

Intentamos la solución de @stevenWatkins arriba, pero aún así tuvimos el "paso".

En vez de

-webkit-backface-visibility: hidden;

Nosotros usamos:

-webkit-backface-visibility: initial;

Para nosotros esto hizo el truco 🎉

Nicholas McCreath
fuente
1

Agregar lo siguiente en el div que rodea el elemento en cuestión solucionó esto para mí.

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

Los bordes irregulares aparecían alrededor de la ventana de video en mi caso.

chaser7016
fuente
0

Para mí fue la propiedad de perspectiva de CSS lo que hizo el truco:

-webkit-perspective: 1000;

Completamente ilógico en mi caso, ya que no uso transiciones 3D, pero funciona de todos modos.

Aron
fuente
0

Para lienzo en Chrome (Versión 52)

Todas las respuestas enumeradas son sobre imágenes. Pero mi problema es sobre el lienzo en cromo (v.52) con transformación rotar. Se hicieron irregulares y todos estos métodos no pueden ayudar.

Solución que funciona para mí:

  1. Haga el lienzo más grande en 1 px para cada lado => +2 px para ancho y alto;
  2. Dibuje la imagen con desplazamiento + 1px (en la posición 1,1 en lugar de 0,0) y tamaño fijo (el tamaño de la imagen debe ser 2px menor que el tamaño del lienzo)
  3. Aplicar la rotación requerida

Tan importantes bloques de código:

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

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

Nota: hay muchos divs anidados porque es una versión simplificada de mi proyecto.


Este problema también se reproduce para Firefox . No existe tal problema en Safari y FF con retina.

Y otra solución fundada es colocar el lienzo en un div del mismo tamaño y aplicar el siguiente CSS a este div:

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

Y la rotación debe aplicarse a esta envoltura div. La solución listada funciona pero con una pequeña modificación.

Y el ejemplo modificado para tal solución es: https://jsfiddle.net/tLbxgusx/2/

Nota: Vea el estilo de div con la clase 'tercera'.

Kiryl
fuente