Ir directamente al contenido de esta página

opacity: sí, mola… ¿y la legibilidad?

Modificar la opacidad de un elemento es una de las novedades de CSS3 que los desarrolladores estamos deseando poder aplicar en nuestros proyectos. Pero dejando a un lado la cuestión sobre el soporte de opacity en los navegadores actuales, hay que valorar su impacto en la accesibilidad y la usabilidad de un diseño.

Al rediseñar nuestro blog, aproveché para aplicar un poco de CSS3, algo que en los proyectos para nuestros clientes no siempre tengo la oportunidad de hacer. Y como siempre me han gustado los efectos de semitransparencia, quería incluir algunos en la hoja de estilo. Así que repasé el boceto del módulo de color y me puse manos a la obra.

opacity

La primera opción que se encuentra en el módulo es la propiedad opacity que, como su nombre indica, sirve para especificar la opacidad de un elemento, definida ésta por un valor decimal comprendido entre 0 (totalmente transparente) y 1 (totalmente opaco).

He aquí un ejemplo de la sintaxis:


opacity:0.5;
		

Su belleza reside en su simplicidad, sobre todo porque hasta ahora empleábamos para lograr el mismo efecto un PNG asignado como imagen de fondo, y aunque lográbamos la semitransparencia, opacity presenta algunas ventajas:

  1. Se reduce el número de peticiones al servidor. Aunque los PNG empleados para tal fin suelen ser archivos que no llegan a pesar medio kilobyte, la reducción de peticiones siempre es una mejora de rendimiento.
  2. Se puede implementar como una mejora progresiva. Cuando se emplea un PNG para lograr un efecto de semitransparencia, no se puede asignar un color de fondo al elemento como medida de seguridad para el caso de que la imagen no se cargue —dado que eso anularía el efecto—. Con opacity, si el agente de usuario no interpreta la propiedad, mostrará el fondo sólido del color asignado.
  3. Se agiliza el desarrollo. Gracias a que la opacidad es una propiedad más que se aplica al elemento, se pueden probar distintos colores de fondo sin necesidad de generar un nuevo archivo .png.
  4. Se evitarían los problemas que presenta la interpretación del canal alfa de los PNG en IE6. Es bien sabido que para que una imagen en ese formato muestre correctamente su transparencia en este navegador hay que aplicar un filtro.

Además de todo esto, su soporte en los navegadores modernos está bastante extendido. La excepción es Internet Explorer, cuyas versiones hasta la fecha carecen de soporte para la propiedad opacity. No obstante, cuentan con filter, su própio código propietario para lograr el mismo efecto. Su sintaxis, en este caso, sería:


filter:alpha(opacity=50);
		

No vamos a entrar ahora en las cuestiones de sí se debe o no emplear código propietario —puesto que no es ese el tópico de la entrada—, sino que, superado el escollo de Explorer, es cuando se presenta el verdadero problema que plantea la opacidad de un elemento: en muchas ocasiones puede mermar la legibilidad de su contenido. Y esto afecta a cualquier navegador, independientemente de que emplee una propiedad estándar o no.

El problema

Al aplicar opacity y hacer semitransparente un elemento, su contenido también deja entrever el fondo sobre el que se sitúa, lo que en algunos casos dificulta su lectura.

Veamos una aplicación muy popular de los fondos semitransparentes: el pie de una imágen. La idea es que el texto que acompaña a la misma se superponga a ésta, y que su fondo permita entrever la porción de la imagen que oculta:

Un ejemplo del uso de opacity que merma la legibilidad [Mozilla Firefox 3.5]

Como se puede observar, el texto del pie se vuelve también semitransparente, y los cambios de tono dificultan su lectura.

Y no se trata de un problema de implementación, sino que en el boceto de la especificación se indica que ese es el comportamiento correcto, como se desprende de la definición del valor alfa de opacity (el resaltado es nuestro):

Syntactically a <number>. The uniform opacity setting to be applied across an entire object. Any values outside the range 0.0 (fully transparent) to 1.0 (fully opaque) will be clamped to this range. If the object is a container element, then the effect is as if the contents of the container element were blended against the current background using a mask where the value of each pixel of the mask is <alfavalue>.

CSS Color Module Level 3, 3.2 Transparency: the ‘opacity’ property

Traducido al común, quiere decir que por definición el canal alfa asignado a un elemento debe aplicarse a todos y cada uno de sus descendientes, y eso incluye los nodos de texto.

Como a veces soy muy listo, se me pasó por la cabeza la idea de englobar el texto en algún elemento y a ese aplicarle una opacidad que corrigiera el valor computado heredado por el padre. Pero si se revisa la cita de arriba, eso no tiene sentido: los valores superiores a 1 se igualan a este valor, por lo que el alfa máximo de cualquier elemento puede igualar pero no superar el de su padre. En definitiva, estas reglas…


#padre{
  opacity:0.5;
}

#padre #hijo{
  opacity:1.5;
}
		

…son inútiles.

Así, para el ejemplo anterior, el problema de la legibilidad persiste.

¿Alguna alternativa?

Sí: rgba(). Básicamente, se trata de una extensión del modelo de color RGB definido ya en CSS2, y que incluye un cuarto parámetro, el valor del canal alfa. Como en el caso de opacity, su valor se sitúa entre 0 y 1, y su sintaxis es la siguiente:


propiedad-que-acepte-un-color:rgba(255,255,255,0.5);

// Por supuesto, también se puede asignar los valores así:

propiedad-que-acepte-un-color:rgba(100%,100%,100%,0.5);
	

Nótese que rgba() no es una propiedad, sino un valor. Eso significa que se puede aplicar a cualquier propiedad que acepte un valor de tipo <color> de manera independiente. Si reescribimos el ejemplo anterior asignando al pie el color de fondo de esta manera:


