Apr 1

i see your schwartz is bigger than mine

scene from the movie spaceballs

A week or two ago a perl 6 enthusiast friend of mine mentioned how he’d, “just used a Schwartzian transform to answer a guys question in #perl” during the brief passing of an otherwise routine instant message conversation.

Knowing nothing about the Schwartzian transform — in fact, only hearing of its existence for the first time — and not wanting to look like a narc in front of my nerd fanboy friend. I did what any self-respecting good guy would do. I turned to the google.

I skimmed through the wikipedia page felt slightly confused, read it properly and gained a better understanding. I also happened on this page which lists the implementation of the Schwartzian tranform in several different languages. Except one, your favourite AND mine: JavaScript.

So I decided I would implement a Schwartzian transform in JavaScript and design a crude test to see the performance benefits for myself.

The test sorts arrays of strings — containing numbers with thousands separators — in ascending order of lengths: 20, 200, 800, 1600 & 2000; and uses arrays in descending order, as well as randomly ordered arrays.

Before I explain the benefits of using a Schwartzian transform over a regular sort, I’ll go through the code required to implement a Schwartzian transform.

As it turns out, this is hella-easy and — the actual sort — only requires one line of code, if you like squeezing code onto one line. For the purposes of explaining this technique though, I will be more verbose.

function getValue( o ) {
    /* returns a specific value from item: o */
}
function compareFunction( a, b ) { // depending on how you want to sort, asc or desc, your sort function would look something like this
    var _a = a[1], _b = b[1];
    return _a == _b ? 0 : _a < _b ? -1 : 1;
}
var unsorted_array      = [/* array of stuff */], // the schwartz starts here
    paired_array        = unsorted_array.map( function( o ) { return [o, getValue( o )]; } ),
    paired_array_sorted = paired_array.sort( compareFunction ),
    sorted_array        = paired_array_sorted.map( function( o ) { return o[0]; } );
 

Breaking it down

unsorted_array — is the array of unsorted values we want to sort.

paired_array — is the result of iterating through unsorted_array to create and return, a new array, of tuples, containing the original item and the value we want to sort on. This would look something like this:


[[original_item_1, sort_value_1], [original_item_2, sort_value_2], ..., [original_item_N, sort_value_N]]
 

paired_array_sorted — is the result of sorting paired_array, though as sorting happens inline, paired_array_sorted is the same as paired_array.

sorted_array — is the result of iterating through paired_array_sorted and returning the first, original, item from each tuple.

Putting it all on one line we can get something like this:


sorted_array = unsorted_array.map( function( o ) { return [o, getValue( o )]; } ).sort( compareFunction ).map( function( o ) { return o[0]; } );
 

What’s the benefit of using a Schwartzian tranform?

When I first saw this, I thought it was kind of complex and that running a map on the array we want to sort, twice, was excessive. But have a look at the code for just using a regular sort:

function getValue( o ) {
    /* returns a specific value from item: o */
}
function compareFunction( a, b ) { // depending on how you want to sort, asc or desc, your sort function would look something like this
    var _a = getValue( a ), _b = getValue( b );
    return _a == _b ? 0 : _a < _b ? -1 : 1;
}
var unsorted_array = [/* array of stuff */],
    sorted_array   = unsorted_array.sort( compareFunction );

At first glance this looks much more elegant, I mean there is a lot less code. But in actual fact this sort can take a significantly longer amount of time to complete than the Schwartzian tranform sort, depending on the time it takes to retrieve each value from the getValue function. Why?

…the Schwartzian transform actually reduced the order of complexity of the number of times the keys are calculated from O(N*log(N)) to O(N).

Optimizing Code for Speed - wikibooks

In plain english this means:

  • Using the Schwartzian method, we calculate the values we want to sort on, for every item in the array, ONCE, storing them with their original item in a new array.
  • Using a regular sort, we are calculating the values we want to sort on, EVERY TIME the sort function compares two items in the array.
Chart time!

So with this post almost at an end, it’s time to display a chart, showing the efficiency of the Schwartzian tranform over a regular sort, for the test I created.

