Depurando CSS entre navegadores

Cuando desarrollamos una web generalmente lo hacemos para un navegador concreto. Durante el proceso (o al final de él, práctica nada recomendable si no queremos llevarnos sustos) tendremos que ir comprobando la web en el resto de navegadores. Dependiendo de varios factores (entre ellos, la calidad de nuestro código) nos llevaremos más o menos sorpresas, pero lo normal es que casi siempre encontremos inconsistencias entre navegadores.

Publicamos aquí una traducción del artículo Cross-Browser Debugging CSS, de Nicole Sullivan, en el que explica varias técnicas que nos ayudarán a la hora de depurar nuestro código y encontrar qué está haciendo que el diseño falle en algún navegador.


Estaba ayudando a Laura (una desarrolladora que trabaja conmigo) esta semana a aprender cómo depurar entre navegadores, y me animé a compartir mi procedimiento.

La principal premisa es simple: Trabaja con CSS, no contra él.

El CSS tiene un diseño subyacente y, cuando se trabaja con él utilizándolo del modo para el se diseñó, al final se acaba con muchos menos errores. Yo aprendí CSS leyendo las especificaciones del W3C, que es la razón por la cual empecé a escribir código acorde con el diseño del lenguaje, pero no importa dónde lo aprendierais vosotros, podéis captar algunos de los puntos clave implicados.

Lo primero que hago es escribir código para un buen navegador desde el principio. Nuestra elección es Google Chrome, principalmente por sus magníficas herramientas para desarrolladores. Cuando algo funciona en Chrome y estoy satisfecha con ello, lo compruebo en Safari o en Firefox.

Si hay alguna discrepancia entre estos buenos navegadores, lo más probable es que estéis trabajando contra CSS. No intentéis resolver con hacks las discrepancias entre buenos navegadores. Vuestro objetivo es averiguar *por qué* están interpretando el código de manera diferente. Normalmente hay una muy buena razón. Éstas son algunas de las cosas que compruebo si hay errores:

  • Interpretación del HTML: ¿Habéis olvidado cerrar alguna etiqueta? ¿Habéis metido un elemento de bloque dentro de un elemento inline? Cualquier cosa que se desvíe de los estándares será interpretada de modo diferente por cada navegador.
  • Comprobad vuestro CSS con CSS lint. Os dará una buena idea de los errores (¿falta un punto y coma?) que pueden estar volviéndoos locos. Para depurar diferencias entre navegadores, los errores son más interesantes que los avisos.
  • Se os olvidó usar un reset o normalize y el diseño se está basando en los (diferentes) estilos por defecto de los navegadores.
  • Diferencias de compatibilidad. ¿Estáis usando propiedades avanzadas de CSS3 o elementos HTML5? Comprobad su compatibilidad con los navegadores para aseguraros de que hay soporte para los que os interesan (esto lo hago normalmente en quirksmode). Si no, aún podréis usar esas estupendas propiedades, sólo tendréis que diseñar fallbacks adecuados para los navegadores atrasados. Por ejemplo, bordes en vez de sombras o esquinas rectas en vez de redondeadas.
  • Los márgenes no se están comportando correctamente. Si tenéis huecos extraños en sitios inesperados, lo más probable es que los márgenes estén colapsando de una manera no deseada.
  • Habéis creado un nuevo contexto de formato en un navegador, pero no en otro. Típicamente, esto ocurre como resultado de un uso demasiado entusiasta de la propiedad zoom:1 para forzar hasLayout en IE. Sí, hasLayout es esencialmente lo mismo que un nuevo contexto de formato en mejores navegadores.
  • Usar posicionamiento absoluto, sin establecer la posición horizontal y vertical. Por esta razón, el elemento con posición absolute tendrá la misma posición que si tuviera posición static. Pero si intentáis establecer alguno de los valores top, right, bottom o left, el elemento tendrá de repente una posición relativa al ascendiente más cercano que tenga position relative, haciendo que salte de lugar.
  • ¿Habéis realizado combinaciones no contempladas de diferentes tipos de display? Por ejemplo, las especificaciones no explican qué ocurre cuando se coloca un elemento con display:table-cell junto a un elemento flotante sin una fila de tabla o una tabla entre ellos. Esto no quiere decir que no podáis hacerlo, sino que si lo hacéis, os exponéis a errores potenciales y deberéis dedicar más tiempo a comprobar las diferencias entre navegadores.
  • ¿Los espacios están afectando a vuestro diseño? Casi nunca deseamos que la apariencia que genera nuestro CSS dependa de espacios en blanco, pero a veces ocurre, particularmente con displays inline e inline-block, y con imágenes, dado que se representan como bloques, pero que, a menos que les pongáis a todos display:block, no se comportan así.
  • Los errores de redondeo pueden causar diferencias de visualización. Todas las plantillas y grids flexibles tienen que trabajar con errores de redondeo por los decimales en los píxeles, y cada una encuentra diferentes modos de minimizar la visibilidad de esas diferencias.

