No Mod Required

Archive for the 'standards' Category

Some Internet Explorer Innovations You Probably Forgot About While Waiting for IE6 To Die

Lost in the past few years of IE6 based stagnation (and ensuing developer angst) is the fact that the Internet Explorer team have come up with some pretty cool enhancements to the way we build web sites over the past ten plus years.

So, while we’re cheering on Firefox’s growing market share, hesitantly eying IE8 and waiting for the ugly stepchild of the browser landscape, IE6, to finally die a painful (and hopefully immediate) death, I thought I’d lay out some of the innovations introduced by Internet Explorer to remind us of relatively positive days gone by*.

As a fun exercise, while you’re reading this, compare these innovations to the black hole left in the web development world by the long and terrible reign of IE6. It’s an interesting juxtaposition of help vs. harm. Here’s hoping future versions of the browser continue to trend closer to the “help” line as IE7 has and IE8 appears to be doing**

XMLHttpRequest

For those that don’t know, XMLHttpRequest (XHR) is an API used by JavaScript to transfer XML (and other text formats like JSON and plain text) data between a browser and the web server.

This one is obviously pretty big. While “Ajax” the phrase coined by Jesse James Garret of Adaptive Path, didn’t spring directly from Redmond, a large part of it, and therefore much of the recent innovation in the way web interfaces are programmed, does spring from the creation of the XMLHttpRequest (XHR) object. Originally an ActiveX object, XHR is so far entrenched into the way web works right now it’s not even funny.

Personally, without Ajax making JavaScript the hot language it is today, I wouldn’t be half as marketable as I currently am.

Introduced in Internet Explorer 5.0

innerHTML

This JavaScript property is a read/write interface to the HTML markup and content within a given element.

All day, every day I use the innerHTML property. Faster than the DOM methods for object creation and insertion setting innerHTML is normally my first choice whenever I do DOM manipulations.

Introduced in Internet Explorer 4.01

iFrame

Like a frame, an iframe (”inline frame”) is an HTML element that allows you to embed a HTML document inside another HTML document. The iframe is the earliest innovation this list, appearing all the way back in 1996.

Humorously (or tragically depending on where your allegiance lies- Mountain View or Redmond,) a good portion of the GOOG empire is built on the iframe as the search giant uses an iframe to deliver its advertising on non-Google properties (you can see one in action on this very page.)

Introduced in Internet Explorer 3

The favicon

A favicon (favorites icon) is an icon associated with a particular website or webpage. The favicon not be the innovation that affects me the most on a day to day basis, but judging by the chatter generated by Google’s new favicon, I think a lot of people notice that little browser accessory.

Introduced in Internet Explorer 4

overflow-x, oveflow-y

Maybe not the biggest impact, being able to set the overflow property in one dimension is an immensely handy thing to be able to do and I’m happy to have it in my list of tricks.

*This is 100% focused on only technology. Anti-competitive practices and killing Netscape are definitely NOT positive.

**it should be added that while I’m pleased to develop for IE7 in comparision to IE6, it still falls short of what I’d like to see in terms of standards support. Hopefully IE8 will knock it out of the park, but until that time, I’d much rather everyone just go with Firefox, Safari or Opera :)

My New GetElementsByClass() + a Safari 3.1 Oddity

To make use of the native getElementsByClassName I rewrote my getElementsByClass function to use the method where possible.

Here’s the code*:

function getElementsByClass(theClass,node) {
    var classElements = [];
    var i;
    if ( node == null ) {
    	node = document
    }
    if (node.getElementsByClassName) {
    	var tempCollection = node.getElementsByClassName(theClass);
        for (i = 0; i < tempCollection.length ; i++) {
    		classElements.push(tempCollection[i])
    	}
    }
    else {
    	var els = node.getElementsByTagName("*");
    	var elsLen = els.length;
    	var pattern = new RegExp("(^|\\s)"+theClass+"(\\s|$)");
    	for (i = 0; i < elsLen; i++) {
    		if ( pattern.test(els[i].className) ) {
    			classElements.push(els[i]);
    		}
    	}
    }
    return classElements;
};

The above code works as expected in Firefox 2, 3; IE 6,7,8, Opera 9.5 and Safari 2.

Interestingly it doesn’t work in Safari 3.1. Safari supports the native getElementsByClassName, so one would expect it to work alongside Firefox 3 and Opera 9.5.

It does not.