graph: regular sort vs schwartzian transform

I ran the test in the latest stable versions of each browser on a MacBook Pro with OS X 10.6.3. Except Internet Explorer which I tested using a VM running Windows XP. Sorry the graph times aren’t incrementing nicely, Internet Explorer’s times blow the whole graph out and I wanted to show the distributions more clearly.

As you can see though, in each browser the Schwartzian transform far out performs a regular sort for this test.

Conclusion

The Schwartzian transform is a simple method we can use to improve the performance of sorting arrays of items, where the values we wish to sort on involve expensive calculations. However, you should always consider when to use this method on a case by case basis.

PS. This is NOT an April fools’ day prank. :¬P


Mar 18

css organisation: putting it all together

Ok, so no series is complete without an example. I’ve created two very simple pages, which should look the same as each other. However, they will degrade gracefully in less capable browsers.

The pages all have their CSS inline, except for the reset CSS. They have been tested on FF3.6, Safari4.0.5, Opera10.5beta, Chrome4 and MSIE6+.

The first page achieves cross browser css using JavaScript, alphabetised style properties, hyphenated classes and short consistent naming conventions.

The second page uses conditional comments, browser hacks, style properties in any order and camelCase class names.

My (biased) opinion is that the first page’s CSS is easier and quicker to read, debug and update. I can clearly see all the browser adjustments for a specific rule and if I need to make a change to a property or add a new browser or browser version override, I know immediately where to look. If a user has JavaScript turned off for whatever reason — try it — the page doesn’t explode in any of the tested browsers. If I walked into a new contract with a CSS code base similar to this, for a change, I would be one happy chappy!

What I don’t like about the second page is all the scrolling I have to do to see all the browser and browser version overrides. What makes this worse is that generally you would put the Internet Explorer hacks in separate files, this would mean having to tab back and forth between files, it really slows you down and as I’ve already said, you have hacks everywhere. No thanks, not for me; if it has to be done, I like to be able to see it all in the one place.

So, at this point I’d like to ask — if anyone out there in internet land actually reads this blog — What do you think? Which is your preference and why? If you are generally a page two kind of developer, would you consider doing things in a page one kind of way in the future? And if not, why not?


Mar 15

css organisation: hyphenate classes and ids, use short and consistent naming conventions

In this post we will see how implementing a consistent naming convention for our CSS classes and ids, using hyphen delimiters, will allow us to easily arrange our CSS into concise modules making our style sheets more organised and can also speed up our page loading and rendering too.

For the remainder of this post I will be referring mainly to CSS classes, though the same principles can and should be applied to IDs as well.

Use hyphens, not camelCase

There is nothing stopping you from using camel case. I’ve always found using camel case for defining CSS classes makes your code look messy and harder to read when skimming through an html page. It is also easier to search for hyphenated CSS classes in JavaScript rather than camel case as we generally uses camel case naming conventions in JavaScript. Consider the following code:

ns.fooBar = $( '.fooBar' );
ns.fooBar.bind( 'click', function() {
   ns.fooBar.toggleClass( 'selected' );
} );

Compared to this:

ns.fooBar = $( '.foo-bar' );
ns.fooBar.bind( 'click', function() {
   ns.fooBar.toggleClass( 'selected' );
} );

Your eye has a much easier time finding the foo-bar CSS class amongst all the fooBar JavaScript variables. When you have thousands of lines of code to skim through, this can become a valuable time saver. If you want to do a search and replace on .fooBar, it also leaves a greater margin for creating a JavaScript error — as you can see the JavaScript property ns.fooBar is also preceded by a period — whereas search and replacing on .foo-bar would not only be a much quicker search, it almost eliminates the margin for error by excluding all fooBar strings. Hyphens are not valid characters for standard JavaScript variable/ property names, it’s worthwhile having thus clear separation of presentation and behaviour.

However, if that’s not enough to convince you. Using a hyphen also makes it easier to use a CSS class to hold values we want to later retrieve using JavaScript. Consider the following simple example:

<div class="carousel horizontal3easeIn">...</div>