Si no queréis leer nada más, leed los dos párrafos siguientes

Lo más importante que hay que tener presente es que los comportamientos erróneos no están definidos en las especificaciones. Si os salís de ellas, no se sabe qué os encontraréis. Lo más probable es que lo que os encontréis sea diferente en cada navegador. Si realizáis combinaciones poco convencionales (como usar márgenes con un elemento inline), tendréis diferencias entre navegadores.

Display

Yo me imagino CSS como un libro de Elige tu propia aventura. Cuando has tomado ciertas decisiones, otras se convierten en obvias. Por ejemplo, primero tenéis que elegir el tipo de display: block, inline, inline-block o table. Una vez elegido, tendréis una caja con las herramientas apropiadas para manipular el aspecto. Por ejemplo:

  • Los elementos tipo block deben usarse con margins, paddings, height y width. Line-height no es adecuado.
  • Los elementos tipo inline tienen line-height, vertical-align, y además pueden verse afectados por la presencia de espacios en blanco. No son adecuados los margins, paddings, heights ni widths.
  • Las tablas tienen alineamiento vertical y horizontal, y a veces pueden tener comportamientos extraños si tenéis un elemento de la tabla sin los demás (por ejemplo, una fila sin celdas). Los margins no son adecuados para filas de tabla ni para celdas. Los paddings no son adecuados para tablas ni para filas de tabla.

Si os ceñís a la caja de herramientas que viene de forma natural con vuestro tipo de display, tendréis muchos menos errores y diferencias entre navegadores.

Posicionamiento

Después, si elegisteis block, tenéis que elegir el mecanismo de posicionamiento (los demás generalmente se posicionan de acuerdo con el flujo normal). Para bloques podéis elegir:

  • Float: desplaza los bloques al extremo izquierdo o derecho. Si flotáis algo lo convertís en un elemento de tipo bloque, lo que se traducirá en que propiedades vertical-align o line-height previamente asignadas pueden dejar de funcionar.
  • Absolute: coloca el elemento relativamente a su ascendiente más cercano que tenga posicionamiento relativo. Tened presente que los elementos posicionados con absolute no modifican el flujo, y el flujo no les afecta a ellos cuando se cambian sus ascendientes o hermanos. Esto es una ventaja para las animaciones, pero puede causar problemas en el diseño si usáis demasiado posicionamiento absoluto con contenido actualizable dinámicamente (como el clásico ejemplo de las esquinas que no se mueven cuando se añade más contenido a la caja).
  • Static: el valor por defecto, así se consigue un elemento estándar en el flujo normal.
  • Fixed: coloca el bloque relativo a la ventana del navegador. Poco usado.
  • Relative: la mayoría de las veces no afecta al nodo al que se aplica, sino a los descendientes, cuyo posicionamiento absoluto se realizará respecto a este nodo.

No me he organizado lo suficiente como para enumerar todos los tipos de display y de posicionamiento y deciros cuáles pueden usarse o no con otras propiedades, por lo que tendréis que pensar por vosotros mismos cuando depuréis y escribáis código. Hay dos cosas importantes para considerar:

  1. ¿Esas propiedades cuadran con los tipos de display y posicionamiento que hemos elegido?
  2. ¿Van juntos los hermanos con los mismos tipos de posicionamiento?

