Progressive enhancements with JavaScript and CSS

It is clear that IE6 is not going away just yet, at least not for mainstream websites targeting a large (and non-tech) audience. Quite some time and effort is put into making design and functionality work in IE6 which otherwise works perfectly well in more modern browsers. This is inefficient, but just because IE6 support cannot be dropped does not mean the cause is lost. The key is to not think black and white, instead think in terms of progressive enhancements.

The fundamental concept of progressive enhancements are that anyone may use the functionality, but a more enhanced version is available for those with more advanced browsers.

Having a complex feature with pixel perfect appearance and functionality in all browsers usually means that you implement it on standard compliant browsers, and then provide workarounds to make it work in Internet Explorer (usually a significant amount of work). The key to reduce this waste of time is not to skip IE6 entirely (which may not be an option), but to let go of having everything exactly the same in all browser. Instead, provide the basic functionality to IE6 but add the shinyness and bling to newer browsers.

The old approach

About a year ago I did a JavaScript map implementation (similar to Google Maps) and it had an info box popup that could contain additional information. The original requirements were that it should have rounded corners and a pointer that depending on position could point in four directions (flipping when the map moved). In addition the dimensions should automatically size to the content unless a fixed width and/or height were set.

Old (complex) InfoBox implementation

Old (complex) InfoBox implementation

And it should look exactly the same in all browsers. This single line of requirement resulted in the implementation becoming one of the largest and most complex modules in the whole mapping application. Using css sprites for the corners, off-screen rendering to estimate size, lots of IE workarounds and so on… probably 60% of the development time were spent on compatibility issues.

The modern way

I recently had the opportunity to rewrite the info box implementation, using a much smarter approach. The key was that the basic functionality should work in IE6, but it shouldn’t necessary look the same.

This resulted in an implementation that was 1/5 of the number of lines of the original, didn’t require additional images for the corners (reducing number of HTTP requests), no IE hacks and was a lot more flexible.

By using border-radius and box-shadow available in CSS3 the implementation was very simple, and we even got a drop shadow for free.

InfoBox in modern browsers

InfoBox in modern browsers

Using an old or non-standard browser like Internet Explorer resulted in the following look.

InfoBox in Internet Explorer

InfoBox in Internet Explorer

Still functional and useful, but without the extra visual appearance. However, instead the development time was dramatically reduced and the implementation dead easy instead of very complex.

The challenge

This is all pretty straightforward, why do it any other way? Usually the challenge is not technical, but rather to communicate this to the stakeholder. Most organizations simply state “Support IE6+, FF2+, …” implicitly resulting in requirements demanding exactly the same functionality pixel by pixel between the supported browsers.

This is where it gets wrong and the challenge is to change it! It is not about being supported or not supported – it is about to what extent should a browser be supported! IE6 may be supported in a way that the core functionality is useful, but it may look less attractive and some fancy (but non critical) features may be removed.

To what extent each browser should be supported should be a conscious and strategical choice! The benefits are huge with productivity gains, less complex code and faster time-to-market. And it is up to you, as a developer, to communicate this and make it happen!

iPhone Developer Meetup Stockholm

Just organized the first meetup of Sweden iPhone Developer User Group in Stockholm.

Presentations available here and a report from the evening at iphone24.se (in Swedish).

Using screen for linux background processing

Perfect for long running batch jobs on a remote server over unreliable connections or if you want to bring your laptop home (instead of keeping that terminal running).

Log in and run
screen -t title_of_your_choice

Do the same thing again if you want to create another window.

All the following screen commands are preceeded by Ctrl-a (i.e. first press ctrl-a then the shortcut below)

  • 0-9 – switch to window by id
  • Ctrl-n – next window
  • Ctrl-a – previous window
  • K – kill window

The next day, log in as usual and attach to the screen session using

screen -x

Check the man page for screen for other options and shortcuts.

Xcode won’t build for iPhone 3.0.1

After updating to iPhone 3.0.1 (the SMS security fix) Xcode refuses to build and deploy to the iPhone, claiming it doesn’t support that version. However, 3.0 (and not 3.0.1) is currently the latest supported version.

To fix this, execute the following (everything in one line) in a terminal to create a softlink for 3.0.1 to 3.0:
ln -s /Developer/Platforms/iPhoneOS.platform/DeviceSupport/3.0\ \(7A341\) /Developer/Platforms/iPhoneOS.platform/DeviceSupport/3.0.1

For more information, see the iPhone OS 3.0.1 Advisory available at the bottom of the iPhone SDK page (in the downloads section).

Internet Explorer cross-site scripting warning

I came across the warning “Internet Explorer has modified this page to help prevent cross-site scripting.” which is triggered by the IE8 security filter.

However, IE gives no clues of why the warning was triggered or what was modified to prevent it. Annoying.

To get some more information you must download Microsoft Application Compatibility Toolkit and run the Internet Explorer Compatibility Test Tool.

More information about this particular issue with XSS is available here.

It is possible to stop this warning from occuring (beside actually fixing the underlying issue) by adding a custom header entry: X-XSS-Protection: 0