August 12, 2007

XHTML as HTML and True Image Overlays

I ran into two issues while trying to make sure my new web site is compatible in Safari, Firefox, and Opera. (Internet Explorer 6 makes up about 30% of my traffic, and Internet Explorer 7 about 20%, but I am not going to use non-trival hacks to deal with a non-compliant browser.) The first issue was a situation in Opera where the Gallery popup images would not display. The second was the different overlay behavior of the Gallery popups in Safari, Firefox, and Opera. You can view the behavior I tried to make identical in all three browsers by clicking on any image in my photo album; the page should be covered with the full-size image and some controls at the bottom, and clicking on the info icon in the lower-right should show image details in a popup frame that is visible above the full-size image.

The first problem was Opera would not display the full-size image popup at all. It complained about the return value of a document.getElementById() coming back as undefined. However the same call worked just fine in Safari and Firefox. I posted a question getElementById returns null for empty anchor on the Opera community forums, and got a relatively quick reply explaining how even though the doctype and markup is valid XHTML 1.0 Strict, the MIME-type in the HTTP response headers is text/html. And having self-closing tags like <span /> results in bad things happening when the DOM structure is modified with JavaScript.

This is explained in further detail in Understanding HTML, XML and XHTML and in my forum reply, but the short of it is that changing the Content-type to application/xhtml+xml made using self-closing tags work, but broke everything else. Safari was no longer loading images correctly because the URLs didn't get sent out correctly. Firefox complained about something bad in the DOM structure. JavaScript was not being processed or executed even when using the <![CDATA[ ... //]]> modification.

For all those reasons, plus having HTML 4.01 embedded in my older blog posts, I changed the Content-type back to text/html and am instead making sure to use a full closing tag on any XHTML elements that require closing tags in HTML 4.01, such as <a> and <div>. I'd actually noticed that Safari wasn't doing the right thing all the time when self-closing elements like div, but didn't know the reason why until now.

The second issue was a little easier to resolve, once I saw how Opera was rendering things. In Safari, everything was looking how I expected it to, and how things look now in all three browsers. Firefox was doing something a little different where the header and footer divs were still appearing above the full-size image div, but my previous investigation led me to believe that was due to a case of float elements always having a z-index below those of positioned elements. But once I saw the rendering in Opera, I knew it was something else. Opera was showing the full-size image div enclosed entirely within its parent div with overflow hidden. So the fix was simple: move the image div out of its parent div and make it a child of the body. I also had to make the image details div a child of the body, otherwise it would be constrained as well and could not appear above the full-size image div.

I ended using a little bit of JavaScript to move the two divs into the body, because of how my Smarty templates and PHP header and footer include files are being used. Here's some code that does what I described:

function relocate(id) {
app_body = document.getElementById(id);
while (app_body && app_body.tagName != 'BODY') app_body = app_body.parentNode;
var imageview = document.getElementById(id);
var parent = imageview.parentNode;

Posted by josuah at August 12, 2007 8:27 AM UTC+00:00

Trackback Pings

TrackBack URL for this entry:


Post a comment

July 2013
Sun Mon Tue Wed Thu Fri Sat
  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