Por ejemplo, ¿tiene sentido tener unos elementos float, table-cell e inline interactuando entre ellos? ¿Qué va a hacer el navegador con ellos? ¿Está definido en las especificaciones? Si no, probablemente estaréis yendo contra las bases de CSS. A veces esto puede no ser un problema, pero deberíais saber exactamente por qué lo habéis elegido y guardar tiempo extra para las comprobaciones entre diferentes navegadores.

Internet Explorer

Cuando hayáis resuelto todas las discrepancias entre los buenos navegadores, entonces estáis preparados para mirar en IE. Yo recomiendo empezar con la versión más antigua de las que queramos comprobar, porque en las nuevas siguen existiendo muchos errores (de manera ligeramente distinta), con lo que tendréis menos cosas que arreglar si empezáis por la peor versión.

Incluso con IE, es mejor intentar averiguar por qué está interpretando algo de manera diferente que simplemente arreglarlo con un hack. Añadir hacks * y _ a vuestro código es, queramos o no, como encontrarse con una función que devuelve un valor erróneo (digamos, 4 menos de lo que debería devolver) y simplemente añadirle la diferencia al resultado en vez de averiguar primero dónde se han hecho mal los cálculos.

return resultado+4;

Dicho esto, está bien y a veces es necesario usar hacks con IE6 y 7. IE8 sólo suele necesitar hacks por falta de soporte a CSS3 moderno. Si creéis que tenéis que usar hacks, intentad averiguar cuál es el error exacto con el que estáis tratando. Hay toneladas de recursos para esto en la red (¿alguien recuerda PIE?). Los problemas particulares que necesitan hacks en IE6 y 7 son:

  • Necesidad de añadir hasLayout con zoom:1.
  • Posicionamientos relativos que hacen desaparecer cosas.
  • El bug 3px float.
  • El bug al expandir un contenedor con float (¡útil!) y overflow hidden, que por desgracia “arregla” este bug tan útil.
  • ¿Tenéis un bug de IE favorito? Me encantaría leerlo en los comentarios.

Por supuesto, hay otros, pero éstos son los que he tenido que arreglar para OOCSS. Los demás ocurren con mucha menos frecuencia, como el bug de contenido duplicado cuando tienes dos elementos flotantes con un comentario entre ellos. No sé explicar cómo encontrar errores en IE porque la mayoría los he interiorizado. Como hablar en un idioma extranjero. Lo mejor que puedo sugerir es que examinéis cuidadosamente lo que veis y que elaboréis una buena descripción para buscarlo en Google. No empecéis a usar hacks hasta que encontréis el error. Las herramientas para desarrolladores de IE son horribles, así que quizás necesitéis usar colores de fondo para “ver” los problemas. Yo creo hojas de estilo de depuración para este propósito.

Aplicando soluciones

Cuando hayáis averiguado qué falla y sepáis cómo resolverlo, estáis preparados para averiguar cómo ponerlo en vuestro código sin romperlo todo. Éste es mi procedimiento:

  1. Delego en la cascada.
  2. Uso prefijos propietarios.
  3. Uso los hacks * y _ para IE6 y 7.
  4. Casi nunca uso \9 para IE8.
  5. Sé cuando parar de intentar arreglar IE.
  6. Nunca uso hacks para las últimas versiones de Firefox, Chrome o Safari.

Esto es mucho para recibir, así que a continuación voy a detallar cada punto.

Delegad en la cascada

Primero, delegad en la cascada siempre que sea posible. CSS tiene implementado un sistema natural de fallbacks. Los navegadores tienen en cuenta el último valor que son capaces de entender (la cascada fue diseñada para funcionar así). Esto significa que si ordenáis diferentes soluciones al mismo problema desde las menos hasta las más avanzadas, los navegadores usarán de modo natural la solución más avanzada que sean capaces de comprender. Por ejemplo:


.foo{
  background-color: #ccc; /* los navegadores antiguos usarán esto */
  background-color: rgba(0,0,0,0.2); /* los navegadores que entiendan rgba usarán esto */
}

Usad prefijos propietarios

La siguiente herramienta que tendréis que usar son los prefijos propietarios. Permiten establecer diferentes valores para diferentes navegadores, particularmente en propiedades que todavía no están estables.