background:rgba(0,0,0,0.7);
	

la semitransparencia se aplica exclusivamente al fondo, no a su contenido. Comparando ambos ejemplos:

Comparativa: opacity vs. rgba() (ampliación) [Mozilla Firefox 3.5]

vemos que la legibilidad mejora sensiblemente en el segundo.

Problemas con rgba()

Aunque el empleo de rgba() presenta ventajas sobre el de opacity, no está exento de inconvenientes:

  1. Menor soporte en los navegadores. Para datos más concretos, dejamos abajo una tabla detallada.
  2. No hay alternativa para Explorer, ni siquiera en su versión 8. A diferencia de opacity, no existe un filtro específico de Explorer que reproduzca el efecto de rgba().

Llegados a este punto, tenemos dos opciones: intentar desarrollar una solución que incluya un plan B para los navegadores que no soporten rgba(), o cambiar nuestra forma de pensar.

Con respecto a la primera posibilidad, podemos idear algo como esto:


<style type="text/css">
  pre{
    background:url('imagenes/fondo_semitransparente.png');
    
    /* Asignamos como fondo nuestro .png, para los
       navegadores que lo interpreten correctamente */

    background:rgba(0,0,0,0.7);

    /* Redefinimos el valor del fondo; como empleamos
       la propiedad global para el mismo, a la vez que
       asignamos el color eliminamos la imagen. Los
       navegadores que no soporten rbga() ignorarán
       esta declaración y mantendrán la anterior */
  }
</style>

<!--[if IE6]-->
<style type="text/css">
  pre{
    filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='imagenes/fondo_semitransparente.png',sizingMethod='scale');  

    /* Éste es el filtro que corrige la interpretación 
       del canal alfa para IE6, de ahí que lo incluyamos
       en un comentario condicional */

    background:none; 
    
    /* Esta última línea evita que bajo el fondo filtrado 
       siga apareciendo el mosaico del .png no filtrado 
       (que bloquearía el efecto de semitransparencia) */
  }
</style>
<![endif]-->
		

De hecho, era una de las opciones que tenía a mi disposición al crear la hoja de estilo de este mismo blog —quería que los pre presentaran una ligera semitransparencia—. No obstante, esta solución dista de ser ideal:

  1. Si mi imagen de fondo no se carga —o el usuario deshabilita las imágenes—, la imposibilidad de definir un fondo opaco alternativo deja abierta la posibilidad de que las líneas se vuelvan ilegibles.
  2. En los navegadores que sí interpretan rgba(), sigo descargando una imagen que se vuelve inútil, con lo que pierdo una de las ventajas que indicaba al principio de esta entrada.
  3. Esta aplicación de filter a una imagen de fondo no está exenta de problemas adicionales, aunque en este caso concreto no se den.

Todo esto nos lleva a la segunda alternativa, la de cambiar nuestra forma de pensar. Ésta, a su vez, nos lleva a plantearnos una pregunta: ¿los sitios web necesitan verse exactamente iguales en todo navegador? Como estoy de acuerdo con Dan Cederholm, pienso que la solución está en abrazar plenamente la filosofía de la mejora progresiva, así que personalmente me bastó con esto:


pre{
  background:#464646;
  background:rgba(0,0,0,0.7);
}
		

Sí, en Explorer, Firefox 2 y las versiones de Opera previas a la 10 el fondo aparecerá opaco… pero, como diría Andy Clarke, puedo vivir con ello.

Conclusiones

Tras todo lo dicho, ¿opacity tiene alguna utilidad? Pues la verdad es que sí:

En definitiva, como tantas otras veces, el problema no está la herramienta, sino en cómo se emplea.

Anexo

Recojemos en la tabla siguiente el soporte que tienen opacity y rgba() en algunos de los navegadores actuales:

Soporte de opacity y rgba() en algunos de los navegadores más comunes
Navegador opacity rgba()
Firefox 3.5
Firefox 3.0
Firefox 2.0 No
Safari 3.2.1
Safari 4 Beta
Safari 3.1.1
Safari (iPhone)
Opera 10
Opera 9.63 No
Chrome 2.0
Chrome 1.0
Explorer 8 No No
Explorer 7 No No
Explorer 6 No No

Esta entrada se publicó el 24 de septiembre de 2009, se archivó en , y fue etiquetada como , . Autor: Saúl González Fernández. Hay 4 comentarios ›.

Comentarios

  1. Jhonn dice:

    Mis felicitaciones por un articulo tan explicativo. En mi caso yo tenía el problema con el opacity en un menú en Mootools: la transparencia al ul que solamente funcionaba en IE, pero el opacity daba al contenido de mi menu li, gracias al rgba solucioné mi problema. Estoy muy agradecido. Felicitaciones nuevamente por su artículo.

  2. kcmr dice:

    Bueno, hay una alternativa de esas guarrillas para Explorer:

    background: transparent; filter: progid:DXImageTransform.Microsoft.Gradient(StartColorStr=’#33000000′, EndColorStr=’#33000000′);

    A veces es menos problemático usar esto que hacer arreglos para que IE6 soporte la transparencia alpha en PNG’s

    Saludos

  3. Mario dice:

    Luché brutalmente en dreamweaver para lograr una simple tabla con un poco de transparencia… finalmente llegué a tu blog y logré lo que necesitaba. Excelente.

  4. Víctor dice:

    Muy bien explicado, tu artículo permite esquivar el truco del GIF/PNG, gracias.

¿Algún comentario?

* Los campos con un asterisco son necesarios

Últimos proyectos

© Digital Icon, S.L., 2007 – 2017