Friday, February 5, 2010

Re-Recreating the Button

This post owes its inspiration to Doug Bowman's excellent post from about 1 year ago, titled Recreating the Button.

What's changed since Doug's post?

  • -webkit-gradient and -moz-gradient(>= FF3.6) support for backgrounds. (IE has had the Gradient filter since 5.5)
  • -webkit-border-radius and -moz-border-radius work pretty much flawlessly, and degrading to square corners is currently in vogue.
  • I've seen several projects implement this div/span button implementation when a native control would be much more appropriate.

So using the spec that Doug and others came up with, I wanted to see how close I could get to it using un-nested anchors, spans, and divs, but much more notably - native inputs and buttons. JavaScript buttons are fine, but native buttons can degrade. There's few things as horrible as clicking a form submit button and having nothing happen due to a JavaScript error. The implementation has not been all that easy in the end. Many times I've thought I had it only to be thwarted seeing the result in some other browser and going back to the drawing board. For now I've got a CSS file and a unit test page which represents what I'd like to achieve and how close (and sometimes how far!) I am to getting there.

I'll continue to update the test page as I hear from folks about what is and isn't breaking, but in the meantime, I'm happy to report that the test is passing on all A-grade browsers (with the exception of Safari on Mac - hopefully some nice Mac folks can clue me in on what to change to get it working I am not sure about Mac, but Safari 4.04 on Windows passes all the tests now).

The test page shows off something I've found really helpful as a UI developer: unit testing of computed styles in different browsers (in this case, making use of closure-library's goog.testing.jsunit module). Having a page like this makes it much easier to discuss and document anomalies and provides a lot more assurance when making adjustments. We all tend to test our work in one browser and then go through the process of making tweaks for others, but it's crucial to be sure that a change for one doesn't botch something in another. Specifically, this page documents a few use cases that I didn't originally set out to solve, but which now seem like big wins - namely, the icon-buttons as well as the buttons in fixed width containers. Of course there's no way to unit test for everything. Many of the browser-specific tweaks to the padding are specifically for visual consistency inside the button, so testing the padding would be a joke. To that end, I have to plug the free Adobe BrowserLab, which I used constantly while developing this code.

This is still something of a work-in-progress, but you can look forward to seeing these buttons, and some correspondingly styled select elements, in the next App Engine Admin Console release and ultimately the closure-library.

No comments: