Imposta l'opacità dell'immagine di sfondo senza influire sugli elementi figlio


214

È possibile impostare l'opacità di un'immagine di sfondo senza influire sull'opacità degli elementi figlio?

Esempio

Tutti i collegamenti nel piè di pagina richiedono un punto elenco personalizzato (immagine di sfondo) e l'opacità del punto elenco personalizzato deve essere 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%;
}  

Quello che ho provato

Ho provato a impostare l'opacità degli elementi dell'elenco sul 50%, ma anche l'opacità del testo del collegamento è del 50% - e non sembra esserci un modo per ripristinare l'opacità degli elementi figlio:

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

Ho anche provato a usare rgba, ma ciò non ha alcun effetto sull'immagine di sfondo:

#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%;
}


Risposte:


119

Puoi usare 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>


Questa è la soluzione migliore!
Dzenis H.

93

Porta la tua immagine in un editor di immagini, abbassa l'opacità, salvala come .png e usala invece.


8
Hmm ... Ho appena downvoted, ma un'occhiata a questa risposta accettata: stackoverflow.com/a/6502295/131809 upvoted 10 volte, e più o meno identici.
Alex

9
Questa è una buona opzione, non ho idea del perché così tanti voti negativi. Se potessi votare questo due volte lo farei. Un elemento figlio di un elemento padre parzialmente opaco sarà parzialmente opaco, e dovrebbe esserlo. Tutti i "workaround" sono bug che dovrebbero essere corretti.
RobW,

6
@mystrdat Stai già scaricando l'immagine, questa non è una richiesta aggiuntiva.
Brad

2
@mystrdat Ma sta già scaricando l'immagine della freccia. Non hai fornito una soluzione senza immagini, quindi quello era il mio punto. Sta già scaricando l'immagine della freccia, potrebbe anche venire, se necessario, il che non sarebbe una richiesta aggiuntiva. Non capisco da dove vieni.
Brad

1
@brad Mi scuso, ho scoperto che ho letto male la domanda ora che ho controllato di nuovo.
mystrdat,

42

Funzionerà con ogni browser

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; 
}

Se non si desidera che la trasparenza influisca sull'intero contenitore e sui relativi figli, controllare questa soluzione alternativa. Devi avere un figlio assolutamente posizionato con un genitore relativamente posizionato.

Controlla la demo su http://www.impressivewebs.com/css-opacity-that-doesnt-affect-child-elements/


Penso che sia necessario modificare le "virgolette nel codice sopra riportato in" affinché funzioni
correttamente

6
questa risposta è ancora la migliore soluzione che le persone hanno trovato al problema di: "come fare in modo che un elemento figlio non erediti il ​​valore di opacità CSS dell'elemento padre"? Ho bisogno che il bambino sia davvero un bambino .. e nel flusso di documenti ... e inoltre non voglio portare javascript / flash per questo; preferisci CSS puro.
govinda,

Ho il 50% di padre opaco <li> che contiene immagini figlio che voglio opaco al 100%. Impostare <li> su position:relative;e img su position:absolute;NON mi consente di ignorare l'opacità ereditata su img, e non posso usare il posizionamento assoluto per gli <li> stessi (è un casino ;-). In Javascript ho provato imgs[i].style.opacity = '1';, ma anche questo non funziona per ignorare l'opacità ereditata. Se ho capito bene, non posso nemmeno usare rgba perché ho bisogno di influenzare le img stesse, non solo un colore di sfondo. Qualcuno ha una raccomandazione per me?
govinda,

26
Tutta questa risposta non ha senso. Il codice dato, oltre ad essere esattamente ciò che il richiedente non vuole fare perché non funziona , non corrisponde alla descrizione o al collegamento. Sto facendo fatica a capire perché così tante persone lo hanno votato.
BoltClock

Se la domanda fosse "Come impostare il 50% di trasparenza su un elemento", questa sarebbe una buona risposta.
Lharby,

29

Se stai usando l'immagine come un punto elenco, potresti considerare lo 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;
}

3
Filter è solo una soluzione IE
Hussein,

1
Penso che questa sia probabilmente la soluzione migliore. È una soluzione CSS pura. È anche possibile hackerare il supporto di IE7 usando *zoom: expression( … );(vedi : after e: before css pseudo elements hack per IE 7 ), ma IE7 sta finalmente diventando passé.
terzo


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;
}

Hack con opacità .99 (meno di 1) crea un contesto z-index in modo da non poterti preoccupare dei valori globali di z-index. (Prova a rimuoverlo e vedi cosa succede nella prossima demo in cui il wrapper principale ha z-index positivo.)
Se il tuo elemento ha già z-index, non hai bisogno di questo hack.

