soy Kseso y esto EsCSS

Corrige las distorsiones del texto en transformaciones 2D Css

Traducción al español del artículo de @zoltandulac "Fixing Typography Inside of 2-D CSS Transforms" con las solucciones para corregir el mal renderizado del texto dentro de las transformaciones 2D Css

Corrige las distorsiones del texto en transformaciones 2D Css

·Por Kseso ✎ 0

Si has usado transformaciones de Css, probablemente hayas observado que algunas veces el texto no es renderizado correctamente. Los caracteres se presentan con bordes dentados, desalineados respecto a la línea base y girados. Esto sucede desde que las transformaciones fueron introducidas en Firefox 3.6. Está documentado en la web por gente como Nicolas Gallagher

Pero antes de seguir, dejemos claro la autoría de todo el artículo y su título original:

Fixing Typography Inside of 2-D CSS Transforms

Créditos y reconocimiento de autoría

Zoltan "Du Lac" HawrylukTodo el contenido del artículo, así como las imágenes ilustrativas, es obra de:
Zoltan 'Du Lac' Hawryluk
@zoltandulac en twitter.
User Agent Man es su web.
El Artículo original [ING]
Yo sólo me limito a trasladarlo al español para su difusión con su conocimiento y beneplácito. Y ahora ya puedes seguir leyendo el post.

Si no sabes de qué estoy ablando echa un vistazo al siguiente ejemplo en Firefox, Chrome, Safari o Opera.

Ver Demo en JSFiddle

Si haces :hover sobre el bloque verde, verás que durante la transformacioón estas distorsiones se suavizan. Pero nada más terminar el giro vuelven a manifestarse.

En la captura de abajo verás ilustrado que este efecto es notoriamente más acusado en windows. Es menor en OS X y Linux y casi inapreciable en theiOS y Android en dispositivos móviles. Observa que el efecto apenas se presenta en todos los IE 9+. (¡Sí! ¡Por una vez y para variar IE hace las cosas bien!)

texto transformado con css en Firefox
Firefox en windows
texto transformado con css en Chrome
Chrome en windows
texto transformado con css en IE9
IE9 en windows

Así que ¿cómo areglarlo?

Solucción 1ª: Añade perspectiva

Para los navegadores Webkit/Blink (i.e. Chrome, Safari y Opera) la solucción es sencilla. Recordemos cómo girar un elemento -10º. El Css para hacerlo sería como sigue:

#elemento-girado { -webkit-transform: rotate(-10deg); -moz-transform: rotate(-10deg); -ms-transform: rotate(-10deg); -o-transform: rotate(-10deg); transform: rotate(-10deg); }

Un grupo de desarrolladores añadiran, a a la transformación, precediendo al giro, el valor translateZ(0) para forzar a la GPU el renderizado del elemento.

#elemento-girado { -webkit-transform:translateZ(0) rotate(-10deg); -moz-transform: rotate(-10deg); -ms-transform: rotate(-10deg); -o-transform: rotate(-10deg); transform: rotate(-10deg); }

Los desarrolladores vienen haciendo esto para mejorar la animación del elementos (especialmente en dispositivos móviles). Esto también mejora el renderizado del texto.

Desafortunadamente esto no funciona en Firefox, añadiéndolo a la declaración de su prefijo -moz-transform o la la reglada transform.

Afortunadamente hay una solucción que funciona tanto en navegadores Firefox como en Webkit: Usar perspective(1px) en vez de translateZ(0) (para forzar el renderizado por GPU).

Este es el código

#elemento-girado { -webkit-transform: perspective(1px) rotate(-10deg); -moz-transform: perspective(1px) rotate(-10deg); -ms-transform: rotate(-10deg); -o-transform: rotate(-10deg); transform: perspective(1px) rotate(-10deg); }

Observa que no se usa el valor perspective(1px) en todos los prefijos privativos porque "rompe" a IE9 y Opera 12.1 e inferiores (que usa Presto) debido a que no dan soporte a las transformaciones 3D (perspective) que es usado para determinar la intensidad del efecto 3D. Pero como estamos usando sólo transformaciones 2D no tendrá otro efecto que el de mejorar el dibujado en pantalla.

Si observas la demo de abajo en Safari, Chrome, Opera y Firefox notarás la diferencia en el texto respecto al primer ejemplo (el JSFiddle):

