Establezca la opacidad de la imagen de fondo sin afectar los elementos secundarios

214

¿Es posible establecer la opacidad de una imagen de fondo sin afectar la opacidad de los elementos secundarios?

Ejemplo

Todos los enlaces en el pie de página necesitan una viñeta personalizada (imagen de fondo) y la opacidad de la viñeta personalizada debe ser del 50%.

HTML

<div id="footer">
    <ul>
        <li><a href="#">Link 1</a></li>
        <li><a href="#">Link 2</a></li>
        <li><a href="#">Link 3</a></li>
        <li><a href="#">Link 4</a></li>
        <li><a href="#">Link 5</a></li>
    </ul>
</div>  

CSS

#footer ul li {
    background: url(/images/arrow.png) no-repeat 0 50%;
}  

Lo que he probado

Intenté establecer la opacidad de los elementos de la lista al 50%, pero luego la opacidad del texto del enlace también es del 50%, y no parece haber una manera de restablecer la opacidad de los elementos secundarios:

#footer ul li {
    background: url(/images/arrow.png) no-repeat 0 50%;
    /* will also set the opacity of the link text */        
    opacity: 0.5;
}

También intenté usar rgba, pero eso no tiene ningún efecto en la imagen de fondo:

#footer ul li {
    /* rgba doesn't apply to the background image */
    background: rgba(255, 255, 255, 0.5) url(/images/arrow.png) no-repeat 0 50%;
}
jmohr
fuente

Respuestas:

119

Puedes usar CSS linear-gradient()con rgba().

div {
  width: 300px;
  height: 200px;
  background: linear-gradient(rgba(255,255,255,.5), rgba(255,255,255,.5)), url("https://i.imgur.com/xnh5x47.jpg");
}
span {
  background: black;
  color: white;
}
<div><span>Hello world.</span></div>

Pegatinas
fuente
¡Esta es la mejor solución!
Dzenis H.
93

Lleva tu imagen a un editor de imágenes, baja la opacidad, guárdala como .png y úsala en su lugar.

2ToneKenobi
fuente
8
Hmm ... acabo de votar, pero mira esta respuesta aceptada: stackoverflow.com/a/6502295/131809 votado 10 veces, y casi idéntico.
Alex
99
Esta es una buena opción, no tengo idea de por qué tantos votos negativos. Si pudiera votar esto dos veces, lo haría. Un elemento hijo de un elemento padre parcialmente opaco será parcialmente opaco, y debería serlo. Todas las "soluciones" son errores que eventualmente deberían corregirse.
RobW
66
@mystrdat Ya está descargando la imagen, esta no es una solicitud adicional.
Brad
2
@mystrdat Pero ya está descargando la imagen de la flecha. No ha proporcionado una solución que no sea de imagen, así que ese fue mi punto. Ya está descargando la imagen de la flecha, bien podría venir según sea necesario, lo que no sería una solicitud adicional. No entiendo de dónde vienes.
Brad
1
@brad Pido disculpas, resulta que he leído mal la pregunta ahora que lo revisé nuevamente.
mystrdat
41

Esto funcionará con todos los navegadores

div {
 -khtml-opacity:.50; 
 -moz-opacity:.50; 
 -ms-filter:"alpha(opacity=50)";
  filter:alpha(opacity=50);
  filter: progid:DXImageTransform.Microsoft.Alpha(opacity=0.5);
  opacity:.50; 
}

Si no desea que la transparencia afecte a todo el contenedor y sus elementos secundarios, consulte esta solución alternativa. Debe tener un hijo absolutamente posicionado con un padre relativamente posicionado.

Consulte la demostración en http://www.impressivewebs.com/css-opacity-that-doesnt-affect-child-elements/

