soy Kseso y esto EsCSS

Desheredando opacity

Desheredando opacity

·Por Kseso ✎ 3

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

  1. opacity se puede declarar a todos los elementos.

  2. 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
  3. No se hereda pero el valor computado afecta (se aplica) por igual al elemento declarado y a todo su contenido y descendientes.
  4. 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.

avatar del Editor del blog

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 Don Kseso Kseso