I'm a ex-barman that became a web developer. I like what I do, but what I really love is a good beer, portuguese food, my football (soccer for the US people) team, F.C.Porto, and of course, my biggest love, my son, Tiago.


Subscribe Now!

...with web-based news readers. Click your choice below:

addtomyyahoo4Subscribe in NewsGator OnlineAdd to My AOL
Subscribe in RojoSubscribe with BloglinesAdd to netvibes
Add to Google

...with other readers:

original feed View Feed XML

 

SEARCH

Google
This Blog:


NAVIGATION

  • Polls

    What do you think about the upcoming changes in Javascript?

    View Results

    Loading ... Loading ...
  •  

  • Mini Wiki - Click a word and view/add/edit a definition

     
  •  

     

  • Archives

  • Meta

2007 | Content: HRCerqueira’s Blog | Design: Julian Klewes | Licence: CC 3.0

         

 

UPDATE: I received some complaints about this script not working under ie6. I build this script to run on a intranet page that I knew that was only to be viewed with firefox. It’s very simple to tweak it, however I’ve updated the script (just the simplified version) to be used with IE6 as well. Just remember that IE doesn’t have the opacity attribute, instead it uses the filter attribute, that can be set with something like alpha(opacity=##) //0 to 100

Transparency is something that gives our pages a super modern look. It’s primarily a css effect, but there are two alternatives, using the background: transparent property, or the opacity property. The first one make elements background completely transparent, or invisible if you like, but the second one allow us to have full control of the alpha channel on an element, like this:

porto.gif This is the content of a semi-transparent html element. The important part on its definition is background-color: blue; opacity: 0.5
And theres an image to…

The transparent content problem
As you can see by the previous example, it’s not only the background that becomes semi-transparent, the content of the element inherits the same opacity settings, and even if you apply opacity: 1.0 you won’t see any changes.

There are some workarounds, one of the most common is to use a png image as the background of the element, since png uses 256 alpha gradients, but that can be a problem in some browsers, like IE5.

Another workaround is to have two absolutely positioned elements on the exact same position and with the exact same size, inside the same parent element, one of them containing only the background settings, and the other one having the content in it. The “content” element should be the over the “background” element.

This last workaround seems the best solution in my humble opinion, however, if we have many elements like this in one page, that can be a tedious task. And that’s happened to me in my last project. But I found a good solution, I created a piece of Javascript code that “scans” the page after it loads, and then convert all the elements i specify into that double element trick, like this:

porto.gif This is the content of a semi-transparent html element. The important part on its definition is background-color: blue; opacity: 0.5
And theres an image to…

This is the initial html:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
   <div style="position: relative; left: 60px; background-image: url(/wp-content/uploads/2007/11/board7.jpg); color: white; font-weight: bold; height: 200px; width: 400px; ">
      <div style="position: absolute; left: 25px; top: 25px; width: 350px; height: 150px; background-color: blue; opacity: 0.5;  filter: alpha(opacity=50)" id="transparentdiv">
         <table border="1">
            <tr>
               <td>
                  <img src='/mfiles/porto.thumbnail.gif' alt='porto.gif' />
               </td>
               <td>
                   This is the content of a semi-transparent html element. The important part on its definition is background-color: blue; opacity: 0.5<br />
                   And theres an image to... 
               </td>
             </tr>
          </table>
      </div>
   </div>

And this is how it looks after conversion:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
   <div style="position: relative; left: 60px; background-image: url(/wp-content/uploads/2007/11/board7.jpg); color: white; font-weight: bold; height: 200px; width: 400px; ">
      <div style="width: 350px; height: 150px; position: absolute; left: 25px; top: 25px;">
         <div style="position: relative; left: 0px; top: 0px; width: 350px; height: 150px; background-color: blue; opacity: 0.5; filter: alpha(opacity=50)" />
         <div style="position: relative; left: 0px; top: 0px; width: 350px; height: 150px;" id="transparentdiv">
            <table border="1">
               <tr>
                  <td>
                     <img src='/mfiles/porto.thumbnail.gif' alt='porto.gif' />
                  </td>
                  <td>
                      This is the content of a semi-transparent html element. The important part on its definition is background-color: blue; opacity: 0.5<br />
                      And theres an image to... 
                  </td>
                </tr>
             </table>
         </div>
      </div>
   </div>

Now the “transparentdiv” element was spitted into two, one with the background definitions, and the other with content. And the both elements are contained inside a topmost element that is on the previous position of “transparentdiv” inside the document. That topmost element is just there, because if we later want to move the elements around we don’t have to do it with the two pieces of “transparentdiv”, so, it’s not absolutelly necessary. Now to the Javascript code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
function applyTransparencyHack(element) {
	//create the topmost container
	var container = $new('DIV');
 
	//apply the same position and dimension properties of the element
	container.style.width = element.style.width;
	container.style.height = element.style.height;
	container.style.position = 'absolute';
	container.style.top = element.style.top;
	container.style.left = element.style.left;
 
	//create the background container
	var backContainer = $new('DIV');
 
	//apply the same dimension and background properties of the element
	backContainer.style.width = element.style.width;
	backContainer.style.height = element.style.height;
	backContainer.style.background = element.style.background;
	backContainer.style.opacity = element.style.opacity;
	backContainer.style.position = 'absolute';
	//and position it at (0, 0) because it will be a child of container
	backContainer.style.top = '0px';
	backContainer.style.left = '0px';
 
	//remove background definitions from the element
	element.style.background = '';	
	element.style.opacity = 1;
	//position it at (0, 0)
	element.style.position = 'absolute';
	element.style.top = '0px';
	element.style.left = '0px';	
 
	//now append the container before the element
	element.appendBefore(container);
	//and remove the element from its original position
	element.remove();
	//move the background container to inside the container
	container.appendChild(backContainer);
	//move the element to after the background container
	backContainer.appendAfter(element);
 
	//create shortcuts for the background and the container in the element
	//that are going to be useful if we later need to do some dom handling
	element.background = backContainer;
	element.container = container;
}

For this specific example, I applied the hack to an element with a specific id, “transparentdiv”, like this:

48
49
50
51
//tell the window to apply the transparency hack to "transparentdiv" after it loads
window.addEvent('load', function() {
	applyTransparencyHack($('transparentdiv'));
});

but I could have done something involving class names, for example assigning the “semitransparent” class to the element and then calling:

48
49
50
51
52
53
54
55
//tell the window to apply the transparency hack to all elements which implements the class "semitransparent"
addOnLoad(function() {
	var trnspEls = document.body.getElementsByClass('semitransparent');
 
	for (var i = 0; i < trnspEls.length; i++) {
		applyTransparencyHack(trnspEls[i]);
	}
});

Then was just a matter of adding the class name “semitransparent” to the element to hack it.

Finnaly, if you don’t need to do any kind of dom handling after the hack is complete, you can simplify the function. You can also make it work independantly of any external functions, like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
function applyTransparencyHack(element) {
	//simple trick to check if were facing the evilness of a ie browser
	var ie = (document.all) ? 1 : 0;
 
	//create the background container
	var backContainer = $new('DIV');
 
	//apply the same location, dimension and background properties of the element
	backContainer.style.width = element.style.width;
	backContainer.style.height = element.style.height;
	if(ie)
		backContainer.style.backgroundColor = element.style.backgroundColor;		
	else
		backContainer.style.background = element.style.background;
 
	if (ie)
		backContainer.style.filter = element.style.filter;
	else
		backContainer.style.opacity = element.style.opacity;
 
	backContainer.style.position = 'absolute';
	backContainer.style.top = element.style.top;
	backContainer.style.left = element.style.left;
 
	//remove background definitions from the element
	element.style.background = '';	
	if (ie)
		element.style.filter = 'alpha(opacity=100)';
	else
		element.style.opacity = 1;
 
	//now append the background container before the element
	element.parentNode.insertBefore(backContainer, element);
}

Now, please note that this example was perfectly suitable for my project needs, and it works very well on absolutely positioned elements, like in tableless layouts, but it can look clumsy in other layouts. Give it a try on your webpage, and if it doesn’t work well, you’ll probably have to make some tweaks. If it’s the case and you need help, just leave me a message here and I’ll be glad to help you out.

Hope this helps someone.
Cheers,
Hernâni





Name (required)

Email (required)

Website

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>

Feel free to leave a comment

#