• 200703 Jun

    The header of my own blog (still in development; please don’t judge me!) features a single image which spans two columns, with a semi-opaque panel featuring text over the top of it. I wanted the image to be clearly visible in the left column, and faintly visible in the central column. I could have done this by designing it that way in a graphics package, but as I intend to swap the image around in future, I wanted to come up with a client-side solution.

    I could have just used a semi-opaque background image, which would have worked immediately with all major browsers bar IE6. But I didn’t want to use an extra image and I wanted to play around with CSS 3, so this is what I came up with:

    Firstly, I put the image as a background property on the <body> element. Next I created an empty, presentational <div> with a class of ‘header’. To this I assigned the colours and border colours, then gave it a large left-margin to allow the image to completely show through on the left column, and an opacity of 0.9 in order to allow the image behind to faintly show through on the central column.

    The problem with opacity is that it is inherited by all child elements, so if I had put text inside div.header, the text would also have become semi-opaque. To get around this I assigned position: relative to the <body>, then wrapped another <div> called .title around <h1> and <h2>, put it after .header, then absolutely positioned it where I wanted it to appear:

    <body>
    <div class="header"></div>
    	<div class="title">	
    	<h1></h1>
    	<h2></h2>
    	</div>
    </body>
    
    body { background: white url(images/header.png) no-repeat; }
    
    .header {
    background-color:#8DCC3A;
    border-top:60px solid #4A5C61;
    margin-left:20%;
    opacity:0.9;
    }
    
    .title {
    left:21.5%;
    position:absolute;
    top:80px;
    width:57%;
    }

    Opacity doesn’t work in Internet Explorer, of course; I could have used a proprietary filter, but decided that the 19% of visitors to my site who use Internet Explorer wouldn’t suffer by not being able to see the whole image; it would be a little ‘bonus’ for whoever uses a better browser (here’s an image if you’re using IE and want to see what other users see).

    Another solution was available to me; keep the <h1> and<h2> inside .header, and use rgba values on it instead. This would be better semantically as I could drop .title, and wouldn’t involve any positioning as rgba values are not inherited. I could have used the following code:

    <body>
    <div class="header">
    <h1></h1>
    <h2></h2>
    </div>
    </body>
    
    body { background: white url(images/header.png) no-repeat; }
    
    .header {
    background-color: rgba(141,204,58,0.9);
    border-top: 60px solid rgba(74,92,97,0.9);
    margin-left: 20%;
    padding-top: 20px;
    }
    
    h1, h2 { padding: 0 7%; }

    While this is obviously leaner and quicker, support for it is not as widespread; at the time of writing this, perhaps only 4% of my visitors would see the effect I wanted.

    My two most extreme options were to have added extra styles and conditional comments to the document in order to getting working across all browsers, or to use the purer, smaller CSS3 to get it working on only a tiny amount of current browsers. In the end I did what we’ve been doing for so long now, and made a compromise.

    You can skip to the end and leave a response.


  • Comments

    • 01.

      Funny, I was messing about with more or less the same thing today.

      However, I didn’t mind the text to be affect as I was applying opacity to a footer element which I wanted to blend into the textured background.

      Using the opacity attribute worked fine in Firefox. Opera made the text aliased. And IE off course didn’t apply it. However not even the filter opacity worked in IE7 for some reason.

      So I ended up using a small alpha transparent background image instead. Not ideal, but it did the trick in Firefox, Opera and IE7.
      Saying that, I’m not looking forward to creating a fallback solution for older browsers. Especially IE6-.

      On another project of mine I used similar techniques as you described. All though that was part of an AJAXification of a gallery section. So the the elements used for it was all done in DOM scripting, leaving the source semantically clean.

      You’d think we’d have proper transparency control in CSS by 2007 wouldn’t you..? *sigh*

      Seeing how IE7 shaped up from previous versions, I’m looking forward towards the next as it’s crucial to allow webdesigners migrate towards CSS3.

      I’d only wish that other browsers would pick up on conditional comments to allow an easy way to target specific browsers and address their issues. In fact, allows conditional comments inside CSS files would be better. You could then have a main css file that would direct the various browsers to the appropriate stylesheets. CSS3 powered browers could get your ultra-super-duper cutting edge stylesheet, while you served a more conservative stylesheet to the older browers.

      Ach, the dreams…

    • 02.

      @Thomas: though I like the idea of a sort of semantic to target different browsers with different fixes from within the same CSS file, I absolutely hate the idea of more browsers picking up on conditional comments… They’re one of the most horrible solutions I’ve ever seen… (although it beats using css hacks ;) )

      @Peter: nice article! Like the idea, I’ll be using it a new site I’m building for work :)

    • 03.

       Excellent! Clear, thorough, and precise explanation and solution. Love the affect!

    • 04.

      The best solution would be using a semi-transparent background image.

    • 05.

      I used a PNG which was semi-transparent as the background which worked very well.

    • 06.

       As a web developer, i no more worry about old IE browsers. I directly use the CSS3 for background transperancy. Only less than 1% of my visitors use old IE’s.

    • 07.

      “rgba values are not inherited”

      Those five simple words solved my problem. I spent most of yesterday, and all of last night trying to find a way to get an entirely CSS3, semi transparent, radius cornered box containing text and a border without transparency. I tried numerous Google searches, many of which brought me back to this page, but until 20 minutes ago, nothing was sinking in. Then, when those words walloped me, my background color became semi transparent, and my text, and border remained opaque. Unless you’d rather a kiss, let’s go for a beer.

    • 08.

      It is worth being repeated:

      “rgba values are not inherited”

       Those five simple words solved my problem.

      Thanks!

Hosting by: