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


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;

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


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;


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);

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);

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;}


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;
        }

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)


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 🎉


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.


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.


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'.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.