Sunday, December 30, 2007

Images and Mysterious Gaps

While rewriting a page on Sepia Mutiny, I found yet another reason why being a site designer is a highly-paid full-time job. It's impossible for anyone else to keep up with browser standards and implementations.

Consider the simple HTML below

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Sepia Mutiny</title>
</head>
<body>
<div style="border: 1px solid black; background-color: red;">
<img style="" src="/sepia/images/SMB3.jpg"/></div>
</body>
</html>

This is a well-formed strict HTML document that validates. You'd be surprised to see what it produces. See below.



If you haven't realized what's wrong, there is a gap below the banner image, before the div tag ends. Why? Probably stupid IE doing it's own thing, is anybody's first guess. Actually this is Firefox 2. Huh? I tried setting margin, padding and any other property that I could think of to 0. No effect. What gives? The same document renders differently in Internet Explorer 7. No gap below the image. Weird. Upon further tests, I made another HTML document.

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Sepia Mutiny</title>
</head>
<body>
<div style="border: 1px solid black; background-color: red;">
<img style="" src="/sepia/images/SMB3.jpg"/></div>
</body>
</html>

What's the difference? Only the Doctype is missing. So of course this is not a valid strict HTML document. Here's how it renders in Firefox?



I spent scratching my head for the better part of this sunday over this. Is Firefox buggy and IE7 getting things right now? Traditionally, sites are designed for non-IE browsers first because they are standards-compliant, and code exceptions/hacks for IE because of all its quirks. Has the situation reversed? After much Googling, I finally found the story behind this mysterious gap. Apparently, Firefox is too good at being standards compliant.

Lesson: Because the html element <img> is an inline element by default, it is rendered with a baseline whose height from the bottom border of its container depends on the font applied to the container. The element's property must be set to block to render the element differently without this baseline (assuming there is no other element such as inline text that may need a baseline within the same container). Thus, re-writing legacy HTML to conform to today's standards will break a template design. This is because a well-formed standards compliant HTML document is rendered by today's A-grade browsers in 'standards mode', whereas badly written html documents of yesterday are rendered by browsers in 'quirks mode'. As some of us who don't have enough background in designing sites usually just wing it, this is going to be a problem because of the all the bad habits we've learned over the years working in browsers' quirks mode. Now doing it the standards way is rather hard because we have to re-learn or rather learn correctly html and css standards.

References:
  1. Eric A. Meyer, Images, Tables, and Mysterious Gaps. Mar 21, 2003.
  2. Eric A. Meyer, Images, Tables, and Mysterious Gaps. Mar 3, 2002.

Thursday, December 13, 2007

perl xml parser and dependency hell

Was trying to install a perl module from CPAN (Frontier::Daemon) which needed XML::Parser which just wouldn't install. Perl's package manager kept complaining about a missing expat.h file, followed by many lines of errors. yum said expat is up to date. Removing expat (in an effort to reinstall it) removed yum as well. Installing yum wasn't easy. Finally got the rpm for yum to work and installed CentOS's precompiled perl xml parser. perl was satisfied with this and installed Frontier::Daemon without further complaints.

Tuesday, December 11, 2007

sendmail Doesn't Listen

sendmail service on CentOS default installation listens only on the loopback interface, for obvious security reasons. To modify this to listen on all binding ip address change the line

DAEMON_OPTIONS(`Port=smtp,Addr=127.0.0.1, Name=MTA')dnl

to

dnl DAEMON_OPTIONS(`Port=smtp,Addr=127.0.0.1, Name=MTA')dnl

As usual with any configuration change, recompile and restart service

> m4 /etc/mail/sendmail.mc > /etc/mail/sendmail.cf
> /sbin/service sendmail restart

Ensure sendmail.cf has rw-r--r-- permissions only, or it will complain about "dangerous write permissions".

When Yum Corrupts Its Own rpm Database

I was using yum the other to update a CentOS 5 server after a long time. It got stuck on a long download and didn't seem to quit even after a long time. Tried ending the process using

> kill pid
> kill -INT pid

This did nothing and the process was still hung. Finally used the trusty but dangerous kill -9 which terminated the process. But this made matters worse. Now yum wouldn't even start. A quick google search led to someone speculating that such forceful killing of the process could have corrupted the rpm database. Per their suggestion,

> rm /var/lib/rpm/__db*
> rpm --rebuilddb
> yum clean all

This fixed everything. Not sure what the above does exactly, but hopefully it's ok. This was not a production box, so it was fine. Yum works!