Here’s a sample. Click “start” and everything should go from blue to black (which means the class is removed from the LIs) and the numbers should read “10 0″. The 10 is the length of the collection returned by my function when the test starts. The 0 refers to the length after the test has run it’s course and the class has been removed.

Safari 3.1 looks like this:

So the count is 10, even though there are 0 instances of the class in the DOM:

This is the code I’m running:

function testSafari() {
    $("messages").innerHTML = getElementsByClass("sample").length;
    var samples = getElementsByClass("sample");
    for (i=0;i<samples.length;i++) {
	    removeClass(samples[i],"sample");
    }
    $("messages").innerHTML += "    "+getElementsByClass("sample").length;
}

I’ve approached the problem from a few different angles (not exhaustive) and taking a quick look at the WebKit source it seems to me that Safari might be incorrectly caching the results of the getElementsByClassName call. I haven’t had the time I would like to test this to see what might be happening in specific, but that’s what it feels like.

Anyone know more about the guts of WebKit? Am I onto something? Or is my nonexistent Apple dev knowledge showing? :)

For the webdev crowd, anyone else seen anything like this? Is it something stupid that I’m doing that I’m just not seeing (and therefore not actually a bug)?

That’s always my first assumption, but the native method works in both Opera and Firefox so I’m more confident than normal that the issue isn’t my fault.

*I used to have support for a specific tag. When rewriting it I thought “I never use the tag argument, I’m dropping it.” Of course, as soon as I did that one of my co-workers used the tag argument in a script he was writing for a site we were working on. I’ll be adding the tag option back in.

Also, this version relies on support for Array.push(). Our little library adds it in with this:


if(!Array.prototype.push) {
    function array_push() {
        for(var i=0;i<arguments.length;i++){
	        this[this.length]=arguments[i]
        };
        return this.length;
    }
    Array.prototype.push = array_push;
}

Say Hello to JavaScript’s Native getElementsByClassName

With the recent release of Firefox 3, we’ve now got a full fledged, mainstream browser that supports the long-awaited, often replicated, getElementsByClassName method. This is good news as we’ll all be just that much speedier as we ditch the various helper functions and go right into the browser for that functionality.

The thing is, the transition, when we’ll finally be able to make it, isn’t a one to one swap. In fact, depending on what you’re using it for you could run into problems transitioning from a helper function to the native method.

Why? Well, the native getElementsByClassName returns a NodeList and the functions an Array. This is a fundamental point as a NodeList, while it has a length and can be accessed by a numerical [index], isn’t an Array. One major difference, and the one that might cause serious problems if you’re not careful, is that it’s live. It doesn’t merely grab the returned value at the time of invocation, it updates its members as the document changes over time.

Here’s a simple example where I run the two versions side by side. Click start and both functions will count the number of “sample” classed elements in the document. A couple of seconds later I simply copy the innerHTML of the container DIV, doubling the number of “sample” elements on the page. As you then see a couple of seconds after that, the native code notes the adjustment to the document, the helper function does not. The counts are different.

Check it out (assuming you have a browser that supports getElementsByClassName):

Why is this important? Well, I don’t know about you, but in doing dynamic effects I often attach classes to elements so that (a) I can add effect-specific styles to them (duh) and (b) I can remember what state they’re in when I next run the function. A lot of times when a function is run I’ll take a snapshot of that collection and run some code like this on it:

var currSelected = getElementsByClass("sample");
		for (var i=0; i<currSelected.length;i++) {
			removeClass(currSelected[i],"sample");
		}

Which ensures that I’m starting with a clean slate by removing class “sample” from every element.

This is where it gets tricky. If I did that with the native getElementsByClassName I would get a weirdo result that looks like this. Click start and run the above code with getElementsByClassName in place of the helper:

For those of you without a compatible browser here’s a screen shot of the result:

With the helper function there would be no blue borders. Since getElementsByClassName is a live connection to the document, both the length and the elements at each index CHANGE as you remove elements from the document.

The reverse would be even worse. Adding classes to elements based on getElementsByClassName would create an infinite loop, since i will never be less than collection.length. Every time you add a new class the length increases by one and the loop never ends.

What does this all mean in practice? I’m thinking I’m going to keep my old reliable getElementsByClass function (or a variation that leverages the native method but returns an array “snapshot”) and selectively use the native method where applicable.

[edited] as was suggested in the comments, I wrote a new getElementsByClass to take advantage of the native code.

CSS Patterns That Need to Die- Yes, I’m Looking Right at You IE6

Here’s it is.

