IE8 & Assigning Classnames With new Element(‘…’)

When dynamically creating elements using Prototype’s new Element(‘…’) method, I ran into this irritating gotcha with IE8.

While the following looks great and works well in Firefox:

new Element('span', { 'class': 'someClassName' });

In IE8, not so much.

What one expects, and gets in Firefox:

<span class="someClassName"></span>

What one gets in IE8:

<span></span>

Hmmm, where did that classname go? Yeah, I don’t know either.

To avoid this, one must perform the following incantation:

new Element('span').addClassName('someClassName');

This will give the same result in Firefox and IE8. Tadaa!

No comments | Trackback

Scriptaculous Effect.Morph IE6

Ran into a weird bug the other day in IE6. Some elements, h1′s, weren’t animating with their parent when the parent was being Effect.Morphed. Every other element was moving, but the h1′s just sat there, looking really stupid. I think the use of Twin Helix’s IE PNG Fix was a contributing factor here, since writing this article I’ve noticed ( and fixed, using the solution below ) this issue on other position:relative, PNG fixed elements.

The h1′s were the parents referred to in the post Float:Right Nuke for IE6, and thus had position:relative set. Removing this caused the h1′s to animate nicely, but unfortunately I couldn’t do that because removing the position:relative had the side-effect of causing the content that I wanted to simulate float:right with to shoot up to the top-right of the screen. D’oh.

To solve it, and have everything animate acceptable in IE6 I had to do this:

/* the first morph: */
new Effect.Morph('h1_parent', { style: 'padding-top:50px', delay: 0.5 });
 
/* the fix: */
$$('.h1_className').each( function(element){ 
	new Effect.Morph(element, { 
		style: 'top:1px', duration: 0.5 
	});
});
 
/* the second morph, taking place after some user action: */
new Effect.Morph('h1_parent', { style: 'padding-top:10px', delay: 0.5 });
 
/* the fix: */
$$('.h1_className').each( function(element){ 
	new Effect.Morph(element, { 
		style: 'top:0px', duration: 0.5 
	});
});

Yeah, looks stupid I know. Works though. A bunch of h1′s moving 1px isn’t noticeable, but h1′s that didn’t animate sure would have been!

One more time, combined into a more usable function:

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
/**
 * Wiggles elements with the given classes to make sure they animate 
 * with their parent, their parent's parents, and their parent's parent's 
 * parents ( ad infinitum ) in IE6, when the elements of the given
 *  classes have the Twin Helix PNG fix + position:relative applied
 *
 * @param classes an array of css class names, prefixed with a '.'
 */
wiggle = function( classes ){
classes.each( function( className ){
     $$( className ).each( function( ele ){
          new Effect.Morph( ele, {
               style: 'top:1px', 
               duration: 0.25,
               afterFinish: function(){
                    new Effect.Morph( ele, {
                         style: 'top:0px',
                         duration: 0.25
                    });
               }
     });
}
 
/* the first morph: */
new Effect.Morph('h1_parent', { style: 'padding-top:50px', delay: 0.5 });
wiggle( [ '.classOne', '.classTwo' ] );
 
/* the second morph, taking place after some user action: */
new Effect.Morph('h1_parent', { style: 'padding-top:10px', delay: 0.5 });
wiggle( [ '.classOne', '.classTwo' ] );
No comments | Trackback

Float:Right Nuke for IE6

Lately I’ve been spending a lot of time debugging browser issues in our site ( ECPod – Blog to a Wider Audience ). I’m not going to kid with you here: it isn’t fun. On the scale of hate, 10 being most hated, my browser table would be something like this:

IE 8 – 4 ( It’s actually not too bad, even has so-so dev tools )
IE 7 – 6 ( Bad but not godawful )
IE 6 – One million

IE 6 is so bad it’s not funny. OK so it is funny, just not when you’re the one tasked with forcing it to render a site in a way that doesn’t make me want to vomit correctly.

The point of this particular rant against IE 6 is float:right and stepdown.

WTF is that, you ask? It’s when, instead of floating an element to the horizontal right of it’s siblings, IE 6 will float it right then push it down so that its topmost edge is flush with the bottommost edge of its tallest sibling. Fail!

Below is what I like to call the float:right nuke. Like a nuke, you should only use it in two situations:

  1. you don’t have the time or patience to work out a better solution for your particular issue
  2. nothing else has worked.

Behold, the IE 6 float:right nuke:

#parentElement{
	position:relative; /* prevent #offendingElement from shooting to the top-right */
}
#offendingElement{
	float:none; /* override any non-ie specific css */
	position:absolute;
	right:0px;
	top:0px;
}

Use with caution, and don’t forget your radiation pills.

Comments (1) | Trackback

Check if it’s an Object!

OK Javascripters, check it out: the IE family don’t like you. Or they love you. I’m not sure. Maybe they just want you to be better? To produce perfect absolutely syntax-error free code. Code that caters for even the most careful pedantic Javascript interpreters.

Example:

In the WYSIWYG text editor we use, when one clicks a UI button that is meant to cause say, an “Embed Flash” dialog to popup, there is a section of Javascript devoted to building said dialog and binding functions, style structure to it. My casual inspection of the code leads me to believe that it stores the dialog as an array of objects and functions. Now, when the dialog is supposed to do it’s popping up, this array is iterated over. Certain things are meant to happen to certain objects, objects with certain properties.

Notice how I said objects there. Objects. Not the functions.

So then, we should test each element to make sure it’s a function, right? Well yeah, we should. But the code wasn’t. Firefox didn’t complain, why would it!? If it’s a function, it won’t have attribute x – it’s a function, dummy! Firefox knows this. Safari does too. The IE family knows ( I guess ), but it wants you to be better ( loves ) or wants you to go insane ( hates ).

See when one of the IE’s hits a function and is asked to test whether it has a property, like this:

if( item.type == 'car' || item.type == 'boat' ){ /* do stuff! */ }

It refuses to cooperate. One is simply told: “‘type’ is null or not an object“.

Helpful!

What it really means, in this case is that IE is too dumb confused and needs you to hold it’s hand.

By hold its hand I mean do something like this:

if( ( typeof( item ) == 'object' ) ){
    if( item.type == 'car' || item.type == 'boat' ){ /* do stuff! */ }
}

First, test to make sure it’s an object! If you’re iterating a structure that contains mixed types, and you want to do something to a specific type, test for the type before diving into type-specific conditionals! It will save your sanity points when it comes time for you, or others when performing browser-compatibility testing.

And if you work on a publicly available project, you’ll be saving other people’s sanity as well ;)

No comments | Trackback

Vertically Centered Elements

If you’re looking for a way to vertically center an element of unknown height within another element of unknown height, this guide is for you.

Vertical Centering in CSS

It provides a solution that works in all major browsers – yes even IE6.

I’ve used it, it works.

No comments | Trackback