Desheredando opacity 12.8.12
Desheredando opacity
Una sorpresa bastante desagradable de quienes se inician en Css es descubrir que la propiedad opacity pasa de padres a hijos y que no hay forma de anularla.
Así que de eso va esta entrada: cómo desheredar la propiedad opacity. O diversas formas de lograr el efecto de transparencia de forma selectiva al fondo o background pero no al resto de contenidos.
Opacity en la especificación
La propiedad opacity está recogida e el documento CSS Color Module Level 3 y es una propiedad que no existía en Css 2.1, esto es, fue introducida por primera vez en Css3.
La propiedad opacity define el grado de opacidad o transparencia* de un elemento.
Esto es, en qué medida el elemento al que se declara esta propiedad deja entrever lo que hay debajo (z-index) de él.
El valor de esta propiedad es un número comprendido entre 0.0 y 1
0.0 equivale una transparencia total. En la práctica es como declarar visibility: hidden;
1 hace al elemento totalmente opaco. Esto es, no permite ver en absoluto lo que se encuentre debajo de él (z-index).
* La expresión transparente en este artículo nada tiene que ver con el valor "transparent" de las propiedades que admiten un color como valor (background-color, color), sino con el los conceptos opaco, transparente y traslúcido: la posibilidad de un objeto para dejar pasar la luz (ver a través de él) o no y el grado en que lo hace.
Particularidades de opacity
opacity se puede declarar a todos los elementos.
- En valor por defecto o en ausencia de su declaración es 1. Los valores posibles están comprendidos en el rango numérico de 0.0 a 1
- No se hereda pero el valor computado afecta (se aplica) por igual al elemento declarado y a todo su contenido y descendientes.
- Por los puntos anteriores no es posible aumentar (hacer más próximo a 1) el grado de opacidad de un elemento
Aclaremos el punto 3 y 4 que es la fuente de los quebraderos de cabeza:
La herencia en CSS es el mecanismo mediante el cual el valor de ciertas propiedades se transmiten de un elemento padre a sus hijos.
Lo que sí se produce es que el valor computado de la propiedad se aplica, como ya resalté antes, al elemento al que se declara y a todo lo contenido en él.
Así que si un padre tiene un valor de opacity:0.X, como sólo se pueden dar valores entre 0 y 1, en sus hijos no hay manera de aumentar 0.X (hacerlo más próximo a 1) porque el producto de multiplicar un número por otro menor a 1 siempre es menor al original: 0.X*1=0.X
Conclusión: el título es erróneo, o de mejor onda, es una licencia que me he tomado.
Técnicas para desheredar opacity
Sigo con la licencia xD.
Cuando el efecto buscado es dotar a un elemento de cierto grado de transparencia al background o fondo sólamente, tradicionalmente, y en función de algunos considerandos, se solía recomendar:
Valores en RGBA o HSLA
Si el background es un color plano, la propiedad opacity se evita declarando los colores en notación rgba o hsla que incluyen como cuarto y último valor del color el canal alfa o transparencia del mismo.
Así un fondo negro con opacity:.5 es equivalente a:
background-color: rgba(0,0,0,.5);
Los contras: si das soporte a navegadores que no entienden estos valores
Uso de imágenes en .png
Usar una imagen en formato .png que soporta canal alfa. Ya fuese para formar un patrón o para un color plano.
Añadir etiquetas al html
En aquellos casos de no poder utilizar un .png ¿? cabe la posibilidad de añadir un elemento más en el marcado html dentro de nuestro contenedor. Posicionarlo de forma absoluta y darle las medidas necesarias con las propiedades de posicionamiento top/tight / bottom / left
A este elemento añadido se le aplica la imagen, bien vía background o vía img src="" y se le declara la propiedad opacity.
Sus hermanos (resto de contenido) se posicionarán sobre él y no serán afectados por opacity.
Un ejemplo aquí.
Esto supone tener que usar elementos innecesarios a mayores.
Pseudoelemento ::before
Esta forma es una variación de la anterior, pero con la ventaja de no "ensuciar" el html.
Básicamente consiste en utilizar el pseudoelemento ::before posicionado y con la imagen deseada en el background y la opacidad oportuna:
.elemento::before {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-image: url(...)...;
opacity: .6;
}
Adenda
Sobre la NO herencia de opacity:
Imagina dos elementos (padre e hijo). El primero (padre con opacity:.5). Si la propiedad opacity fuese heredada por el hijo, el valor computado para él sería 0.5*0.5=0.25 Cosa que no ocurre.
El hijo no hereda.
Y si no te lo acabas de creer, mira la captura de la especificación.

Kseso
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
Anotatelo!!... excelente, muy bien explicado, detalladamente y entregas una solución full...
ResponderEliminarhola llevo toda la tarde intentando comprender el tutorial, pero cada vez me asaltan más y más dudas.
ResponderEliminarHola, después de haber estado muchas horas intentando comprender este articulo, muy humilde opinión es que deja muchísimas cosas en el tintero. Creo que al artículo le faltan muchos ejemplos explicativos o con más detalle, ya que por ejemplo la solución “uso de imágenes png” no explica con detalle cómo lograrlo, si es simplemente poniendo una imagen en png o alguna otra tarea que se tenga que hacer, otras de las cosas que veo es que en una de las soluciones en concreto “añadir etiquetas al html” no se corresponde con el ejemplo puesto, ya que si se mira el código fuente y se lee la explicación hay diferencias, por ejemplo cuando se dice:
ResponderEliminar“cabe la posibilidad de añadir un elemento más en el marcado html dentro de nuestro contenedor. Posicionarlo de forma absoluta y darle las medidas necesarias con las propiedades de posicionamiento top/tight / bottom / left
A este elemento añadido se le aplica la imagen, bien vía background o vía img src="" y se le declara la propiedad opacity.”
El elemento que se añade según creo entender dice que se ponga en posición absoluta y darle las medidas necesarias, además también se le aplica la imagen y se le declara opacity. Veo en el código fuente que la caja que tiene la imagen no tiene ni posición absoluta ni opacity. Y la caja que tiene opacity no tiene ni background ni absoluta.
No sé si estaré en los cierto o estaré equivocado pero es lo CREO que he visto aquí y como dije arriba es mi humilde opinión.
Un saludo