I have given a name to my pain, and it is Internet Explorer (IE).
More specifically, it’s versions predating IE 8, which (IMHO) is Microsoft’s first really solid Web browser and gives me little to no trouble. IE 7 and IE 6, on the other hand, are what Napoleon Dynamite would refer to as decroted pieces of crap.
Here’s my most recent study in IE pain. I’m making a Web page that uses a variation on an accordion menu. Said accordion menu needs to allow users to open more than one pane at a time, so I can’t use the handy little .accordion() method in the jQuery UI plug-in to create it. After a little digging around on teh interwebs (Did you see that subtle, humorous allusion to internet culture there? Did I mention that it was subtle?), I opted to write a little click handler that would apply slideToggle to create the modified accordion effect, like so:
BTW, for all you self-appointed code police (SACP) out there, I’m fully aware that the guts of this function can be chained. For me, this looks cleaner and is clearer. There. Are we okay now?
Anyway, this accomplishes the following:
- When each accordion item is clicked, it sets the variable currentAccPane to the next sibling element, which happens to be the div containing the content associated with the clicked heading.
- It changes the on/off state of the clicked heading by toggling the class ui-state-default.
- Then, it slides the pane of associated content down (on) or up (off).
Everything was just ducky in Firefox, IE 8, and Safari, but IE 7 choked on it. Hours of arduous Googling revealed that IE 7 and slideToggle don’t like each other when you’re slideToggling positioned elements (which I was). In this instance, IE 7 simply ignored the height of the parent element and stretched absolutely positioned child elements vertically to the height of the viewport.
Holy MonT-SteR Consternation™, Batman!
Here’s what worked:
The fix occurs in the last two lines:
- After getting the content block associated with the heading, it calculates its pixel height based on the content it contains (which is the same whether open or closed — when the latter, it’s simply hidden) and stores it in the variable divH
- Then it uses divH to assign a hard pixel height to the content’s parent element via inline CSS on the fly (minus the top and bottom padding in the element, which in this case added up to 24px)
Voila! jQuery to the rescue! IE 7 now happily constrains the absolutely positioned blocks that were being inordinately stretched to the size of the containing block in the accordion.
Now, let me preempt the SACP by acknowledging that there may be a more savvy, efficient way to do this. And I admit that this may break the rule of keeping style and behavior separate in Web design. I suppose one could argue that my use of the .css() method here in my script is actually addressing a behavior — albeit a bad one — and so everything’s kosher.
In any case, I’m just getting my feet wet with jQuery, so I’m open to suggestions. But this works without any deleterious effects on other browsers (except IE 6, but that’s a
animal beast monster form of torture horse of a different color). And, it solved my IE pain. For a jQuery noob, I think that’s a pretty good day’s work.
aka The MonT-SteR