Posts Tagged ‘cross-browser’

min-width and max-width with Javascript (IE Hack)

Wednesday, November 5th, 2008

So, recently some of the pages I wrote require me to apply certain CSS feature not supported by IE6. The max-width and min-width. They are what they say, provide a minimum and maximum width requirement for a box element. They work like a charm in Firefox, Webkit, and Chrome, just not IE.

Well, readers who are familiar with cross-browser (in)compatibility problems probably would have encountered similar situations when features work differently in different browser. Short hacking and Google search usually helps a lot. Not in this case. Most pages (well, I only went through the top 20-40 pages in Google search, with several combination of keywords) mention the pretty standard CSS expression hacks, like this one. It’s not good enough. CSS expressions are slow. Intuitively, it should run on every resize. But that’s not the case. Steve Souders research into CSS expressions are still fresh in my mind. Expressions executes on every page resize and mouse move events1! Not good!! Definitely not good!

The next obvious move is to use Javascript and register your own handler. Unfortunately, either the CSS expression hacks are too popular or nobody publishes Javascript code that does this, I could find no results in Google. So I didn’t waste any more time and roll out my own hacks. The hacks is darn simple (okay, not darn simple, but not too difficult either). The idea is to enclose the div where you want to set your max-/min-width with a wrapper div that should have a width of 100%. This wrapper div will take the form of the enclosed div should you not place max-/min-width. Subsequently, register a listener to window’s resize that check whether this wrapper div’s width exceeds the max-width or decreases below the min-width and then set the width of the enclosed div appropriately. The crucial part of the code is the following (I simplify it to register directly on window.onresize, which is obviously a bad code, but illustrates the concept well).

// This one for max-width
window.onresize = function() {
  enclosedDiv.style.width =
      wrapperDiv.clientWidth > maxWidth + 1 ?
          maxWidth + 'px' : 'auto';
}

// And this one for min-width
window.onresize = function() {
  enclosedDiv.style.width =
      wrapperDiv.clientWidth < minWidth + 1 ?
          minWidth + 'px' : 'auto';
}

Replace enclosedDiv and wrapperDiv by the appropriate elements as mentioned in earlier paragraph. Btw, You only need to do this in IE. In other browsers, just set the CSS properties appropriately.

Notice the maxWidth + 1 and minWidth + 1? Without the + 1, IE will lock because of race condition. (This page also mentioned this problem, so it seems like a common problem, and not because of my incompetence.)

Right now I’m writing a library that is specialized for this problem. Look forward for it soon. The libraries will handle multiple resize handlers graciously (well, technically, you only need 1 resize handler that resize all the divs in the page in the correct order; and you define the order). The library should also handle creation of the wrapper for IE automatically. In fact, 90% of the library is done, but I’m not confident of releasing it because I haven’t actually tested it at all! I’m going to replace my hacks with the library, if it works fine after we test it, it’ll show up in this blog.

Javascript is fun (yes, cross-browser compatibility is painful, but isn’t it the thing that makes Javascript colorful?)!

  1. http://developer.yahoo.net/blog/archives/2007/07/high_performanc_6.html []