26

EDIT: Changed title to actually be correct

I'm trying to simulate a modal popup in all HTML and CSS and am having a bit of bad luck with one single element of what I'm doing. I want the innermost div, the one with the content, to not be opaque like the border is, but no matter what I try with the CSS I cannot get it to work. Here's the code:

The CSS

.modalBackground {
    background-color:Gray;
    filter:alpha(opacity=70);
    opacity:0.7;
}

The HTML

  <table style="height: 100%; width: 100%; position: fixed; top: 0; left: 0;"><tr><td class="modalBackground">
    <div style="display: table; height: 40px; width: 150px; position: fixed; overflow: hidden; 
        top: 40%; margin-top: -50px; left: 50%; margin-left: -75px; padding-left: 30px;
        border: solid 1px navy; background-color: White;">
        <div style="#position: absolute; #top: 50%; display: table-cell; vertical-align: middle;">
            <div style="#position: relative; #top: -50%;"
                ><asp:Image runat="server" ImageUrl= "~/images/indicators/indicatordark.gif" /> working...</div>
        </div>
    </div></td></tr></table>

I am reaching my witt's end on this. I'm no HTML or CSS guru by any means, so an explanation of why the solution works would be greatly appreciated.

Payton Byrd
  • 956
  • 1
  • 12
  • 27

7 Answers7

31

Updated Answer

The best way to do this now is to use rGBA colors. It won't work for older browsers, but you can let the design gracefully degrade by just feeding them a solid color. Example:

CSS

.parent {
    background: gray; /* older browsers */
    background: rgba(128,128,128,0.7); /* newer browsers */
}

.child {
    background: blue;
}

Original Answer

It is annoying, but CSS doesn't allow that. Setting opacity for one element means no child element can have any greater opacity. (100% of 25% opacity is? Right.)

So, one solution is to use a tiny transparent PNG as a repeating background image to work around that. The only issue there is IE6, and there's an excellent workaround called supersleight.

(Updated. Think supersleight will work for you.)

Update Here's a very simple test case. Create the image (say, a PNG with 50% black fill) and then create this file--save them in the same folder. If you don't see a thin box with a transparent background behind 'stuff', then you're either not saving the file correctly or have saved the image somewhere else.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<style type="text/css">
body { background:white; }
#overlay { background-image:url(test.png); }
</style>
</head>
<body>
<div id="overlay">stuff</div>
</body>
</html>
  • I've tried adding a solid background to the innermost div but it had no effect. Maybe I did that wrong. here's the CSS I used for that: .solidBackground { background-image: url('images/176x1.PNG'); background-repeat: repeat-y; } 176x1 is a 1-bit PNG set to white for the whole thing. – Payton Byrd Mar 01 '10 at 15:22
  • CSS looks okay, but check that the path is correct (maybe it's ../images/176x1.png'). –  Mar 01 '10 at 15:26
  • Also, of course, you need to make sure you're saving the PNG as a transparency. –  Mar 01 '10 at 15:29
  • I'm doing something fundamentally wrong. Can you point me to a working example that doesn't use Javascript? – Payton Byrd Mar 01 '10 at 15:51
  • Can't find one that's very clear, except maybe this one: http://www.icoblog.com/2008/07/semi-transparent-png-buttons.html –  Mar 01 '10 at 16:09
  • Added a simple test case. Give it a shot. If that works fine and you don't see anything wrong with what you have in your current file, mess around with the path you have to your image. I'd put money on the issue being either the path being wrong or the image not being saved as a transparency.. Also, any background color will show through, so if you're seeing a solid color, that may be why. –  Mar 01 '10 at 16:17
  • 1
    I have searched for this for ages. Thank you! – goodbytes Oct 14 '18 at 12:37
15

You can also do this without using a transparent image. Create two separate divs and use z-index to control which one is on top

Example code on jsfiddle

smarty
  • 378
  • 3
  • 18
  • 1
    this solution (without transparent images) works well. Just make sure z-index of the content modal is topmost. – Mike Padz Mar 20 '14 at 08:07
  • 1
    This also works well, so long as they are `position: relative` or `absolute`. –  Nov 11 '16 at 00:05
  • 1
    this is the solution for my case. I wanted to have a little pop up div when I click a word from a sentence. But I want to hide the portion of the background that my pop up covers and not the entire background page. This is awesome! Thanks. – Gel Jan 17 '22 at 02:42
4

Setting the color of the parent div with opacity with a rgba-color would make more sense here, because in this case the child element wouldnt inherit the opacity and wont be transparent!

so instead of using background-color: gray or #something, use something like this:

.modalBackground {
  background-color: rgba(222, 222, 222, 0.7);
}

Like this the parent-element has an opacity of 0.7 but is does not inherit it to any div or image or whatever inside of this div!

There are many rgba-generators out there on the net, try them.

http://www.css3-generator.de/rgba.html

Pingbeat
  • 305
  • 1
  • 9
2

How about using visibility?

#parentDiv {
  visibility: hidden;
}

#childDiv {
  visibility: visible;
}
Zozos
  • 71
  • 4
  • This is a really neat idea, though it doesn't allow any middle ground between visible and invisible. –  Apr 06 '19 at 18:09
1

A PNG would provide better compatibility (you have to use a filter: statement for IE6) ,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.

1

The way that I was able to put a transparent div behind an opaque div was to use something like:

`div.transparent-behind { opacity: 0.4; 
                      z-index: -1; }

 div.opaque-ontop { position: absolute; 
                top: (wherever you need it to fit)px;
                left: (some # of)px}'

where the div's were not nested inside each other, but one right after another in the html

make sense?

Ryan Greever
  • 151
  • 1
  • 1
  • 4
0

Try this

<div  class="" id="" style=" background: none repeat-x scroll 4px 3px lightgoldenrodyellow; left: 450px;  width:470px; text-align:center; height: 45px; position: fixed; 
  opacity:0.90;
    filter:alpha(opacity=40);
    z-index: 1000; ">
</div>
PPB
  • 2,937
  • 3
  • 17
  • 12