<script type="text/javascript">
   var optionsStr = documents.getElementsByClassName( 'carousel' )[0].className.split( ' ' )[1], 
       carouselOptions = optionsStr.match( /([A-Za-z]+)(d+)(.*)/ ), // regex to extract carousel options
       carousel = new Carousel( {
          orientation : carouselOptions[0],
          itemsPerPage : carouselOptions[1],
          animation : carouselOptions[2]
       } );
</script>

To get the options to initialise the JavaScript Carousel class we need to create a regex to extract the values from the CSS class, horizontal3easeIn. This means, if we want to add more options or change the order of these options, we would need to keep adjusting the regex as well as the instantiation code. Consider the next example:

<div class="carousel horizontal-3-easein">...</div>

<script type="text/javascript">
   var optionsStr = documents.getElementsByClassName( 'carousel' )[0].className.split( ' ' )[1], 
       carouselOptions = optionsStr.split( '-' ), // simple String.split
       carousel = new Carousel( {
          orientation : carouselOptions[0],
          itemsPerPage : carouselOptions[1],
          animation : carouselOptions[2]
       } );
</script>

With this example we only need to split the CSS class, horizontal-3-easein, at the hyphen delimeter. There’s nothing complicated and it’s a lot faster than using a regex.

So to keep things simple, consistent and fast we will only use hyphens in our CSS code.

Don’t include the tag name!

The amount of times I’ve seen code like this:

<style type="text/css">
   #containerDiv {}
   .leftDiv {}
   .middleDiv {}
   .rightDiv {}
</style>
...
<div id="containerDiv">
  <div class="leftDiv" />
  <div class="middleDiv" />
  <div class="rightDiv" />
</div>

I mean seriously, at what point do you think you’re going to forget any of these are a div tag and if you did why would that matter?

There is really no need for this kind of verbose commentary in HTML/ CSS, leave it out, it’s annoying and looks amateurish. That’s all I have to say about that.

Use classes not tags

These two fantastic articles on Writing Efficient CSS and Simplifying CSS Selectors outline how browsers match a rule and the performance losses and gains from using different types of CSS selectors. They also include links to further research on the subject. In my opinion this is all mandatory reading for anyone who builds web user interfaces using HTML/ CSS.

Adaptability

The one thing I will say is, using CSS classes instead of tags will allow you to change a tag in your HTML document without having to change your style sheet.

The best example I can give is the use of headings. If you are as fanatical about correctly nesting your headings as I am, then consider the following example:

<style type="text/css">
   .foo-ct h3 {}
</style>
...
<div class="foo">
   <div class="foo-ct">
     <h3 class="foo-hd" />
     <div class="foo-bd" />
     <div class="foo-ft" />
   </div>
</div>

If we want to reuse this module in a different section of our page/ site where the <h3> would be an <h4>, we would need to add more styles to our stylesheet to reflect this or our headings could potentially be different sizes and worse, lacking specific styles like backgrounds, borders, colours, etc.

Using the CSS class .foo-hd instead of the tag, allows us to adapt our mark up without having to, also adjust, our style sheets.

Having a system/ Keeping it simple

Having tried to implement this type of naming convention in a few jobs, I’ve seen some developers churn out CSS/ HTML code with some crazily long class names — I’ve seen some class names with over 30 characters. Consider the following (tame) example:

<style type="text/css">
   .foo {}
   .foo-container {} 
   .foo-container-header {} 
   .foo-container-body {} 
   .foo-container-footer {} 
</style>
...
<div class="foo">
  <div class="foo-container">
	 <h3 class="foo-container-header" />
	 <div class="foo-container-body" />
	 <div class="foo-container-footer /">
  </div>
</div>

Repetition like this seems ridiculous. Why do we need to repeat the word container in each of its childrens’ class names?

The first thing we can do is get rid of the container- in the header, body and footer div tag class names. That’s easy, but why do we need long names like foo-container, foo-header, etc? If we want to be more efficient we can further reduce those names down, as in the following table:

class namedescription
ctcontainer
hdheader
bdbody
ftfooter

Let’s look at the revised code:

