- We design and build extraordinary applications for companies looking to make the next great idea a reality.
- learn more
Developer’s Notebook: Find computed styles in IE, Firefox, Opera or Safari
At my recent Web 2.0 Expo talk, I exhorted developers to get comfortable outside the Firebug/Firefox safety zone. By rotating between Opera, Safari and even IE as our primary development environments, we can really get to know those browsers - and perhaps learn to utilize their non-standard features. Switching things up, however, can inhibit productivity until you learn your way around each browser's tools.
To that end, I offer these step-by-step instructions for finding computed styles in all four A-grade browsers. I chose the display of computed styles as my "debuggers are cool" use case because it's an obscure but useful feature for CSS debugging. Most of the time I can debug styles by looking at my debugger's snapshot of the current cascade for a given element. But sometimes that's not enough. If I've assigned a value of "inherit" to the font-family of an element, then the cascade snapshot won't tell me what font is actually applied to that element. (Not being a designer, I often can't tell the difference between various sans-serif faces, especially at small sizes.) Luckily, computed styles can give me the information I need.
As these examples demonstrate, debugging tools have come a long way in the last couple of years. Let's make the most of them for all of our UI-layer needs.
Internet Explorer 8 and DebugBar
500
IE's JavaScript debugging tools have finally matured, but its CSS ones lag behind. Even IE8, with its built-in debuggers (under Tools > Developer Tools), won't show you computed styles. Luckily, Jean-Fabrice Rabaute has crafted DebugBar, an plugin for Internet Explorer 5+ that adds all sorts of useful tools. Install DebugBar, fire up your version of IE and choose View > Toolbars > DebugBar to make the plugin visible. Then click the "DebugBar" icon in the resulting toolbar to open the DebugBar sidebar. You'll see two tabbed panes, one below the other. Choose the "DOM" tab on top and the "Comp. Style" tab on the bottom. In the upper pane, you should see a target icon with the caption "Drag target on document to find element." Drag the icon anywhere on an open web page and you'll see computed styles for the corresponding element in the bottom pane of the sidebar.

Alternate approaches to IE6 and transparent PNGs
Who knew IE6 and transparent PNGs could inspire so much discussion?
When you're churning out tips and tricks on a regular basis, you quickly learn to state things like this:
"I had Problem X, and my solution was Y given constraints Z."
... instead of this:
"The only way to solve Problem X is Y."
I was reminded of this lesson last week, after I posted a series of beginner-level tutorials about overcoming some of IE6's shortcomings with jQuery. My two-part piece on transparent PNG support got picked up by the kind folks at Ajaxian, and boy did the comments come. Between the two sites, we've heard from 20 people so far. A few were from the usual cranky haters. (Thanks to whoever felt the need to write, "Is this year 2001? IE6 png transparency? News on Ajaxian? Good heavens..." instead of just moving on to the next post.) But the rest provided lively debate and some valuable alternative approaches to the problem.
For review, here are the posts (with comments):
And here are some of the various approaches suggested:
Hacking transparent PNG support into IE6 with IE PNG Fix, CSS and jQuery (part 2 of 2)

For the recent redesign of the Pathfinder web site, we made extensive use of transparent PNGs to layer rounded corners and other curvy shapes on top of a non-contiguous background that mixes a black-and-gray gradient with a wallpaper-style repeating logo. Transparent PNGs are the only way to achieve this visual effect using semantic, standards-based markup and CSS - but IE6 doesn't support PNG alpha-channel transparency.
Yesterday, in Part 1 of this piece, we showed you how to install Angus Turnbull's IE PNG Fix on your server to correct this IE6 shortcoming. Today, we'll show how to overcome one use case not covered by Turnbull's script using a couple lines of CSS and JavaScript.
As we explained yesterday:
There is, however, one drawback to Turnbull's script: It can't account for PNG background images with a background-position other than top left. It will restore the alpha-channel transparency to such images, but it will reposition them to top left, potentially making your designs look even worse than they would have with an ugly gray halo where the transparency should be.
Topics: CSS, IE, IE6, Javascript, jQuery, Web Standards
Hacking transparent PNG support into IE6 with IE PNG Fix, CSS and jQuery (part 1 of 2)