//height for IE6. Thankfully IE6 messes up height in a useful way
height:350px;
//height for everything else. IE6 looks at this and says "wha?"
height:auto;
//min-height for everything else. IE6 is baffled by this.
min-height:350px;

I can’t tell you how many times I’ve used this exact pattern. It actually works really well, it’s just so wrong it bothers me each and every time I type it into a style sheet.

It works because the first height declaration, in pixels, is rendered by Internet Explorer 6 exactly the way the next two rules are rendered by every other browser. Meaning, it starts at 350px and then expands to fill whatever content it contains. Add to that the fact IE6 is baffled by the next two declarations (not understanding auto as a value for height and not supporting min-height in any way, shape or form) and for IE6 height is all you need.

Thing is, every other browser that matters renders the single height declaration (with overflowing content) like this:

min-height

Which is where the height:auto and min-height declarations come into play. Add those in and things start acting as expected with the other browsers- the container starts at 350px and expands to fit the overflowing content.

Since there are no “hacks”, the above sheet will validate, I just hate the pattern of declaring height once and then immediately redeclaring it- especially to support a seven year old browser.

So… IE6? Are you listening? Can you please give up the ghost so I can put this pattern to bed?

Pretty please?

Question: When is a CSS Class not a CSS Class?

Answer: When it’s a unique identifier.

Check out this class attribute generate by my beloved Wordpress’ upload feature:

class="alignleft size-medium wp-image-4590"

See anything suspicious? I sure do. wp-image-4590 is a unique identifier being passed off as a class. Why? I actually have no clue as I’m not privy to the thought process behind that particular piece of code :) What I do know is pretty much demands to be an ID. When I teach this stuff to people, I say “If it’s unique, meaning there will ever only be one of them, make it an ID. If there’s more than one or it’s a general descriptor, make it a class.” So I look at that code block every time I upload an image and I frown. Then I blow away the whole class attribute away, since I use none of them.

This is just splitting hairs, I know. Using a class like that is basically harmless. But, truth be told, splitting hairs helps me solidify my ideas about the way these things should work. That, in turn helps me improve the way my crew and I do our thing. So? Hairs I split and everyone is happier.

I’m just doing my small part to make the web a better place one nitpicky, semantic post at a time.

Google Doctype - First Pass? Very cool.

Google Doctype, as introduced by Mark Pilgrim:

The open web is the web built on open standards: HTML, JavaScript, CSS, and more. The open web is a beautiful soup of barely compatible clients and servers. It comprises billions of pages, millions of users, and thousands of browser-based applications. You can access the open web with open source and proprietary browsers, on open source and proprietary operating systems, on open source and proprietary hardware.

Google has built its business here, on the open web, and we want to help you build here too. To that end, we are happy to announce the formation of an encyclopedia for web developers, by web developers: Google Doctype.

Google Code Blog: Introducing Google Doctype

Personally, I’m excited by this development (both practically and philosophically) and will likely contribute wherever it makes sense for me to lend a hand. Looking at it quickly some of the HOWTO information is already very useful (the web security information especially) and it will only improve with time as more and more dedicated people get involved with the project.

CSS Variables - My Positive Feedback

I really like the idea, especially for “skinnable” apps and sites. We have a few ongoing concerns here that would immediately benefit from an @variables declaration after the reset section. Coding certain large changes, of course, would also be greatly simplified. Count me as a +1.

Initially, I do wonder about rendering performance since there are issues with IE’s CSS Expressions and this seems like it could run into similar issues- then again I’m not a browser developer, so what the hell do I know? :)

Since the release of CSS Level 2 Recommendation ten years ago in may 1998, the Web authors’ community has been requesting a way of defining variables in CSS. Variables allow to define stylesheet-wide values identified by a token and usable in all CSS declarations. If a value is often used in a stylesheet - a common example is the value of the color or background-color properties - it’s then easy to update the whole stylesheet statically or dynamically modifying just one variable instead of modifying all style rules applying the property/value pair. We expect CSS Variables to receive a very positive feedback from both the Web authors’ community and browser vendors.

CSS Variables

What I Learned Tonight at the MITX Event

The panel was a lot of fun.

Not surprisingly, considering the the smart folks I was paired with, I learned a few things myself, the two biggest:

  1. People are really excited about the potential of Opensocial. I guess that shouldn’t come as a surprise, but it was interesting how unanimous the excitement was amongst the panel members (and that ignores the actual Google employee on the panel)
  2. Adobe AIR is the best solution going for cross-platform desktop widgets. Why? They’ll run on a Mac, Windows and even Linux and the development platform (Flash/Flex) is one that is widely supported and relatively easy to staff. compare that to the specialized knowledge needed to unlock the power of some of the other platforms and the fact that work needs to be split amongst them and Air is the way to go.

