De PNGs transparentes, navegadores y onLoads va la cosa
29 de May, 2008. Escrito por [Q]boss en Flash, Navegadores, Recursos, XHTML + CSS, [Q] interactiva, javascript
En el estudio he tenido que emplear PNGs transparentes, que como sabeís (y sino, deberíais) no son soportados por versiones de Internet Explorer 6 o anteriores, sino que vienen soportadas desde la versión 7 de nuestro amigo IE.
Hasta aqui no hay gran problema, porque empleando un pngfix de javascript se arregla el entuerto (bonito palabro).
-
/*
-
Correctly handle PNG transparency in Win IE 5.5 & 6.
-
http://homepage.ntlworld.com/bobosola. Updated 18-Jan-2006.
-
Use in <HEAD> with DEFER keyword wrapped in conditional comments:
-
<!--[if lt IE 7]>
-
<script defer type="text/javascript" src="pngfix.js"></script>
-
<![endif]-->
-
*/
-
-
var arVersion = navigator.appVersion.split("MSIE")
-
var version = parseFloat(arVersion[1])
-
-
if ((version>= 5.5) && (document.body.filters))
-
{
-
for(var i=0; i<document.images.length; i++)
-
{
-
var img = document.images[i]
-
var imgName = img.src.toUpperCase()
-
if (imgName.substring(imgName.length-3, imgName.length) == "PNG")
-
{
-
var imgID = (img.id) ? "id='" + img.id + "' " : ""
-
var imgClass = (img.className) ? "class='" + img.className + "' " : ""
-
var imgTitle = (img.title) ? "title='" + img.title + "' " : "title='" + img.alt + "' "
-
var imgStyle = "display:inline-block;" + img.style.cssText
-
if (img.align == "left") imgStyle = "float:left;" + imgStyle
-
if (img.align == "right") imgStyle = "float:right;" + imgStyle
-
if (img.parentElement.href) imgStyle = "cursor:hand;" + imgStyle
-
var strNewHTML = "<span " + imgID + imgClass + imgTitle
-
+ " style=\"" + "width:" + img.width + "px; height:" + img.height + "px;" + imgStyle + ";"
-
+ "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader"
-
+ "(src=\'" + img.src + "\', sizingMethod='scale');\"></span>"
-
img.outerHTML = strNewHTML
-
i = i-1
-
}
-
}
-
}
El tema se complicó (no iba a ser todo tan sencillo...) cuando además metía un evento onLoad para el body con la intención de lanzar una función javascript, y paso a describir el caso porque puede ser de ayuda para quien se encuentre en la situación:
LO QUE QUEREMOS LOGRAR
Tenemos una imagen de fondo de un cierto peso en KB (ya que no es una trama, sino una imagen plena de faculades), y sobre esa imagen han de colocarse unos botones que a su vez son imágenes, y que para que quede medianamente bonito han de ser transparentes.
PRIMER PROBLEMA
El primer problema es que la imagen de fondo que se crea por CSS, pesa lo suficiente como para que se dé durante unos segundos la situación de aparecer los botones sin el fondo que les da "sentido", un efecto poco deseable.
SOLUCIÓN PRIMER PROBLEMA
Para solucionarlo buscamos si existía algun método mediante CSS o XHTML para forzar la carga de los elementos de la hoja de estilos antes que se renderizara el HTML, pero..... no lo hemos encontrado. Si algún alma caritativa sabe cómo lograrlo mediante CSS (o de una manera más limpia que la que hemos empleado nosotros) que no dude en contárnosla.
Jorge tuvo la feliz idea de poner la misma imagen con propiedad display:none en el comienzo del body, con lo que la imagen se carga como HTML impidiendo así que se muestre lo que va a continuacion hasta que se completa dicha carga, y luego el CSS no tarda nada de tiempo en cargarla porque está en caché. Mientras esto ocurre, el div con los botones transparentes, permanece oculto también con la propiedad display, para por javascript hacerlo visible en el onLoad de la página.
SEGUNDO PROBLEMA
Cuando ya estábamos pegando saltos de alegría con el trabajo terminado, vemos que nuestro querido IE 6 no muestra los botones, no así en IE 7 o en firefox....
SOLUCIÓN SEGUNDO PROBLEMA
El problema es debido a la mala compatibilidad del pngfix con métodos invocados en el onLoad. La solución pasa por usar una variante del pngfix (que ha salido a la luz porque también da problemas con el swfobject) y que permite mezclar estas dos necesiades: pngfix y onLoad. Lo que hicimos es "googlear" y emplear el citado pngfix adaptado además de colocar la llamada al mismo DESPUÉS (y ojo que esto es necesario para que se dispare el evento onLoad) de la etiqueta de apertura de BODY. Cuando decimos la llamada nos referimos a esto:
-
<!–[if lt IE 7]>
-
<script defer type=”text/javascript” src=”pngfix.js”></script>
-
<![endif]–>
El resultado lo podéis ver aquí, por cierto, la web está recien salida del horno... diseño por takeone dsgn y programación flash y adaptación del blog por [Q].
Comments
5 Responses to “De PNGs transparentes, navegadores y onLoads va la cosa”
Leave a Reply
Llegaste a probar con algo como esto ?
http://www.cmacias.com/png-transparente-con-css/
Pues mira no lo había probado y seguro que no tiene el problema del onLoad
Me hubiera ahorrado una buena comedura de cabeza..
El css que indicas en el post, sabes si es compatible con todos los navegadores.. y por otro lado, las imágenes han de tener asociada la clase “png”?
No es necesario tener asociada la clase.
Si le pones el condicional del Explorer (
) evidentemente no te carga en el resto de navegadores que ya traen soporte para png transparente. En explorer 6 que es donde debería funcionar, lo hace perfectamente, ya que es donde hice las pruebas.
Aún así y por si quedara alguna duda, te adjunto la url del artículo original
http://www.komodomedia.com/blog/2007/11/css-png-image-fix-for-ie/
Hummm…. y esto?
.selected .barra_izq{
background-image:url(grafico.png) !important;
background-image:none;
filter: none !important;
filter:
progid:DXImageTransform.Microsoft.AlphaImageLoader(src=’grafico.png’);
overflow:hidden;
}
eso para mi tiene una pinta horrible… es que odio las hojas de estilo con “trucos” para que haya cosas que las lean unos navegadores y otros no, ya que a mi modo de ver pueden provocar que con la llegada de nuevos navegadores, se te complique la vida