<style type="text/css">
   .foo {}
   .foo-ct {}
   .foo-hd {}
   .foo-bd {}
   .foo-ft {}
</style>
...
<div class="foo">
   <div class="foo-ct">
      <h3 class="foo-hd" />
      <div class="foo-bd" />
      <div class="foo-ft" />
   </div>
</div>

Say you’re building a site for an online retailer and they are displaying 100 products on a page using this format. The first example has an extra 4kb of CSS class names in the HTML page for the end user to download!

Having a set of abbreviated class names in a table like the one above — that you can easily print out and stick on a wall visible to all developers, or as a card developers can have on their desks — can greatly reduce the amount of time developers need to spend coming up with their own class names, improve the consistency of your naming conventions and reduce your overall page weight, without the need of a lengthy document.

Conclusion

Having a consistent naming convention for your CSS classes and IDs, using a hyphen delimiter, and assigning style rules to CSS classes, instead of tags, will help to make your CSS easier to read, easier to program, with JavaScript and potentially quicker to render.

Abbreviating commonly used CSS class names can help to reduce your overall page weight. Printing them out, in a table and making them easily accessible to all developers, provides a very simple guideline to follow without the use of lengthy documents.

This is part 2 of a 3 part series.


Mar 12

css organisation: alphabetising style properties

I started off alphabetising my style properties very early in my web development career. CSS1 was still relatively new so we were all still using the font tag and spacer images inside nested tables.

My main reason for this wasn’t the orderly, easy to find, easy to read and difficult to duplicate the same property in the same rule structure that was to ensue. It was purely because of a slight obsessive compulsive tendency for neatness.

Nicole Sullivan wrote an excellent CSS wish list a few months ago. However, this post is about what we can do to improve the here and now.

Having a system/ Keeping it simple

When trying to manage any code base, having a system is important. This is generally available in the form of coding standards and guidelines. Unfortunately, these documents can quickly become bloated, reducing their usefulness, by reducing their “readability”; lost in a sea of standards and guidelines on dated wiki or worse, a forgotten directory living in a far off network drive; or as in most cases, due to unrealistic deadlines, standards taking a back seat to an iota’s more code been churned out.

Keeping a simple system, such as alphabetising your properties makes it not only easy to remember, but also easy for developers joining your existing project to become familiar with.

As well as alphabetising my CSS, I also like to include similar properties on the same line — think border-*, font-*, margin-*, etc — as long as readability is maintained. Consider the following rule:

.foo {
   background : #fcc ; 
   border-color : #fee #fee #faa #faa ; border-style : solid ; border-width : 1px ; 
   color : #333 ; 
   float : left ; 
   font-size : 1.1em ; font-weight : bold ; 
   height : 50px ; 
   margin : 3px ; margin-left : 5px ; 
   padding : 2px 4px 3px ; 
   position : relative ; 
   width : 150px ; 
}

If I want to know what font properties are declared in the rule, my eye scrolls down from b, c to f, if I want to know what margin properties are declared, my eye scrolls down from b, c, f, h to m.

Compare this to the same rule with the properties in a random order:

.foo {
   position : relative ;
   float : left ;
   height : 50px ;
   width : 150px ;
   margin : 3px ; 
   border-color : #fee #fee #faa #faa ; 
   border-style : solid ; 
   border-width : 1px ;
   padding : 2px 4px 3px ; 
   margin-left : 5px ; 
   font-size : 1.1em ;
   background : #fcc ;
   color : #333 ; 
   font-weight : bold ;
}

The first rule is making CSS easy to skim through, eliminating the time it takes to find specific properties in a rule. The second rule requires more time to look through to find there is margin-left override on the previous margin property, more time to see that there is a font-size property as well as font-weight property on the rule, etc.

Though this “extra time” might not seem like much at first, when you start looking at the size of some CSS files — anywhere from 700-2000+ lines — it can quickly add up!

Tools like Firebug alphabetise your rules for you — as well as showing you what rules belong to what files — in their CSS editors. However, this doesn’t always stop people lazily copying and pasting the code from firebug into their CSS files without first removing the existing rules. These tools also don’t show duplicate properties on a specific rule, so be careful not to duplicate properties!

