A recent mozillaZine article reports that John Carroll of ZDNet has issues with Firefox’s HTML rendering when compared to Internet Explorer. Specifically, he has set up a test page that uses the overflow
property: Internet Explorer displays the page as Carroll intended, while Firefox and Safari don’t. As Carroll describes it,
“I have created a Web page with a fixed position left, top and bottom sidebar that surrounds a scrollable area. All regions resize to completely fill the browser when its dimensions are changed.
To make this work, I have a table which lays out the basic position of the main sections (left bar, top bar, bottom bar, content). I’ve placed a div tag inside the “content” area of the table, setting its width and height to 100% and adding automatic scrollbars by setting the “overflow” CSS attribute to “auto.”
None of this is rocket science. Some might object to the use of tables, which in CSS circles might seem SO 1990s. I couldn’t care less. Tables are easy to use, are immediately intuitive to this old HTML hand-coder, and most important, have existed since the early days of HTML. Regardless of your preferences, there is no reason they SHOULDN’T work.
In IE, the page renders properly. In Firefox, the div tag refuses to size relative to its parent table (and doesn’t provide scrollbars), which causes the bottom toolbar to disappear past the edge of the screen.”
Carroll then proceeds to take Firefox to task for not doing a better job of mimicking IE’s behavior, implementing its proprietary features, and so on. The mozillaZine article retorts that it is Firefox that is rendering the page correctly, and closes with, “We’re not sure if Carroll intends to suggest that Firefox should not only support Microsoft’s proprietary extensions but also do the wrong thing [emphasis theirs] when IE is incorrect.”
I was curious when mozillaZine claimed that Firefox’s rendering was in fact correct. Were they right about that? Carroll’s page is a confusing beast, a weird hybrid of old-skool markup with a sprinkling of advanced CSS layout and overflow rules. Lots of bizarre behaviors we could be bumping into. Fortunately, it turns out the issue is pretty simple.
Let’s begin by eliminating a couple of red herrings. First: Carroll’s impassioned defense of table-based layout is charming, but irrelevant. At first I thought his table structure mattered, but it turns out we can reproduce the effect with only one box element. For its part, the mozillaZine article also snarked that the page “barely validates as the laxest form of HTML 4.0.” Barely validates… like being barely pregnant? Anyway, it turns out that the validation issue is also irrelevant. We could easily construct an XHTML 1.1 + MathML page that exhibits the same problem.
The root problem is in Carroll’s usage of the overflow
declaration. What does overflow
do? Consider a box that you have constrained to be, say, 50 pixels by 50 pixels. Now let’s say you want the box to contain a long chunk of content, say, all of Deuteronomy. Unless you find a reeeally small font, your content will not fit in the box. That’s where overflow comes in. The overflow
CSS declaration defines whether the box should create scrollbars, clip the text, or whatever.
Now consider what Carroll’s page does. He wants to simulate a typical framed layout, where you have a fixed sidebar, topbar, and footer, and a scrollable content pane. So he’s done the following:
- Set
overflow: auto
on his scrollable section. This, he thinks, should cause scrollbars to appear for this section if the content overflows. - Set
overflow: hidden
on theBODY
element. This, he thinks, should force all other sections NOT to have scrollbars on an overflow.
Except there are two problems.
First, Carroll has set the height and width of his scrollable section to “100%” instead of a fixed size. This means that the box automatically expands as large as it needs to be to contain its content. Therefore Carroll’s scrollable section always is large enough to contain all of its content; therefore overflow never kicks in; therefore the section never generates the desired scrollbars, no matter how much “Bah Humbug” text Carroll adds.
Second, by setting overflow: hidden
on the BODY
element, Carroll has not forced all other sections to not have scrollbars. Actually, overflow: hidden
on the BODY
or HTML
element is a special directive. It tells the browser, “Don’t generate scrollbars for the viewport itself,” i.e. the pane that contains the overall HTML page.
Thus, Carroll has doublefucked his code. Because he doesn’t understand how overflow works, his excess content will always flow down below the viewport. Ordinarily this would be fine — the user could scroll down as usual. But Carroll has told the browser to delete his scrollbars. The end result is a completely borked web page, albeit one that works in IE.
There are three lessons to be drawn.
First, if you want to simulate a framed page, use frames. (Or use position: fixed
, if you don’t care about IE.)
Second, IE’s buggy behavior is a major barrier for competing browsers. The typical web designer is not someone who dutifully reads the specs; he is someone with a mental model based on trial-and-error, mystical cargo cult coding. Does it work in IE? It does? Oh good, we’re done. If the alternative browsers can drive their marketshare high enough, this problem will start to go away. Until then, Firefox, Safari, and Opera will always be blamed for IE’s shortcomings.
Third, validation is the starting point for good design, not the end goal. For any web page design, there is an enormous set of possible design problems. Validation reduces this set to a much smaller size, but does not eliminate it. As Carroll aptly demonstrates, it is easy to create a valid page that is totally screwed up. Still,validation is one of the best tools in your toolbox for eliminating basic rendering issues. Unless you are using XHTML (and at most only a couple hundred of you really are), this is by far the best practical reason to validate your pages. Probably the only practical reason. But that’s a story for another day.
Setting the height of the scrollable section to 100% might not mean that it expands to hold whatever the content is, but in this case the table data cell holding the scrollable section has no height specified, hence the 100% (as per the specification) collapses back to “auto”, and that means it expands to hold the content.
Its also interesting to note that he selected a Doctype that triggers Quirks mode in Internet Explorer 6. It would be interesting to see what happens if it is knocked into Standards mode with either a Strict Doctype or the addition of a URI to the Transitional DTD.
Right, the scrollable section expands as needed, subject to any hard constraints imposed by the containing elements. Sorry, I should have made that clear.
Something I else glossed over: if you set
BODY
orHTML
tooverflow: hidden
, the spec says that HTML user agents MAY apply that declaration to the viewport. So IE’s refusal to do so is okay, as far as I can tell. IE is still doing the wrong thing with overflow in general, though.