Thanks to everyone that came out!

Using overflow:auto to Clear Floated Content in CSS

For a long time, I used something like <div style="clear:both"></div> or its class equivalent to clear floated content in layouts. I knew, at some level, there were better solutions, but as these things go- I had deadlines to meet, had a working solution and there was never any inducement to look for a new one. Sure, there was a little extra markup, but it was so limited I could live with it.

Then in a comment on another post here ArkRep gift wrapped a better solution- one I vaguely knew about but had never explored. It looked a little something like this:

.clr {
clear:both;
}
.clr:after {
content: ".";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
.clr {display: inline-block;}

Liking it, since it swapped the useless markup hack thingie for a single class, I took a modified version of his code and moved it into our baseline screen.css at work. I then passed along the addition to the rest of the team. One of them (hi Ryan*), started to do some research into the code above and as an adjunct of that research came across a solution to the problem that was so simple and so clean that it really annoyed me that I didn’t know about it until last week. You can read about the solution in depth at the Sitepoint Blogs (3 years old!)

The simple and clean solution? Use overflow:auto on the containing div and it will, er, contain. Look at this simplified version:

Here’s the relevant CSS:

#container #content {
	overflow:auto;
	border:1px solid gray;
}
#container #copy {
	width:140px;
	border:.1em solid #CFCFCF;
	float:left;
	border:1px solid green;
}
#container #sidebar {
        width:140px;
	overflow:auto;
	float:right;
	blorder:1px solid pink;
}
#container #content #sidebar #sidebar-0{
	float:left;
	border:1px solid orange;
	}
#container #content #sidebar #sidebar-1{
	float:right;
	border:1px solid purple;
	}
#container #content #sidebar #sidebar-0,
#container #content #sidebar #sidebar-1 {
	width: 65px;
}
#container #footer {
	border:1px solid black;
}

I wish there was more to write about, but it’s really that simple. The biggest concern is that your math must work or else you’ll get scrollbars. With other versions of clearing floats, you were allowed to be a little looser with the calculations- if your sidebar actually leaked (overflowed) into the gutter beyond the edge of your container it didn’t actually matter since it would display correctly. With overflow:auto you don’t have that luxury. Of course, who wants to be sloppy? :)

*link? Where should I link?

A New Site I Made is Live and I Have (nearly) Achieved CSS Nirvana

I recently did CSS/HTML and WordPress theming for Tom’s My Card. My Work. blog. Normally, I would get all that excited about a WordPress theme, since I’ve done several, but this one had a lot going for it from a CSS perspective. I’m actually really excited about it.

What’s so special about this one, you ask?

Well, for starters, there’s only one style sheet (1!) and in that one style sheet there’s a total of 0 (zero) rules included for a specific browser. It’s true. Actually, as the last step before I published it out to his server I deleted the lines in my template to pull in an IE6 or IE7 sheet. They were empty :) Across everything else? It just works. No hacks. No weird code. No nothing. Just one style sheet that works in pretty much every major (and minor) browser. I mean it, too- I tested the home page* in Browsercam and it only really fails on browsers that I don’t care about at all- IE5.2 on the Mac, Netscape 4.78, IE5.0 and IE5.5, etc.

I have seen the future**, and it is one style sheet with no hacks.

Hallelujah.

In fact, when coupled with another technique I used for the first time in this layout (using overflow:auto to clear floats) and the fact that it’s fully em-based and scales like a dream, this layout is probably the cleanest I’ve ever done- at least in terms of CSS.

Some time soon I’m going to clean the markup up further to get it in line with the level of the CSS in terms of cleanliness (I didn’t fully craft every line in the theme, using some default markup in places,) re-skin it and publish it out as a theme for folks to download. That’ll be pretty sweet.

Beyond that, which is going to take a little while so I’ve got to do something to tide you all over, I’m going to detail some of the techniques at play in the layout later on this weekend, starting with a head-slapping, *doh* filled post about the magical powers granted by my newfound knowledge of overflow:auto.

overflow:auto!

*Bugs will shake out in both the home page and other pages. I know this.

**Frighteningly it fails in IE8 beta, but then again it is a beta (fingers crossed)