Bill's Computer Circus
Don't get caught with your system down.
NOTICE: This web site may not render correctly in older browers like Internet Explorer 5.2 for the Mac. May the gods help you if you are using Internet Explorer on any machine! Otherwise, if this site does not look right on your browser, please let me know what browser you are using (and what version and on what computer). Thanks!
"Visual Basic makes the easy things easier. Delphi makes the hard things easy."
-- unknown
Tuesday, October 04, 2005
 
The Web is Bent. Standards, Anyone?
Now I know why Web technology is the way it is. It is so people like me can get paid to spend an entire day to produce a piece of code that I should have been able to write in about 15-30 minutes. Now, if I only had a job, this would be a more attractive picture to me.

But my wife is trying to get me in where she works. I'm not sure how that will work out if that happens. Time will tell.

ANYway, I was helping my wife with a problem she has at work. She is helping revamp a web-based interface to allow users to customize the presentation colors. One of the problems is, the developers of the web site did not appear to have a strong grasp on some fundamental concepts behind cascading style sheets (like, for one, the cascade) and JavaScript. My wife has recruited me on a couple issues in this matter, since the developers there are strapped, and she thinks I'm some kind of computer god or something.

Today's task (that actually began yesterday) was to find a way to add color to some navigation tabs. Whereas this might sound like a simple thing to do (and might otherwise be a simple thing to do, given the proper tools), it was about as far from trivial as you can get.

First of all, there is this JavaScript code that she found online to implement nifty rounded corners on things using stylesheets (as opposed to using graphic images). I use this code on this Computer Circus blog, in fact. But it does some funky things, not the least of which is to add 5 pixels to the top and bottom of the element that is being rounded, creating a potential alignment nightmare if you don't factor this into the design from the beginning (like I did on this blog).

This code essentially toys with the background color of the element and tweaks the stylesheets behind the scenes. It can get ugly. But on top of this ugliness, is another script - that I wrote - that addresses PNG images. Most all browsers on the planet support PNG images to some degree, except Internet Explorer. There is a hack, however, to make them work via stylesheets. I implemented that hack where background images are used. When you have a background image in an element, and it is a PNG image with some transparency, then the background color of that element will shine through the transparent regions. This is the approach that was taken for adding color to these navigation tabs.

The problem is, due to other mitigating factors that I won't get into, if a PNG is used within an IMG tag, I had to write some JavaScript to scan the entire document on page load and apply a LoadAlpha filter to all the images behind the scenes, so that they would appear with normal transparency in IE. These images appear gray for a moment, because they are not replaced with their transparent renditions until after the entire page has loaded.

Another problem comes in when you want to round the corners of an element (say, a table cell) that has an image in it (say, a tab) - whether background or in an IMG tag. Suddenly, the image appears with 5 pixels of rounding above it, so you get this colored tab with a line of full background color above it. The idea behind rounding the background color was to match the rounding of the tab image so that it appears as though there is just this colored tab sitting there, with the color of the body background filling in around it - like you would expect.

But this 5-pixel offset makes it look like crap (which is a nice way of putting it).

So, I had to address this problem with a different approach. OMG. What I did was just put the transparent tab images in place, normally, (using a table to layout the tab images), and behind the scenes, using JavaScript, I created a new DIV element with the proper color and rounded corners on it, and stuck it behind the table with the tabs in it, aligning it perfectly with the tab images.

Due to the conflicting nature of web browers and their inability to conform to standards (not to mention their different INTERPRETATIONS of the standards), this implementation was an absolute nightmare.

Can you say, "nightmare?"

In order to put the DIV behind the table, I had to specify a z-index that was lower than the table. In most browsers, this was not a problem. But in FireFox, I couldn't get the colors to come through, and if I specified a positive number, all I could see was the DIV and it blocked out the tab images. What I didn't realize was that, according to the standards, z-index only applies to positioned elements. So, in order to get that to work, I had to go into the HTML and add a DIV tag around the table and give it a stylesheet to specify position:relative;top:0;left:0; - then, suddenly, the z-index:-1; specification on my dynamic DIV became effective, and I could see the color shining through the tabs like it was supposed to. That only took about 4 hours to figure out.

By the way, this story is very condensed - there are a lot of problems I had with this implementation that I am not reporting here. I probably can't even remember them all.

But another problem was with the nextSibling reference. My code looked for the tabs, which were each comprised of three adjacent table cell (td) elements (one for the left tab image, one for the right tab edge image, and one for the middle portion of the tab, the width of which could vary, and which had a background PNG image tiled horizontally to complete the tab picture -- plus the text that appears in front). My code would find the first of the three tags, and compute the width of the new DIV element by adding the width of the three TD tags together. In most browsers, I could use nextSibling to refer to the next adjacent TD tag. This makes sense. But not in FireFox, apparently. The nextSibling reference in FireFox referred to some text element, and nextSibling.nextSibling refered to the next TD element.

Don't ask me why.

So I had to add a kludgy hack to my code (I hate that!) to make it work in all browsers.

Then there was the problem of using setAttribute() with STYLE tags. When creating my DIV element, I had to apply the proper style, and I did that using the setAttribute() method. This worked fine in Safari and FireFox. But then I tested it on IE, and everything came crashing down (and you thought Y2K was a problem?). IE hated it. BUT! IE likes if I just do something like el.style.visibility="visible". So, I was able to get it to work in IE by breaking up the stylesheet and assigning it to style properties in this way. Once I got that working, I checked it in Safari and it worked there, too. But FireFox hated it. FireFox needed it to be in the setAttribute() form.

Safari swings both ways.

So then I had to resort to hacking up my code with browser detection to take one branch if the browser is IE, and the other branch for everything else. Who knows if it works with any other browsers.

What a pain in the BUTT this crap is! My GOD, how does anything work on the Web?

I won't even tell you about the hell I went through to get the Pac-Man to run across the screen. But thanks to Orion for the idea!

posted by Bill  # 6:58 PM