programming & spanish & web Franchu on 22 Jan 2008 06:01 pm
Problemas de renderizado sub-pixel en CSS
Cuando me encontré el artículo de John Resig titulado Sub-Pixel Problems in CSS pensaba que había leido mal. Para mi los pixels eran unidades indivisibles, algo así como cuando de pequeño te dicen que el átomo es la parte más pequeña de la materia y luego te das cuenta que hay más cosas dentro… pues así me he sentido cuando he entendido lo que quería decir. Por eso he decidido traducir su artículo para que más gente lo pueda entender.
Para ilustrar el problema, basta pensar qué ocurre cuando tenemos 4 divs flotados, cada uno de ellos con una anchura del 25%, contenidos en un div padre de 50px de ancho. ¿Qué anchura tiene cada div?
El problema es que cada div debería de tener 12.5px de anchura, pero como no se pueden renderizar fracciones de pixeles los navegadores tienen que redondear el número. Entonces el problema se convierte en saber, cómo redondear el número. ¿Redondeamos hacia arriba, hacia abajo, aleatoriamente? Los resultados son sin duda sorprendentes!
Se pueden ver tres formas diferentes de hacerlo y los efectos que tienen sobre el resultado final:
- Redondear hacia abajo - Tanto Opera como Safari redondean hacia abajo las anchuras de los divs. En este caso el redondeo convierte los divs a una anchura de 12px, dejando un hueco de 2px (se puede apreciar la zona verde) a la derecha de todos los divs. Si alguna vez te has planteado porqué tu página cuidadosamente alineada no llena el contenedor en estos navegadores, esta es la respuesta. La ventaja es que por lo menos sabes que la anchura de estos contenedores será siempre la misma, independientemente del valor que pongas.
- Redondear hacia arriba - Tanto Internet Explorer 6 como Internet Explorer 7 redondean las anchuras de todos los divs hacia arriba, pasando en este caso a tener 13px. Haciendo esto hacen que los divs flotados no quepan a lo ancho y se coloquen debajo, destrozando la maquetación. Esto es obviamente incorrecto y es la causa de que muchas veces la maquetación se vaya al traste sin motivo aparente.
- Redondear algunos números hacia arriba y otros hacia abajo - Tanto Firefox 2 como Firefox 3 mezclan la política de redondeo apareciendo divs con 12px y otros con 13px. La mezcla se hace de tal forma que la anchura final encaje con la del contenedor, haciendo que se ajuste correctamente a los bordes externos. El efecto colateral es que los divs ya no tienen una anchura consistente (aunque esta hubiese sido definida como tal en el CSS!). Además, cuando se pregunta al navegador la anchura del div devuelve 12.5px constantemente no permitiendo al usuario saber cómo se ha realizado el redondeo a la hora de renderizar el div. Para añadir más confusión todavía, el orden en el cual se asignan los anchos de 12px y 13px se ha cambiado entre las versiones 2 y 3 de Firefox teóricamente para mejorar la eficiencia y la velocidad, aunque en la realidad parece que tiene un efecto mínimo (si es que lo tiene!)
David Baron, uno de los desarrolladores de Mozilla, explica la situación muy bien:
Estamos intentando ajustarnos a muchos requisitos que no pueden ser satisfechos simultáneamente:
- 4 objetos adyacentes con alturas/anchuras de 25% (por ejemplo) empezando en un borde de un contendor tiene que terminar exactamente en el borde del otro; no debería haber en ningún caso pixeles extra en el contenedor y nunca deberían descolocarse por ser demasiado ancho.
- Los objetos adyacentes lógicamente, deberían siempre tocarse visualmente; no debería haber huecos de un pixel o superposiciones de un pixel debido a errores de redondeo.
- Los objetos con la misma anchura deberían de ocupar el mismo número de pixels.
La que Mozilla sacrifica normalmente es la tercera, excepto en los bordes en la que se sacrifica la primera al redondear las anchuras a pixeles enteros mucho antes.
Lo más curioso es que no existe una forma de hacerlo bien o mal. La especificación de CSS no define cómo se tienen que renderizar estos casos. Las restricciones de arriba podrían ser utilizadas en todos los navegadores, pero hay que sacrificar alguna de ellas para que sean consistentes y se puedan llevar a la práctica.
Es bastante frustrante, pero tenerlo en cuenta seguro que nos salva de muchas horas de frustración!
No related posts.
on 27 Jan 2008 at 18:55 1.Víctor said …
En mi opinion no existe tal cosa como medio pixel. Tal vez en photoshop o en algun programa de edicion de gráficos. Pero a nivel de navegadores no. Almenos no debería. Por lo que no recomendaría usar medidas como “11.5px”, mucho menos cuando queremos determinar una medida fija mediante CSS.
on 28 Jan 2008 at 2:39 2.Franchu said …
Hola Victor,
Obviamente no existen las fracciones de pixel y ese es el problema. Cuando se utilizan en CSS porcentajes, no se puede saber a priori cuanto va a ocupar en pixels ese elemento y es posible que matemáticamente el resultado sea un número no entero de pixels.
El problema es cómo hace el navegador para redondear ese número, y puesto que no existe una forma estándar de hacerlo los layouts se pueden descolocar en función del navegador empleado.
on 18 Feb 2008 at 22:24 3.Diego said …
Que tal Franchu’s lair.
La verdad que muy bueno lo que he leido, desde ya gracias por traducir éste articulo.
Me cierran algunas cosas, en este mundo de CSS, que mas de alguna vez me ha hecho doler la cabeza.
on 20 Feb 2008 at 0:02 4.Juan said …
Aciertas de pleno utilizando la palabra FRUSTRACIÓN eso es lo que he sentido en mis propias carnes cuando tras horas y horas de trabajo todo va más o menos bien en la mayoría de los navegadores pero en IE todo se ve diferente. Execelente trabajo con la traducción.
Lo cierto es que no andaba buscando ésto pero me alegra haberlo encontrado. Gracias de nuevo…
Juan
on 21 Feb 2008 at 4:37 5.diarioTHC | Problemas renderizado CSS said …
[…] “qué ocurre cuando tenemos 4 divs flotados, cada uno de ellos con una anchura del 25%, contenidos en un div padre de 50px de ancho. ¿Qué anchura tiene cada div?”. Problemas, eso ocurre, la explicación: Problemas de renderizado sub-pixel en CSS […]
on 12 Mar 2008 at 3:14 6.No existe medio pixel | beeBlog said …
[…] medio pixel”, pensaba que era solo un problema mío, pero navegando por la web he encontrado este enlace, donde traducen un interesante artículo acerca de como los navegadores renderizan el […]