Update in 2018: While we still don’t have something like background-opacity, we do now have rgba() and hsla() which would be the easy solution for solid colors like in this article.
Reader Shane left a comment:
If using transparency on a block element it makes the text inside transparent as well. Is there a way I can prevent that from happening? I tried putting the text in another div and setting the opacity to 100%, but that didn’t do the job. Although, logically, I thought it would!
Logically, that makes sense to me to. Is that how it works in practice? Of course not. This is, in my opinion, a major failing of CSS. People just expect that this is possible. It’s a very common effect in print design. Unfortunately, it’s just not so easy on the web. Here is one way out of this mess.
First, you create a bar making sure to use the CSS settings for all browsers. Here is the bar:
<div class="bar">
<h2>Some mild-mannered text trapped inside a bar.</h2>
</div>
And this is how you style it:
.bar {
height: 4em;
padding-top: 2em;
opacity: 0.5;
background: black;
border-top: 3px solid #ccc;
border-bottom: 3px solid #ccc;
margin-top: 5.0em;
}
This is where you notice that the text inside the bar as taken on the transparency of the bar itself. You don’t want that, it’s making the text hard to read! So you get smart and apply 100% transparency to the text inside the div. Doesn’t work right?
You’ll have to resort to some trickery.
As far as I know, there is just no way to force those child elements to be an less transparent than their parent element. And therein lies the solution. What if that child element wasn’t technically a child element.
As you likely know, just because an element occupies the same space as another element, doesn’t make one a child of the other. That’s the beauty of CSS positioning. So the trick to getting our non-transparent text into a transparent div is just to put that text outside of the div and push it visually inside with some CSS positioning.
Here is how we’ll do it:
<h2 class="ontop">Haha! I'm free of my transparent prison.</h2>
<div class="bar"></div>
Notice the class applied to the text. Now you’re going to have to do whatever you need to do with CSS positioning to get it where it needs to be. Negative margins are a popular way to do this. Here I just set the top position:
h2.ontop {
position: relative;
top: 4.7em;
}
Nice one, Chris. You’ve always got more ‘trickery’ up your sleeve.
Stumbled!
A much easier hack is to just set the background to a very small square of transparent png. Eg:
#bar{
background: url('black50.png');
}
Sure it’ll take a browser a few nanoseconds longer to load but it saves hassle. I keep a library of different transparency pngs in the most common colours for when I’m designing.
Tom
@Tom: That’s a nice little trick! That actually would work perfectly here with the bar solution since it’s a solid color. Really, utilizing image transparency instead of CSS transparency is a good solution to any version of this problem. It kind of opens the door to needing to use PNG hacks to guarantee results but that’s fine.
Much more useful having the text staying opaque!!
Well done.
A PNG would provide better compatibility (you have to use a filter: statement for IE6, but you’re already doing that anyway), but the better CSS3 method is just to use RGBA colours (e.g. background: rgba(0,0,0,0.5); will get you black at 50% alpha), that gets rid of any inherited opacity.
Neat solution!
This solution also works when you don’t know the size of the element you’re working with, it is easy and fast.
Thanks for the hint!
safari seems to render it differently than in Firefox
just what i need!
beautiful ;)
Good job! been trying to get my head around this for a long time….
Will this work on images? I need to make an image non transparent in my opacity div
@Jamie: Sure, it’ll work for images, perhaps it’s even easier since you typically know the exact height and width of images so you know exactly how much offset you will need.
thank you
Non-Transparent Elements Inside Transparent Elements
is working with ie7 but nit with Mozilla
Please help
Thank to share..I need sample non-Transparant image inside Transparent element bg….
#bar{
background: url(‘black50.png’); /* <– Much better, more versatile */
}
Just used that, and Yep, by using it, you do not have to worry one bit about nested divs inheriting the transparency of any parent div. Thanks a bunch!
-Yep
Some will say that im a pain in the ***, i already had this problem, solved it, but…
there’s always a but.
Here is what i did not solve :
what if you have a div which contains a paragraph, and of course, you need to apply transparency to div’s background and keep the paragraph’s text non-transparent ?
You will tell me, easy : use the method you used before !
You just can’t if you choose to size your div with your paragraph element’s size, unfortunately i have to (web is dynamic !)
I thought i could re-write a second time the paragraph’s content, over the first (that takes transparency) so i would have some non-transparent text; but i’m not happy with having two times the same content in my Html code…
So if anyone has an idea on how to fix this, i’d be glad to hear it…
Bye
hi dude,
i want the box with opacity but text inside content is without opacity.
i want color of text is white, and the result of box with opacity is the color of text is not white
please…
I have the same request as empe – I want transparent text, but opaque background. Is this possible?
@empe: That’s what this article explains how to do.
@black swan: You are asking for the opposite thing. Fortunately, this is easier. Just set the opacity of the text, not it’s container. As in:
Thanks for your reply, but I don’t think I explained myself properly in my last post.
I have a background picture, and text with a background colour on top of that. When I try to make the text transparent, the color of the background colour shows through – but I want the *background picture* to show through.
An example of the effect I want is shown at the website below, but that is using graphic files, not css. I am not sure if what I am aiming for is possible using css, but when I came across your thread I thought it wouldn’t hurt to ask.
http://www.karneval-berlin.de/de/
@black swan: Yes I see what you mean now. That’s not gonna happen with CSS. That is a knockout, not transparency. Pretty neat effect though.
Do you think it is possible to use this to create a transparent hover effect?.. I have seen one with java script. its pretty.
Please delete my previous comment.
Isn’t..
[div style=”border: 1px solid black;”]
[div style=” float:left”]bla bla bla..[/div]
[div style=”background-color: #91E391; opacity: 0.2″ ]{whitespace here}[/div]
[/div]
..another good way how to get the same effect?
Actually the behavior of inheriting transparency is perfectly logical.
You specify in your css that some block is not entirely opaque, you don’t specify the opacity of only it’s background (which you could do with css3 rgba colors or a transparent png as previously said). In practical terms, the whole block (including the text) is painted on a separate canvas, then this canvas is drawn over the parent block with the specified opacity.
This is exactely like layers in drawing softwares, if you specify the opacity of the layer, you affect everything inside that layer (including sublayers). If you want something drawn over it with more opacity, you create a separate layer over it to put your opaque content (which is exactely what you did with your additional div).
nice men ;)
is there a way to make it so EVERY image i ever post on my blog will not go transparent automatically. I’m VERY new to this so laments terms would be greatly appreciated.
At the moment i only have 1 picture on my blog but it’s background is white and it being see-through really makes it harder to understand
@hachaifair
exactly, ever since they introduced the opacity attribute ive used this technique. except i use a container div and relatively position the elements then give each its own opacity. i thought this was obvious
@alex
Using RGBA is a snap, thanks! But is there an easy hack for IE6/IE7?
The png works better for me too, at least when all you want to do is to put a transparent background for your container (image, text, image(s) + text, etc…).
I like the PNG idea, but how exactly does one create a PNG image with 50% transparency? I’ve created such an image in Paint Shop Pro, but when I save it as a PNG the image is saved with no transparency.
I tried the PNG trick. works well in firefox, not working in IE 6….
Well, well, well, looks like this little trick may be useful for some of us… but I’m trying to use it on a div that should slide in & out and it doesn’t work at all :/ who the hell said “yeah, nested divs should follow the transparency”?? That’s stupid, godammit.
You cannot use this “trick” when you are attempting to slide objects within a container using an “overflow:hidden” declaration — true. However, you can also work around this problem, simply by creating a pseudo :after or :before element, making it relative position to the parent, then adjust its opacity and place it with CSS accordingly. Worked like a charm for my use-case.
I visit your site all the time. Thanks all the good content! It has helped me become a better programmer and saved me lots of time!
Regards
You can also assign a 1px x 1px transparent image to the div, so you can forget about relative/absolute positioning.
This is maybe an old post, but assigning a color to the div like rgba(255,255,255,0.5) also does the trick (just figured it out)