Rules are meant to be broken (sometimes): Browser specific CSS3 properties

The only caveat to this very simple method of keeping your CSS tidy is the new CSS3 properties available in some browsers. The main reason being: browsers’ implementations of these properties using their own specific namespace e.g. -moz-*, -webkit-*, etc.

There are two ways we can work with these properties: by sticking to the original guideline and having all the browser specific properties at the top or bottom of the rule. Shown below:

.foo {
   background : #fcc ; 
   border-color : #fee #fee #faa #faa ; border-radius : 3px ; border-style : solid ; border-width : 1px ; 
   box-shadow : 1px 1px 7px #999 ; 
   color : #333 ; 
   float : left ; 
   font-size : 1.1em ; font-weight : bold ; 
   height : 50px ; 
   margin : 3px ; margin-left : 5px ; 
   padding : 2px 4px 3px ; 
   position : relative ; 
   width : 150px ; 
   -moz-border-radius : 3px ; 
   -moz-box-shadow : 1px 1px 7px #999 ; 
   -webkit-border-radius : 3px ; 
   -webkit-box-shadow : 1px 1px 7px #999 ;
}

Or, by separating out the CSS3 properties onto a separate line and including the browser specific versions of these properties on the same line, as in the example below:

.foo {
   background : #fcc ; 
   border-color : #fee #fee #faa #faa ; border-style : solid ; border-width : 1px ; 
   border-radius : 3px ; -moz-border-radius : 3px ; -webkit-border-radius : 3px ; 
   box-shadow : 1px 1px 7px #999 ; -moz-box-shadow : 1px 1px 7px #999 ; -webkit-box-shadow : 1px 1px 7px #999 ; 
   color : #333 ; 
   float : left ; 
   font-size : 1.1em ; font-weight : bold ; 
   height : 50px ; 
   margin : 3px ; margin-left : 5px ; 
   padding : 2px 4px 3px ; 
   position : relative ; 
   width : 150px ; 
}

My preference is for the latter version. My reasons being:

  • It’s easier to update the properties as they’re all on the same line; and
  • It’s easier to skim through the standard CSS3 properties and then see the browser specific properties next to them.

Conclusion

Alphabetising your CSS properties is an easy way to neaten up your CSS, eliminate the possibility of duplicate properties in the same rule and it generally speeds up finding properties in a rule.

It will greatly improve a new developer’s familiarisation with your project’s CSS codebase, as it provides a very simple guideline to follow.

This is part 1 of a 3 part series.


Mar 5

a.b.a: cross browser css

I first saw this technique in Jack Slockum’s Ext JS framework.

There are a range of CSS hacks and other types of work arounds available to target the inconsistencies in the various CSS rendering implementations of different browsers; and different browser versions.

A lot of developers I’ve worked with vehemently support the use conditional comments — this is, to insert IE specific stylesheets into a page, to target the various versions of Internet Explorer. Their reasons being:

  • It’s only picked up by Internet Explorer so other browsers don’t have to worry about downloading irrelevant CSS code.
  • You can keep all your different Internet Explorer CSS hacks separate so as you stop supporting versions you can simply remove the offending file and conditional comment code.
  • It’s neater than having all your CSS hacks in the one file.
  • CSS hacks aren’t generally valid CSS and your stylesheet will not validate if you include them in your stylesheets.