Demo di questa tecnica .


Sai perché dobbiamo impostare un valore inferiore a 1 per l'opacità? È una soluzione cross-browser?
zVictor,

1
@zVictor sì, questo è un comportamento standardizzato da w3c. Vedere Informazioni su CSS z-index: il contesto di impilamento .
utente

4

Sfortunatamente, al momento di scrivere questa risposta, non esiste un modo diretto per farlo. Devi:

  1. usa un'immagine semi-trasparente per lo sfondo (molto più semplice).
  2. aggiungi un elemento extra (come div) accanto ai bambini di cui vuoi l'opaco, aggiungi lo sfondo e dopo averlo reso semitrasparente, posizionalo dietro i bambini menzionati.

4

Un'altra opzione è l' approccio CSS Tricks per inserire uno pseudo elemento delle dimensioni esatte dell'elemento originale proprio dietro di esso per falsare l'effetto di sfondo opaco che stiamo cercando. A volte dovrai impostare un'altezza per lo 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;   
}

3

La proprietà "filtro" ha bisogno di un numero intero per percentuale di opacità anziché doppia, per funzionare con IE7 / 8.

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

PS: inserisco questo come una risposta, dal momento che SO, ha bisogno di almeno 6 caratteri modificati per una modifica.


2

Per ottimizzare davvero le cose, ti consiglio di inserire le selezioni appropriate nei wrapper di targeting per browser. Questa è stata l'unica cosa che ha funzionato per me quando non sono riuscito a convincere IE7 e IE8 a "giocare bene con gli altri" (poiché attualmente sto lavorando per una società di software che continua a supportarli).

/* 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);
}

Potrei avere esuberi nel codice sopra - se qualcuno desidera ripulirlo ulteriormente, sentiti libero!


3
Non è necessario indirizzare ciascun browser separatamente, basta usare i prefissi del browser all'interno di un singolo blocco selettore. Con i prefissi del browser, il browser utilizzerà solo la proprietà CSS appropriata. Col passare del tempo e la sintassi per quella proprietà diventa standardizzata, i fornitori di browser lasceranno cadere il supporto per i prefissi e useranno la proprietà CSS senza alcun prefisso (ad esempio, Firefox ha abbandonato il supporto per -moz-border-radiusFirefox 13 e cerca solo la border-radiusproprietà standard ora). IE7 e IE8 sono una storia diversa, ma questo è solo IE :-p
terzo

Mi piacerebbe sapere chi l'ha votata e perché, per favore. Il voto è inutile senza feedback informativo. Mi piacerebbe poter migliorare le mie risposte. Se era solo perché le informazioni erano obsolete, controlla la data. :) Grazie.
code-sushi,

@ code-sushi: se il downvote si è verificato più o meno nello stesso momento del tuo commento, considera che potrebbe essere stato da qualcun altro che si è trovato d'accordo con il commento di un terzo (nota i voti sul commento stesso). Non ho votato sulla tua risposta, ma devo essere d'accordo - vorrei aggiungere che 1) KHTML non vedrà mai il -khtml-opacityperché non capisce la media query, rendendola inutile 2) IE è più stabile di quanto pensi; non "esploderà" solo perché aggiungi prefissi non IE a una regola che si applica a IE. Il problema, nel momento in cui lo hai affrontato, deve essere venuto da altrove.
BoltClock

La mia risposta originale era di quasi 2 anni fa e il voto negativo è avvenuto di recente, come quest'anno. Ero solo curioso. Per quanto riguarda i commenti di IE si riferivano a 7 quando era ancora necessario il supporto; Sono abbastanza sicuro che ora va bene nella maggior parte dei casi ignorare Internet Explorer 7 in questi giorni. Grazie per il tuo feedback
code-sushi,

1

Se devi impostare l'opacità solo sul punto elenco, perché non imposti il ​​canale alfa direttamente nell'immagine? A proposito, non penso che ci sia un modo per impostare l'opacità su un'immagine di sfondo tramite css senza cambiare l'opacità dell'intero elemento (e anche dei suoi figli).


1

Solo per aggiungere a quanto sopra .. è possibile utilizzare il canale alfa con i nuovi attributi di colore, ad es. rgba (0,0,0,0) ok quindi questo è nero ma con opacità zero, quindi come genitore non influenzerà il bambino. Funziona solo su Chrome, FF, Safari e .... I thin O.

converti i tuoi colori esadecimali in RGBA


4
Questo non funzionerà con background-imagequanto richiesto dall'OP.
Torsten Walter,


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;
    }

Puoi provare questo codice. Penso che funzionerà. Puoi visitare la demo

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.