264

Is it possible to set the opacity of a background image without affecting the opacity of child elements?

Example

All links in the footer need a custom bullet (background image) and the opacity of the custom bullet should be 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%;
}  

What I've Tried

I tried setting the opacity of the list items to 50%, but then the opacity of the link text is also 50% - and there doesn't seem to be a way to reset the opacity of child elements:

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

I also tried using rgba, but that doesn't have any effect on the background image:

#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%;
}
Stickers
  • 75,527
  • 23
  • 147
  • 186
jmohr
  • 4,706
  • 4
  • 29
  • 29

15 Answers15

252

You can use CSS linear-gradient() with 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>
Stickers
  • 75,527
  • 23
  • 147
  • 186
  • 7
    Really nice trick and exactly what I was looking for, thanks – Mike Nov 28 '20 at 06:24
  • Please @jmohr mark this answer as the right one. – Despertaweb Mar 15 '21 at 15:15
  • This answer is so clever I overlooked it at first. I'm not all that clever though so.. Thanks for sharing. – dibs Jul 19 '21 at 06:24
  • @stickers may i ask if say i want to make it to a lighter opacity so which numbers or decimals should i add in the rgba? thanks – J_Y Aug 30 '21 at 09:09
  • @JaeYing adjust *alpha* value, and same value in both [rgba](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/rgba()), otherwise there will be gradients. – Stickers Oct 29 '21 at 18:09
  • Thanks. This solution works as expected when using `url()` with `.svg` image files. – OXiGEN Sep 04 '22 at 12:50
  • Awesome! Anyway to achieve this with 2 background images? Original Code: ► background-image: url(https://example.com/image1.png), url(https://example.com/image2.png); With your CSS: ► background-image: linear-gradient(rgba(255,255,255,0.5), rgba(255,255,255,0.5)), url(https://example.com/image1.png), linear-gradient(rgba(255,255,255,0.3), rgba(255,255,255,0.3)), url(https://example.com/image2.png); This results in both images showing, but Image1 turns white & Image2 has no change. If I remove the CSS in front of the 2nd URL, both images show, but only the Image1 is at 0.5 opacity. – nnamerz Nov 15 '22 at 23:40
  • Is there a way to achieve the same thing but with relative path? – holydragon Apr 25 '23 at 02:54
  • Absolutely wonderful, best known way to add an overlay to images directly – Sarang Kakkoth Jun 07 '23 at 15:15
103

Take your image into an image editor, turn down the opacity, save it as a .png and use that instead.

Ionică Bizău
  • 109,027
  • 88
  • 289
  • 474
2ToneKenobi
  • 1,421
  • 1
  • 9
  • 2
  • 9
    Hmm... i just downvoted, but look at this accepted answer: http://stackoverflow.com/a/6502295/131809 upvoted 10 times, and pretty much identical. – Alex Nov 07 '12 at 15:56
  • 10
    This is a good option, no idea why so many downvotes. If I could upvote this twice I would. A child element of a partially opaque parent element is going to be partially opaque, and should be. All "workarounds" are bugs that should eventually be fixed. – RobW Nov 28 '12 at 21:17
  • It is not a "good" option as it fires +1 http request and needs to load additional data. – zrooda Dec 11 '12 at 15:44
  • 6
    @mystrdat You're already downloading the image, this isn't an extra request. – brad Feb 22 '13 at 04:47
  • @brad You don't need to download an image at all, that's the point. – zrooda Feb 25 '13 at 13:21
  • 2
    @mystrdat But he is already downloading the arrow image. You haven't provided a non-image solution, so that was my point. He's already downloading the arrow image, it might as well come as needed, which would not be an extra request. I'm not understanding where you're coming from. – brad Mar 02 '13 at 21:17
  • 1
    @brad I apologize, turns out I've read the question wrong now that I checked again. – zrooda Mar 05 '13 at 16:54
  • This will work of course, but as for opacity, I would vote for using the image inside a separate span/div inside the li tag and just applying opacity to it instead of the solution above (or pretty much all of them here) as that leaves some fine animation options opened and doesn't require any hardcode resource editing. – zrooda Mar 05 '13 at 17:00
  • What if you're working with dynamically updated images? Poor solution. – master_gracey Jul 11 '13 at 03:16
  • What about Linux users? We don't have Photoshop. I edited your answer. :-) – Ionică Bizău Aug 31 '13 at 17:53
  • This is not the right answer. It works in some sense, but does not allow one to play around with the opacity except for making a slew of images. This *should* be able to be done with css. – abalter Sep 20 '13 at 20:23
  • On the other hand this is quite usefull when you create modal windows. – cptnk Feb 11 '14 at 16:19
  • Well, the sad but straight truth! – Mark Lalor Aug 25 '15 at 04:53
  • It works, but what if he wants to use the same image with two different type of opacity depending if you click or not on it? In your solution he will be using two images slowing down the download time of the page if he has many images to do so with, wile if we used a code, he could use one and the same image except different opacity levels on it. – SeekLoad Jul 24 '20 at 20:23
  • What if the image licence allows reuse but only without modification? This answer doesn't help there as the image file itself has been modified. – Alex Ander Apr 27 '22 at 08:45
42

This will work with every 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; 
}

If you don't want transparency to affect the entire container and its children, check this workaround. You must have an absolutely positioned child with a relatively positioned parent.

Check demo at http://www.impressivewebs.com/css-opacity-that-doesnt-affect-child-elements/

alex
  • 479,566
  • 201
  • 878
  • 984
Hussein
  • 42,480
  • 25
  • 113
  • 143
  • I think you need to change the ” quotes in the above code to " in order for it to work when straight copy-pasted. – nsantorello Feb 06 '12 at 16:44
  • 6
    is this answer still the best solution people have found to the problem of: "how to make a child element not inherit the parent element's CSS opacity value"? I need the child to really be a child.. and in the document flow... and also do not want to bring in javascript/flash for this; prefer pure CSS. – govinda May 14 '12 at 19:58
  • I have 50% opaque parent
  • 's containing child images which I want 100% opaque. Setting the
  • to `position:relative;` and the img to `position:absolute;` does NOT allow me to override the inherited opacity on the img, and I can't use absolute positioning for the
  • 's themselves (that's a mess ;-). In Javascript I tried `imgs[i].style.opacity = '1';`, but that also does not work to override the inherited opacity. If I understand correctly, I also can't use rgba because I need to affect the imgs themselves, not just a background color. Anyone have a recommendation for me?
  • – govinda May 14 '12 at 21:11
  • 28
    This entire answer makes no sense. The given code, on top of being precisely what the asker **does not want to do** because **it doesn't work**, does not match the description, or the link. I'm having a very hard time understanding why so many people have upvoted it. – BoltClock Aug 31 '14 at 06:41
  • If the question was 'How to set 50% transparency on an element', this would be a good answer. – lharby Apr 25 '19 at 09:52