Needless to say I tend to disagree with all four of these reasons. My reasons being:

  • What about versions of Firefox, Opera and Safari that need specific hacks in place to get them to display your page correctly? Now you have some hacks in your main stylesheets and others in another file. All your hacks are all over the place, it makes bug fixing a lot more time consuming!
  • Having some styles, in a separate stylesheet, that override styles in your main stylsheet — for a specific browser/ version — makes it harder to see the overall all picture. I have to either remember, or worse, if I am not familiar with the codebase, constantly check the IE specific stylesheet to see if IE specific hacks are in place. It makes developing and debugging a lot more frustrating and time consuming.
  • I now not only have separate stylesheets to worry about, I have to add conditional comments to my templates to make sure they pick that stylesheet up, then manage the stylesheets AND the conditional comments when new versions of a browser come out. Generally this means — for sites with badly designed templates, which, from what I have seen, is a lot — regenerating, retesting and releasing the whole site again. Very time consuming!
  • It’s an extra HTTP request for only IE, especially IE6 which only supports 2 downloads per domain, and probably for only a small amount of extra CSS code.
  • IE is probably your biggest market share and you’re punishing them with this extra download.
  • It’s easier to see what’s going on when you have all your hacks for each browser grouped together rather than scattered all over the place.
  • How many users care whether or not your CSS validates? Chances are it’s going to be less than a percent of them.

A Better Approach

I’ve used Ext JS on a few big “single page application” projects over the past 4 years. It’s an amazing framework, In my opinion, it’s probably the best and most complete — inlcuding documentation and samples — JavaScript UI framework on the market, at the moment.

One of the first things I wanted to know was: how does it get it’s UI components to look the same in all supported browsers?

It definitely doesn’t use conditional comments because you only need to include one stylesheet and one JavaScript file if you want to use everything Ext has to offer. I started looking at its stylesheets to see if I could find any hacks, none.

What I did find were styles like:

.ext-ie6 .x-form-text, .ext-ie7 .x-form-text {...

In case you can’t tell, this specific rule is targetting IE’s versions 6 & 7.

So I looked at the Ext JS API doc’s generated markup in Firebug and saw this:

<body class="ext-gecko ext-gecko3 ext-mac"/>

And in Safari’s debugger, this:

<body class="ext-safari ext-mac"/>

In case you can’t guess, these classes were added to the body tag via JavaScript.

To me this is a brilliant idea! So brilliant I have used it on other projects to make it easy for all developers to write cross browser CSS. I will also be using this approach in the thudjs framework for the same reasons.

But this will only work with JavaScript turned on…

All I can say to that is, “So?”. How many of your users are actually using your site WITHOUT JavaScript turned on? Do you actually test your site(s) without JavaScript turned on, in every browser? Chances are you’re either living in a fantasy world or your site is so simple you don’t require any hacks or cross browser CSS.

This technique still conforms to the principles of graceful degredation/ progressive enhancement. You’re site may look a little b0rked to 0.001% of your users, if that. It does not mean that this miniscule percentage of users will not be able to navigate your site.

This is the technique you want to use if you want to make your CSS easier to maintain and reduce your overall development/ bug fixing time.

Imagine opening a CSS file and seeing code similar to this:

#container { background-position : left top ; background-repeat : no-repeat ; width : 100px ; }
.gecko  #container { background-image : url(firefox.png) ; height : 97px ; }
.ie     #container { height : 94px ; }
.ie6    #container { background-image : url(msie6.png) ; }
.ie7    #container { background-image : url(msie7.png) ; }
.ie8    #container { background-image : url(msie8.png) ; }
.safari #container { background-image : url(safari.png) ; height : 88px ; }
.chrome #container { background-image : url(chrome) ; height : 104px ; }

Now to me, that is an easy to read snippet of CSS. Rather than having to waste time looking for hacks or sifting through different files looking for the correct rule(s) to change. I can see the main rule and what browsers/ versions required adjustments. If there are any bugs raised with specific browsers/ versions I can make quick adjustments. If a new browser version comes out that fixes a previous CSS rendering bug or updates its CSS3 support, I can take care of it in a matter of a few minutes.

Your choice…

If your interested in this approach to cross browser CSS, I have created a standalone script available for download (less than 1kb gzipped). It creates a global object called UserAgent which you could very easily change to sit under your own namespace. There’s also a test page to display all the values contained in the UserAgent object, the classes assigned to the page’s documentElement (HTML tag) and an approximation of how long it took to complete the operation, for anyone interested in how this script will affect page speed — it’s generally less than 5ms.

However, if you get your kicks from making things difficult for yourself, well then there are, as we’ve seen, a few choices at your disposal. :^)