Hussein
fuente
Creo que debe cambiar las "comillas en el código anterior a" para que funcione cuando se copia y pega directamente.
nsantorello
66
¿Sigue siendo esta respuesta la mejor solución que la gente ha encontrado para el problema de "cómo hacer que un elemento hijo no herede el valor de opacidad CSS del elemento padre"? Necesito que el niño sea realmente un niño ... y en el flujo de documentos ... y tampoco quiero traer javascript / flash para esto; Prefiero CSS puro.
govinda
Tengo 50% de padres opacos <li> que contienen imágenes secundarias que quiero 100% opacas. Establecer el <li> en position:relative;y el img en position:absolute;NO me permite anular la opacidad heredada en el img, y no puedo usar el posicionamiento absoluto para los <li> 's (eso es un desastre ;-). En Javascript lo intenté imgs[i].style.opacity = '1';, pero eso tampoco funciona para anular la opacidad heredada. Si entiendo correctamente, tampoco puedo usar rgba porque necesito afectar las imágenes en sí mismas, no solo un color de fondo. ¿Alguien tiene una recomendación para mí?
govinda
26
Toda esta respuesta no tiene sentido. El código dado, además de ser precisamente lo que el autor de la pregunta no quiere hacer porque no funciona , no coincide con la descripción o el enlace. Me cuesta mucho entender por qué tanta gente lo ha votado.
BoltClock
Si la pregunta fuera "Cómo establecer un 50% de transparencia en un elemento", esta sería una buena respuesta.
lharby
29

Si está utilizando la imagen como una viñeta, puede considerar el pseudo elemento: before.

#footer ul li {
}

#footer ul li:before {
    content: url(/images/arrow.png);
    filter:alpha(opacity=50);
    filter: progid:DXImageTransform.Microsoft.Alpha(opacity=0.5);
    opacity:.50;
}
Sr. Griever
fuente
3
El filtro es solo una solución IE
Hussein,
1
Creo que esta es probablemente la mejor solución. Es una solución pura de CSS. También es posible hackear el soporte de IE7 usando *zoom: expression( … );(ver : after y: before css pseudo elements hack for IE 7 ), pero IE7 finalmente se está volviendo pasado.
Thirdender
9
#footer ul li {
  position: relative;
  opacity: 0.99;
}

#footer ul li::before {
  content: "";
  position: absolute;
  width: 100%;
  height: 100%;
  z-index: -1;
  background: url(/images/arrow.png) no-repeat 0 50%;
  opacity: 0.5;
}

Hackear con opacidad .99 (menos de 1) crea un contexto de índice z para que no pueda preocuparse por los valores globales del índice z. (Intente eliminarlo y vea qué sucede en la próxima demostración donde el contenedor principal tiene un índice z positivo).
Si su elemento ya tiene un índice z, entonces no necesita este truco.

Demostración de esta técnica .

usuario
fuente
¿Sabes por qué necesitamos establecer un valor de opacidad inferior a 1? ¿Es una solución de navegador cruzado?
zVictor
1
@zVictor sí, este es un comportamiento estandarizado w3c. Consulte Comprender el índice z CSS: el contexto de apilamiento .
usuario
4

Desafortunadamente, al momento de escribir esta respuesta, hay hay una forma directa de hacerlo. Necesitas:

  1. use una imagen semitransparente para el fondo (mucho más fácil).
  2. agregue un elemento adicional (como div) al lado de los niños que desea que sea opaco, agregue un fondo y, después de hacerlo semitransparente, colóquelo detrás de los niños mencionados.
Reyraa
fuente
4

Otra opción es el enfoque de CSS Tricks de insertar un pseudo elemento del tamaño exacto del elemento original justo detrás de él para simular el efecto de fondo opaco que estamos buscando. A veces necesitará establecer una altura para el pseudo elemento.

div {
  width: 200px;
  height: 200px;
  display: block;
  position: relative;
}

div::after {
  content: "";
  background: url(image.jpg);
  opacity: 0.5;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  position: absolute;
  z-index: -1;   
}
kaleazy
fuente
3

La propiedad "filtro" necesita un número entero para el porcentaje de opacidad en lugar de doble, para que funcione para IE7 / 8.

filter: progid:DXImageTransform.Microsoft.Alpha(opacity=50);

PD: publico esto como respuesta, ya que SO necesita al menos 6 caracteres modificados para una edición.

lyubeto
fuente
2

Para ajustar realmente las cosas, recomiendo colocar las selecciones apropiadas en los contenedores de orientación del navegador. Esto fue lo único que funcionó para mí cuando no pude lograr que IE7 e IE8 "jugaran bien con los demás" (ya que actualmente estoy trabajando para una compañía de software que continúa apoyándolos).