Ver Demo en JSFiddle

Aquí tienes este mosaico con las capturas de pantallas en diferentes navegadores en windows.

Distorsión del texto corregida con perspective()
Distorsión del texto corregida con perspective()

Solucción 2: filtro SVG y backface-visibility

borde dentado en firefoxSi vuelves a echar un vistazo al ejemplo con perspective(1px) en FIrefox, notarás un feo efecto dentado en el borde:/p>

Después de darle un par de vueltas observé que usando filtros SVG en el contenido del Html en vez de la solucción perspective() renderizaba el texto igualmente y además perfilaba el borde. Ante esto, elegí difuminarlo con un blur de 0 (que no afecta a la nitidez del elemento) pero que logra el efecto buscado.

Uso el data URI directamente en el Css para aplicar el filtro SVG para evitar descargar por separado el SVG.

El código todo junto quedaría así:

#elemento-rotado { /* el giro */ -webkit-transform: rotate(-10deg); -moz-transform: rotate(-10deg); -ms-transform: rotate(-10deg); -o-transform: rotate(-10deg); transform: rotate(-10deg); /*Solucción para navegadores WebKit/Blink*/ -webkit-backface-visibility: hidden; /*La corrección para Firefox ... sí, tiene que estar en una sola y larga línea*/ filter: url('data:image/svg+xml;utf8,<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><filter id="gaussian_blur"><feGaussianBlur in="SourceGraphic" stdDeviation="0" /></filter></defs></svg>#gaussian_blur'); }

Efectivamente, el Css para Firefox va en una sóla línea muy larga, pero ¡funciona!. Comprúebalo por ti mismo en la demo de abajo y toma nota que declaro -webkit-backface-visibility: hidden; en vez de la solucción previa de perspective(1px) en la propiedad -webkit-transform. Es otra forma de forzar la renderización por GPU de un elemento en Webkit y Blink.

Ver Demo en JSFiddle

Aquí tienes otra captura de pantalla para que lo veas su usas un navegador distinto a Firefox.

Dentado del borde suavizado con filto SVF
Dentado del borde suavizado con filto SVF

Ver demo del fix en acción

Otra solucción con Outline

También puedes utilizar la propiedad de Css outline para el borde aserrado

#relemento-girado { -webkit-transform: perspective(1px) rotate(-10deg); -moz-transform: perspective(1px) rotate(-10deg); -ms-transform: rotate(-10deg); -o-transform: rotate(-10deg); transform: perspective(1px) rotate(-10deg); outline: 1px solid transparent; }

Esta corrección puede que sea mejor en animaciones, ya que los filtros SVG en Firefox suponen mucha carga de trabajo a la CPU. Sin embargo no he realizado ningún text de rendimiento sobre este particular.

Otras notas

  1. El texto no aparece tan irregular en Firefox e IE en Windows 8 sin estos apaños. Es más, en algún caso puede que hasta se vean peor. Para más información sobre Windows 8 y el renderizado de la tipografía puedes leer el artículo ClearType takes a back seat for Windows 8 Metro de Long Zheng y Users keep reporting blurry text in Windows 8 and 8.1 de John Callham.
  2. renderizado texto rotado en ie 8 y 9 Sólo a título informativo, el funcionamiento de las demos en IE 8 e inferiores lo he realizado ayudado por IE Transforms Translator. La tipografía es un poco más gruesa que en IE9 en Windows 7, pero lo suficientemente decente. Aquí están algunas capturas de pantalla para comparar.

Créditos y reconocimiento de autoría

Zoltan "Du Lac" HawrylukDe nuevo. Todo el contenido del artículo así como las imágenes ilustrativas es obra de:
Zoltan 'Du Lac' Hawryluk
@zoltandulac en twitter.
User Agent Man es su web.
El Artículo original [ING]

Mis disculpas por los posibles seguros errores de interpretación y traducción del original. Si adviertes alguno déjame tu interpretación en los comentarios. Gracias.

avatar del Editor del blog

the obCSServer ᛯ Ramajero Argonauta, Enredique Amanuense de CSS.
#impoCSSible inside
Dicen que, en español, EsCss es el mejor blog de CSS. Posíblemente exageren.
@Kseso EsCss Kseso