background: #1e5799; /* Navegadores antiguos */
background: -moz-linear-gradient(top, #1e5799 0%, #2989d8 50%, #207cca 51%, #7db9e8 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#1e5799), color-stop(50%,#2989d8), color-stop(51%,#207cca), color-stop(100%,#7db9e8)); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, #1e5799 0%,#2989d8 50%,#207cca 51%,#7db9e8 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, #1e5799 0%,#2989d8 50%,#207cca 51%,#7db9e8 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(top, #1e5799 0%,#2989d8 50%,#207cca 51%,#7db9e8 100%); /* IE10+ */
background: linear-gradient(top, #1e5799 0%,#2989d8 50%,#207cca 51%,#7db9e8 100%); /* W3C */

Fijaos en las dos sintaxis para webkit. Al igual que los fallbacks para propiedades normales, los prefijos propietarios deben ordenarse de versión más antigua a más moderna, para que cada navegador utilice el mejor código que sea capaz de entender.

Si hay una sintaxis estándar hay que ponerla la última, para que mientras la compatibilidad con el estándar se va extendiendo, cada vez más navegadores utilicen el mejor código. Esto es lo que está marcado con un comentario “W3C” en el código anterior.

Usad hacks * y _ para IE6 y 7

Cuando hayáis identificado errores específicos de IE, y sepáis cómo queréis solucionarlos, usad los hacks _ y * para apuntar a ese navegador en particular. Por ejemplo:


.clearfix {
  overflow: hidden; /* nuevo contexto de formato en mejores navegadores */
  *overflow: visible; /* protege a IE7 y anteriores de la propiedad overflow */
  *zoom: 1; /* da hasLayout en IE, equivalente a un nuevo contexto de formato */
}

Todos los hacks para IE apuntan a un navegador determinado y a todos los anteriores a él. Por ejemplo:

  • _ apunta a IE6 y anteriores
  • * apunta a IE7 y anteriores
  • \9 apunta a IE8 y anteriores (ACTUALIZACIÓN: también apunta a IE9 para ciertas propiedades)

Esto significa que cuando uséis varios hacks, tenéis que ponerlos en orden; guión bajo, luego asterisco, luego \9.

Casi nunca se usa \9 para IE8

Dicho esto, realmente no he tenido que usar \9 para ningún arreglo en IE8. Simplemente lo uso para rellenar los huecos cuando hay diferencias de compatibilidad. Por ejemplo, si estoy usando box-shadows en navegadores modernos, y la caja se ve extraña sin nada alrededor en IE8, usaré \9 para añadir un borde para ese navegador. La técnica de la cascada no funcionaría en este caso, porque el método se usa con una propiedad diferente.

Hay que saber cuándo dejar de usar hacks para IE

No intentéis hacer todo exactamente igual en IE. Es importante pensar cuáles son los intereses más importantes de cada grupo de usuarios. ¿Gastaríais más peticiones HTTP, código HTML extra, JS y más código CSS para forzar las esquinas redondeadas en IE6-8? Para mí, la respuesta es un claro “No”.

Es importante saber cuándo parar con una característica particular. Por ejemplo, no uséis filtros para simular gradientes CSS3. Causan problemas de rendimiento y problemas en el diseño. Es mejor evitar el deseo de hacer vuestra web exactamente igual para cada navegador independientemente de sus capacidades. Los usuarios de IE6-8 están mucho mejor con una experiencia simplificada (no rota, sólo más simple) que con una web que despliega todo su arsenal de efectos usando un montón de polyfills, pero que es increíblemente lenta.

Por ejemplo, evitad el siguiente código para duplicar el gradiente del ejemplo anterior.


filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#1e5799', endColorstr='#7db9e8',GradientType=0 ); /* IE6-9 */

Nunca uséis hacks para apuntar a las últimas versiones de Firefox, Chrome o Safari

Finalmente, si creéis que necesitáis usar hacks para darles código diferente a Firefox, Chrome o Safari, es que algo se ha torcido bastante. Lo mejor es volver atrás y mirar lo que habéis escrito para ver si estáis yendo contra la esencia de CSS.


Artículo original: Cross-Browser Debugging CSS

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *