Saturday, June 19, 2010

IE7 is why I drink so much

Cool bug in IE7; I think I ran across it years ago in IE6, but back then I thought everything any browser did was essentially magic so I didn't worry too much. Make a table. Put rows in your table, rows filled with glorious content. Give some columns — header and data cells alike — a class, like maybe "hideMe". Put a control somewhere on your page, preferably a checkbox. Wire that up to a Javascript handler that adds/removes a class from the enclosing table. Maybe your class can be called "hide". It is not important what these things are called. Please don't lose sight of the forest by becoming preoccupied with the color of the lichen on the trees. Now. Add some CSS such that a table cell (or header cell) with class "hideMe" inside a table with class "hide" is not displayed.

   table.hide th.hideMe, table.hide td.hideMe {
     display: none;
   }
  
OK now what have we got? We've got a table with some columns and a control that you can click to make some columns go away. It's like a "peek a boo" game. Sometimes dogs really freak out over stuff like this. Now, let's say you want to use something like this for real. Let's say you want a table for something actually useful, and you want a "condensed" mode and a "full" mode. Thus your "condensed" mode will involve the outer table tag having that "hide" class, while the "full" mode will not. Possibly you'd like your page to start off in condensed mode, because the "full" mode has columns that only dumb people want to look at. This brings us to IE7. Your page loads, and you set things up so that the table has the "hide" class, and sure enough the "hideMe" columns are not shown. Great! That's exactly what we wanted! However we have to put that checkbox on there so that the dumb people can toggle the display of "hideMe" columns. So we do. In browsers developed outside of Mordor, everything works exactly like you'd expect. Not in IE7. IE7, perhaps like its Balrog predecessor IE6, has something up it's sleeve. When the page first loads, the hidden columns are hidden. Click that checkbox. Do you see the columns? No? Well, that's because IE7 has decided that table sub-elements hidden when the table is first rendered will never ever be visible ever, even if Elrond and Gandalf throw Frodo into the volcano and jump in after him. Note that if you load your page configured for dumb people, with the "hideMe" columns visible, then everything works. Things are just problematic when parts of tables (and just tables) are hidden upon initial DOM rendering. (Yes, this applies to stuff dynamically added to the DOM later — the Dark Lord is pretty thorough.) I don't know of any good way around this. A bad way around it is to make sure that things are set up in "everything visible" mode upon initial DOM rendering, and then have something come back in a few milliseconds and make things look the way you actually want them to look. I suspect that IE7 users have so many bruises on their brains that the page wiggle thusly induced might actually seem comforting and familiar, like the smell of burned waffles at your grandparents' house.

Wednesday, June 9, 2010

Safari 5 Has Some Printing Problems

A bug report was logged against my application today concerning the new Safari 5 release. On the Mac it apparently displays some layout issues that I don't see on the Windows version, so I can't say much about those (though they seem pretty fishy; button elements styled with borders rendered such that the borders aren't completely drawn doesn't seem like a CSS issue to me ...). Also reported however was a problem with printing. Some of the application (the "help" pages) are printable, and have a "print" stylesheet that arranges for some differences with the screen version. Some elements are hidden, links are printed a different way, etc. The print version works fine in IE7 & 8, Chrome 4 and 5, Firefox 3.5 and 3.6 (and probably 3.0/3.1 too), and Safari 4. In Safari 5, however, it's completely broken — not a little wrong, but obviously messed up and totally unreadable. I messed around with the stylesheet randomly with no luck, and so I started on a much simpler test page (here). That page is also broken when printed from Safari 5, in a very similar way too. Hmm. I decided to start with the part of the stylesheet that was most relevant to the paged media context: the @page rules. The stylesheet had:
@page { margin: 1in 1.75in 1.5in 1.5in; } @page :left { margin: 2in 1.75in 1.5in 1.5in; }
Those do pretty much nothing at all in all the browsers I know of, but sure enough when I commented those two lines out, printing started working. Searching around the Apple documentation, I could find nothing to suggest that those rules should cause a freak out. Nor could I find any mention of a change in semantics from Safari 4 to Safari 5; in fact I could find no mention of @page on the Apple site at all, even though they do list some unsupported CSS stuff. (Note that @page is a CSS2 thing, though again none of the browsers seem to pay attention to it.) It finally dawned on me what was going on in Safari 5's little mind: those @page rules, formerly ignored completely, were being treated as if they were "*" rules. That is, the margin was being applied to everything on the page, and every block-level element. Well no wonder things looked funny. The moral of this story is to keep @page rules out of your print stylesheets, as most everybody probably does anyway.