Yesterday's post showed how to hack the :first-child pseudo-class into IE6 with jQuery and CSS. Continuing with that theme, today and tomorrow we'll show how to enable transparent PNG support in IE6 (so your rounded corners don't look like the ones in this picture).
Today, we'll look at an awesome open-source script that will cover 90% of your needs. Tomorrow, we'll cook up some custom jQuery-flavored JavaScript to cover the corner cases.
As with many of my recent posts, my use case is the new Pathfinder web site, which launched last month. We took a pragmatic approach to implementing our new visual design using web standards. We practiced progressive enhancement globally, resorting to hacks and trickery only in browsers that aren't fully standards-compliant. (To be honest, that includes most modern browsers, though IE6 is the biggest problem child by far).
Our game plan went like this:
- If possible, implement the desired look and feel across all browsers using only CSS and semantic markup.
- When necessary, serve browser-specific styles using CSS filters.
- Don't deploy non-semantic markup just to achieve a specific visual objective in non-standards-compliant browsers.
- Instead, if only junk markup will achieve the desired visual effect in non-compliant browsers, inject that junk markup via JavaScript.
- The result is a site whose visual fidelity suffers only in non-standards-compliant browsers with JavaScript disabled.
Topics: CSS, IE, IE6, Web Standards
Hacking the :first-child pseudo-class into IE6 with jQuery and CSS

IE6 continues to define the lowest common denominator for our JavaScript and CSS strategies. IE7 may finally have edged past its younger sibling in terms of market share, but as of late 2007, IE6 still commanded commanded close to a third of the market.
For the relaunch of Pathfinder's website, we wanted our code to be standards-compliant and forward-looking, but we didn't want things to fall to pieces in IE6. We therefore used a variety of strategies to achieve a high degree of visual fidelity between IE6 and newer, better browsers. When CSS hacks and filters wouldn't provide us what we needed for IE6, we resorted to one of two strategies:
- Use JavaScript to create the desired visual effect so that only JavaScript-disabled IE6 users would see a less than perfect rendering.
- Just accept a degraded visual experience in a seven-year-old browser with declining market share.
Luckily, strategy No. 1 worked in most cases. Often, a single line of jQuery and a couple of CSS tweaks would create the desired look and feel. This was the case with one of IE6's most annoying shortcomings: its lack of support for CSS's :first-child pseudo-class.
Web standards won’t get you into heaven
The endless hand-wringing over browser version targeting in IE8 illustrates what's wrong with the web standards community. For every sane, rational discussion about the practicalities of future-proofing the web, we get a couple knee-jerk anti-Microsoft screeds and at least one accusation that A List Apart - the standard-bearer of web standards - has somehow sold out by signing on to Redmond's plan.
First, a little background: Howls of protest echoed across the 'net a few weeks ago when Microsoft announced that Internet Explorer 8 would implement a new type of meta tag to enable both forward and backward compatibility in web pages. Once IE8 is out, users will be able to target rendering of their pages to a specific version of IE so that changes to the rendering engine of IE9 (or IE10 ...) won't subsequently "break" those pages. Basically, from IE8, onward, Explorer will include multiple rendering engines and display individual pages based on the browser version targeted by this new meta tag. The markup will look something like this:
<meta http-equiv="X-UA-Compatible" content="IE=8" />
I have no interest in debating whether or not it's "semantic" and "standards compliant" to include the name and version number of a specific user-agent in my markup. That's already been debated to death (on the 200,000+ pages Google currently reports for the keywords "IE8 meta tag"). What I want to know is this: Will Microsoft's move make my job as a web developer easier or harder? At this point, the jury's still out, but I think the answer is probably "easier."
Topics: Browsers, IE, Web Standards
Ajax, Browsers, Running Out of Time
History repeats itself, first as tragedy, second as farce. -- Karl Marx
I can remember the day, back in 1994, when I abandoned the Mac for Windows. It was a gloomy, overcast day when I made that bittersweet decision -- I was a Mac and Unix nerd all through college -- but after my twelfth or thirteenth crash of the day, I had had enough. Photoshop, Netscape, Secure Shell and Word were just not meant to run more than one at a time on Mac OS 7. Had I stayed with Apple through that rough patch I'm sure I would have been slimmer, sexier and happier, but NT 3.51 only crashed twice a day, so my hand was forced. I ran out and bought a PC that very day.
Now I fear history may be repeating itself. Yesterday, I had Firefox 2 for linux crash 5 times, and IE7 for XP crash 7 times. The cause? Too many fat Ajax applications. Zimbra, the whole Google bestiary of applications, Yahoo Mail, etc.. These are all long running applications that I keep open for most of the day. Then all of a sudden the Browser is gone and I have to relaunch and login all over again.
I'm not alone in this. Colleagues and friends report similar problems with Safari/Mac, IE7/Vista, Firefox/Mac. I've even checked with a friend that runs the helpdesk for a large firm: reported problems with browsers are up. The only one who seems blissfully unaffected is the lone Opera nerd in my office. He just keeps chugging along with what seem like 200 open tabs.
The cause should be evident to everyone. We've taken what was first called LiveScript -- a crufty embedding just good enough to validate a form or two -- and we've abused it into being the foundation for a whole new kind of application platform. The browsers have just not kept up and the situation will only get worse with the accelerated proliferation of Web 2.0 apps.
Help is on the way, in the form of bytecode interpreters and vm's for Safari and Mozilla, though the future of IE is still cloudy (still, there is a plan to bring Tamarin to IE). But if the new Browser version don't arrive quickly enough, or if they don't fully solve the problem of browsers crashing once an hour, then a mass migration to Opera may be the best we can hope for. At worst, content and application producers will opt for more stable non-Ajax alternatives such as Flash or Silverlight.
Ajax and the browsers it depends on are running out of time. If the notion spreads that it isn't reliable, it will be as dead as the Java Applet, never to be heard from again.
Topics: Ajax Applications, Browsers, Editorial, Firefox, IE, IE6, IE7, Javascript
DOMContentLoaded and the quick rise of de facto standards
There's never been a better time to be a JavaScript developer. JS hit the big time with the advent of Ajax, and overnight client-side programmers went from being the redheaded step-children of the web-development world to front-and-center participants in the RIA revolution. Even if you're working on a team of one, there's a thriving global community of JavaScript gurus constanly pushing the language forward, working out browser kinks, demonstrating how to import concepts from other languages and computing paradigms, and otherwise inspire you. It's a big change from 10 years ago, when you had Webmonkey and the David Flanagan book and a few cookbook-style compendiums of tips and tricks. This is seriously the golden age.
Working for the last couple of months on Really Simple History, though, I've become interested in the way specific techniques become the flavor of the month and quickly redefine how we conceptualize "good" JavaScript coding practices. Take, for instance, DOMContentLoaded. After the first version came onto the scene, within a matter of months we had many competing implementations of the basic concept that your scripts shouldn't have to wait for window.onload to fire before getting down to business. Now, DOMContentLoaded is the de facto start point for many, many JavaScript applications. Heck, it's even the basis of the entire jQuery event model. There's nothing wrong with that, but widespread use of Ajax toolkits can conceal the fact that DOMContentLoaded is just a collection of hacks. It works, as long as our toolkits keep iterating one step ahead of the browser vendors. But do we really need it?
At Orbitz Worldwide, my previous employer, we implemented a first-rate unobtrusive-JavaScript architecture. (See it in action at Ebookers UK.) Everything was progressively enhanced from dumb markup. That meant our application worked just about everywhere. But it also meant lots of DOM parsing and initialization that couldn't begin until window.onload. As our application grew, this caused enough of a UI flicker - form controls turning into widgets, links morphing into Ajax calls - that we needed to jump the gun on window.onload if we wanted a good experience for the majority of users ... the ones with modern, JS-capable browsers. DOMContentLoaded made sense, and architect Nik Krimm pounced on it.
But for a large subset of websites, there really isn't THAT much difference between window.onload and DOMContentLoaded. If you're merely adding an unobtrusive behavior layer to a traditional, content-driven website, chances are that good old window.onload will perform just fine. There's usually little reason NOT to use DOMContentLoaded. But unless you are developing a desktop-style webapp or implementing progressive enhancement on a foundational level, it's not really necessary. And in certain cases, it just flat-out won't work.
An enthusiastic beta-tester discovered such a case when trying to initialize RSH's dhtmlHistory object from DOMContentLoaded. It broke, and I immediately knew why: RSH relies on the ability of modern browsers to auto-save form data for the life of a session. RSH uses a hidden textarea to cache serialized Ajax application state and render the back button useful again. Internet Explorer doesn't repopulate the cached value of that textarea until an instant after window.onload. If you try to access that cache during DOMContentLoaded, it simply isn't there. This is true of both IE6 and IE7. Therefore, you need to wait for window.onload.
I'm not really sure there's any big conclusion to draw from this example. As I said, it's just interesting to me that in the space of a year or two, DOMContentLoaded has become a de facto standard. As we pile browser hacks on top of one another to push the web forward, sometimes they're going to conflict. Luckily, we can always peek past the curtains and figure out what's going on behind the scenes.
Topics: Ajax Bookmarking, Ajax Frameworks, Browsers, IE, IE6, IE7, Javascript, Javascript Libraries, jQuery, Really Simple History
Really Simple History: Onwards and upwards
I'm excited to announce that I've heard the call and volunteered to tackle maintenance and stewardship of Really Simple History, Brad Neuberg's intuitive, lightweight Ajax history library. Brad developed RSH a couple of years ago, drawing inspiration from the Dojo Toolkit folks to deliver a standalone library that provides back-button and bookmarking support for Ajax apps in IE6 and various Gecko-based browsers. Since, then, many additional Ajax frameworks have implemented back-button and bookmark support, some of them drawing on Brad's work.
Meanwhile, Brad's been too busy with other projects to upgrade RSH for a variety of new and existing browsers: IE7, Opera, Safari/Mac and Safari/Windows. I asked Brad to let me take care of his baby for several reasons. For one thing, I've been an enthusiastic user of the library. For another, I've been wanting to get involved on a more formal basis with open-source JavaScript projects. But most of all, I believe RSH remains a great tool for folks who want a solution to the Ajax history issue without the overhead of a larger Ajax framework.
I'm currently working with Brad to migrate RSH to Google Code, get acquainted with the bug base, and start tackling the thorny issues surrounding Ajax history support in the 2007 browser landscape. I look forward to shamelessly pilfering the many fine solutions uncovered by a large community of developers since Brad's initial work. (Brad was kind enough to point me to this blog post from Bertrand Le Roy, which lays out many of the aforementioned fine solutions and thorny issues.)
In the meantime, I'd love to hear from RSH users about their hopes for the future of the framework. Comments, please, or ping me directly at bdillard (at) pathf.com. Thanks!
Topics: Ajax Bookmarking, Ajax Frameworks, Back Button, Browsers, Firefox, Frameworks, IE, IE6, IE7, Javascript Libraries, Opera, Really Simple History, Safari, Webkit
IE6: The zombie browser
Paul Graham's much-dissected essay Microsoft is Dead offers some witty and perceptive analysis, but it sidesteps the fact that Microsoft's rotten corpse will take decades to decompose. In the meantime, we still live in a world where most people trawl the Internet with a Microsoft browser. I've already linked to Kevin Hale's perceptive essay On the Tenacity of Internet Explorer 6, and I've already covered Eric Meyer's useful techniques for taking advantage of IE7's power while continuing to support IE6. But I've got a few more links to add to Dietrich's and my back-and-forth about the state of JavaScript tooling. I regularly stop by the IEBlog the same way I keep tabs on the neighbors I don't really like but have to live near. They recently added a more in-depth post about Ajax View, a pretty cool profiler that they'd previously covered along with other IE development tools earlier this summer. In a previous post, I surmised that most front-end developers code for Firefox first, then put off their Safari/Explorer testing till the end. Maybe if IE tooling continues to mature, we'll see less of that.
An Event Apart Chicago: Day 2
Tuesday saw the conclusion of An Event Apart Chicago 2007, the two-day web-development conference from the folks at A List Apart. Here's my sequel to yesterday's day-one overview. I'll be back Friday with analysis and afterthoughts.
Jeremy Keith, author of "Bulletproof Ajax" and "DOM Scripting," led the day. His topic? "Be Pure. Be Vigilant. Behave," wherein he outlined the concepts behind "Hijax," the application of progressive enhancement to Ajax functionality. A staunch proponent of unobtrusive JavaScript, Keith warned against throwing web standards out the door when developing Ajax functionality. His examples demonstrated how to separate behavior from content and presentation by abandoning such outmoded techniques as the
Next up was Luke Wroblewski, a Yahoo product designer whose resume includes work on the original Mosaic web browser. Wroblewski covered "Best Practices for Form Design" using exhaustive research from his forthcoming book on the subject. In case study after case study, he demonstrated how simple choices in the design and deployment of HTML forms - from the widths and alignment of inputs and labels to the placement and visual differentiation of cancel and submit buttons - can cut the time it takes to complete them in half. Wroblewski's most persuasive argument, however, was conceptual rather than technical. He made a powerful case that because forms are barriers between users and the things they want to do - buy your product, join your site or begin creating content - you should make them as easy to get through as possible. This central thesis added considerable weight to his many practical how-tos.
Accessibility advocate Derek Featherstone closed off the morning with "Accessibility: Lost in Translation." Featherstone looked at how markup choices can make a site transparent to assistive devices - or render it totally opaque. Using real-world examples from Amazon and other sites, he demonstrated how screen-reading software actually parses markup. His live examples proved that the lack of semantic markup and the absence of ostensibly optional HTML attributes can render a site worthless for disabled users. Featherstone then went beyond the basics, explaining how source order - the sequence in which nodes appear in your markup - can be used to enhance accessibility. By placing your central content first, then positioning chrome above it with CSS and providing jump navigation to skip past inessential modules, you can achieve the presentation you want for typical users without shortchanging disabled ones. In another example, Featherstone examined the ways in which meaning can be encoded in the color and position of elements on the page - and how to replicate that meta-data in a way that disabled users can understand. As with many of the other speakers, Featherstone's examples argued persuasively for the continuing relevance of web standards.
After lunch, CSS expert Eric Meyer again took the stage, this time to explore "The State of CSS in an IE7 World." Using the recent release of Microsoft Internet Explorer 7 as a springboard, Meyer illustrated the concepts that have governed the changing of the browser guard for more than a decade. His overall premise was that developers need to use their own server logs to gauge when support for an older browser can safely be dropped for their site. For most of us, IE6 isn't going away anytime soon, so we need to get creative if we want to harness advanced functionality. To that end, Meyer delved deeply into the details of IE7 techniques, filters and hacks. He praised the browser for the strides it makes over IE6's CSS engine in such areas as child selectors, adjacent sibling selectors and attribute selectors. His real-world examples demonstrated how such functionality adds power and elegance to our code. To cope with IE6's continuing market share, Meyer advocated the use of Dean Edwards's IE7 compatibility script, a JavaScript library that adds IE7 capabilities to older versions of the browser. The take-home message was that older browsers may take a long time to die out, but creative programming techniques can harness the future of CSS now.
The final two sessions for AEA Chicago 2007 were a little offbeat, which was a relief after 10 technical sessions in the previous 32 hours. In the highly anecdotal "Selling Design," ALA publisher Jeffrey Zeldman used stories from his own long career to illustrate best practices for handling difficult clients. His thesis was that collaborative work requires us to deal with a wide range of other people, so we should hone our ability to influence our collaborators - and pick good clients to begin with. Agency owner Jim Coudal closed things off wittily with "Dealing With the Both of You," a slide-free presentation about the crossover between personal projects and professional work-for-hire. Coudal assembled a number of satirical short films to drive home his point: Because most web developers are curious and easily bored, we should strive to marry passion with professionalism whether our clients are external or ourselves.
Ajaxpect: AOP for Javascript
I was looking for a quick way to profile some code in IE. I didn't want to grab Tito (commercial) or JsLex (browser independent, sweet, but a bit of a hog). So I went hunting for a simple little AOP library for Javascript and came across Ajaxpect. In 58 lines of Javascript, it gives you the ability to add before, after and around advice. From the included example:
// Example business logic var thing = { makeGreeting: function(text) { return 'Hello ' + text + '!'; } }alert(thing.makeGreeting('world')); // Hello world!
// Advice definitions function aopizeAdvice(args) { args[0] = 'AOP ' + args[0]; return args; } function shoutAdvice(result) { return result.toUpperCase(); } function ciaoAdvice() { return 'Bye-bye!'; }
// Adding advices Ajaxpect.addBefore(thing, 'makeGreeting', aopizeAdvice); alert(thing.makeGreeting('world')); // Hello AOP world! Ajaxpect.addAfter(thing, /make*/, shoutAdvice); alert(thing.makeGreeting('world')); // HELLO AOP WORLD! var filter = function(name) { return name.indexOf('Greet') != -1 } Ajaxpect.addAround(thing, filter, ciaoAdvice); alert(thing.makeGreeting('world')); // Bye-bye!
Technorati Tags: ajax, aop, profiling
Topics: IE, Performance
Whither Canvas?
This world is but canvas to our imaginations. -- Henry David Thoreau
First support for the WhatWG canvas element was announced by Apple in Safari, then it was included in Opera and Firefox. A little while back, Emil did a cool hack with VML to produce a subset of functionality as canvas for IE. There was a rumor that google would release this or some other code as its Canvas for IE solution, and it sort of has, landing with a thud over at sourceforge with a Google Code imprimature.
There have been no apparent developments since then. It doesn't seem to have been widely tested, is much slower than canvas in Firefox, and has enough differences and functional gaps to make integrating it with Javascript libraries that build on the canvas tag somewhat difficult.
There don't appear to be any plans to support canvas in IE7, but things can change quickly over there, apparently. So, do you support canvas in IE with an impressive piece of late night hackery like Emil's work, or is support for canvas just not there yet -- a really nice feature not supported effectively for 90% of the web browsing public?
I'm leaning toward the latter. What do you think?
About Pathfinder
Recent
- Bandwidth profiling Flex projects and more with Charles
- iPhone SDK: UIViewController Testing & TDD
- Icons are evil; so are menus - unless you do them right
- The Truth About Designing For Security
- GWT, Gadgets and OpenSocial, Part 2
- Has Many has_many: A Refactoring Story
- The Hidden Power of Canvas
- Review of fixture_replacement2 plugin
- Chess Game Viewer in GWT
- From JSP to Ruby on Rails: First thoughts on front-end coding conventions
Archives
- November 2008
- October 2008
- September 2008
- August 2008
- July 2008
- June 2008
- May 2008
- April 2008
- March 2008
- February 2008
- January 2008
- December 2007
- November 2007
- October 2007
- September 2007
- August 2007
- July 2007
- June 2007
- May 2007
- April 2007
- March 2007
- February 2007
- January 2007
- December 2006
- November 2006
- October 2006
- September 2006
- August 2006
- July 2006
- June 2006
- May 2006
- April 2006
- March 2006