/* color or background image for all browsers, of course */            
#myBackground {
    background-color:#666; 
}
/* target chrome & safari without disrupting IE7-8 */
@media screen and (-webkit-min-device-pixel-ratio:0) {
    #myBackground {
        -khtml-opacity:.50; 
        opacity:.50;
    }
}
/* target firefox without disrupting IE */
@-moz-document url-prefix() {
    #myBackground {
        -moz-opacity:.50;
        opacity:0.5;
    }
}
/* and IE last so it doesn't blow up */
#myBackground {
    opacity:.50;
    filter:alpha(opacity=50);
    filter: progid:DXImageTransform.Microsoft.Alpha(opacity=0.5);
}

Es posible que tenga redundancias en el código anterior; si alguien desea limpiarlo más, ¡no dude en hacerlo!

code-sushi
fuente
3
No es necesario apuntar a cada navegador por separado, solo use los prefijos del navegador dentro de un solo bloque selector. Con los prefijos del navegador, el navegador solo usará solo la propiedad CSS apropiada. A medida que pasa el tiempo y la sintaxis de esa propiedad se estandariza, los proveedores de navegadores dejarán de admitir los prefijos y usarán la propiedad CSS sin ningún prefijo (por ejemplo, Firefox dejó de admitir -moz-border-radiusen Firefox 13 y solo busca la border-radiuspropiedad estándar ahora). IE7 e IE8 son una historia diferente, pero eso es solo IE :-p
thirdender
Me gustaría saber quién votó en contra y por qué, por favor. El voto es inútil sin comentarios informativos. Me gustaría poder mejorar mis respuestas. Si fue solo porque la información estaba desactualizada, verifique la fecha. :) Gracias.
code-sushi
@ code-sushi: si el voto negativo se produjo aproximadamente al mismo tiempo que su comentario, considere que podría haber sido de otra persona que estuvo de acuerdo con el comentario de thirdender (observe los votos positivos en el comentario mismo). No voté por su respuesta, pero tengo que estar de acuerdo: me gustaría agregar que 1) KHTML nunca verá el -khtml-opacityporque no entiende la consulta de medios, por lo que es inútil 2) IE es más estable de lo que piensa; no "explotará" solo porque agrega prefijos que no son de IE a una regla que se aplica a IE. El problema, en el momento en que lo enfrentó, debe haber venido de otra parte.
BoltClock
Mi respuesta original fue de hace casi 2 años y el voto negativo ocurrió recientemente, como este año. Solo tenía curiosidad. En cuanto a los comentarios de IE, se referían a 7 cuando todavía necesitaba apoyo; Estoy bastante seguro de que está bien ahora en la mayoría de los casos ignorar IE 7 en estos días. Gracias por sus comentarios.
code-sushi
1

Si tiene que establecer la opacidad solo en la viñeta, ¿por qué no establece el canal alfa directamente en la imagen? Por cierto, no creo que haya una manera de establecer la opacidad de una imagen de fondo a través de CSS sin cambiar la opacidad de todo el elemento (y sus hijos también).

Minkiele
fuente
1

Solo para agregar a lo anterior ... puede usar el canal alfa con los nuevos atributos de color, por ejemplo. rgba (0,0,0,0) ok, entonces esto es negro pero con opacidad cero para que, como padre, no afecte al niño. Esto solo funciona en Chrome, FF, Safari y ... Adelgazo O.

convierte tus colores hexadecimales a RGBA

frontsideup
fuente
44
Esto no funcionará con lo background-imagesolicitado por el OP.
Torsten Walter el
1

Encontré un tutorial bastante bueno y simple sobre este tema. Creo que funciona muy bien (y aunque es compatible con IE, les digo a mis clientes que usen otros navegadores):

Transparencia de fondo CSS sin afectar elementos secundarios, a través de RGBa y filtros

Desde allí puede agregar soporte de gradiente, etc.

Francisco
fuente
Bueno, no funcionará directamente. Tendría que poner un div como elemento aparente con color de fondo: (255,255,255,0.5) por ejemplo
Francisco
0
#footer ul li
     {
       position:relative;
       list-style:none;
     }
    #footer ul li:before
     {
       background-image: url(imagesFolder/bg_demo.png);
       background-repeat:no-repeat;
       content: "";
       top: 5px;
       left: -10px;
       bottom: 0;
       right: 0;
       position: absolute;
       z-index: -1;
       opacity: 0.5;
    }

Puedes probar este código. Creo que se trabajará. Puedes visitar la demo

Jakir Hossain
fuente