Styling XUL Buttons

I’ve spent a lot of time over the past few days working on enhancing a grid-type element in some test code for a XUL application my company’s building. XUL has a native grid element, but it’s for positioning rather than for editing. What we’re after is an editable, dynamic data-driven grid containing multiple types of elements (list boxes, checkboxes, textboxes, some editable, some not, etc.). A native grid of the sort (or at least vaguely like the sort) is referenced in a wiki entry by XUL expert Neil Deakin. Such a grid is useful for things like adding line items to quotes and orders, where text entry fields are necessary for entering numbers, but select boxes and other form controls are useful for entering validated data (categories, for example). But the building of such an element is pretty far off. So we had to roll our own.

Complicating things is the fact that we’re retrieving data from a remote data source. After some testing, we determined that retrieving an XML file generated on the fly and converting it to an in-memory RDF was more bandwidth-efficient than retrieving the RDF itself. In some of our testing, the retrieval, conversion, and rendering of grid elements using the XML file took substantially less time than just the retrieval of the remote RDF. But it was still slow in some cases. In one test, we built an order containing eight or ten columns and about 50 rows. Each field was a text box. It took something like 10 or 15 seconds to render all the elements. Apparently, text boxes are pretty hefty. So we tried using labels instead. Much faster, but not editable. Ah, but there’s a way around that: Just write some javascript that, on focus or click, converts a label into another form control. This worked great, except that labels can’t receive focus, which eliminates the necessary ability to tab through the grid. (I was able to apply the -moz-user-focus style attribute to a label to get around this, but in additional testing, I determined that the remedy I’ll discuss in a moment was at least as good an option.) After discovering the problems with text boxes and labels, the coworker who had put together the base code for the grid had tried using buttons instead. Oddly enough, buttons load much faster than text boxes and not noticeably slower than labels. And you can do more with them (a good reason to use them over labels). But they look like, well, buttons.

Surely, I thought, there’s a way to modify the style on XUL buttons. I tried and tried to no avail. I could set a background color, but it would appear behind the gray button rather than replacing the color of the button. Border and background image changes were also applied to the space around the button rather than to the button itself. I unzipped the classic theme jar file and dug into the skin’s styles to see if I could learn anything about how the buttons were styled, but I initially found nothing useful. I copied the button CSS selector into my local CSS file and screwed with it with little success. Finally, after a day of looking into java as an alternative and some time investigating the prospect of writing our own widgets using XBL (which is really cool, by the way, if not any more efficient for our specific purposes in this case — for example, I wrote a widget that contained a deck that contained a label that turned into a textbox on click or focus, but loading this in the grid essentially loaded a textbox and a label and a deck and so was even slower to load than just textboxes), I took a closer look at the style attributes for buttons.

It turns out that the “-moz-appearance” property was what had done me in. I had simply overlooked it. This attribute dictates that the given element should take its appearance from the native system’s version of the element. So try as I might, if this property was set, I couldn’t override the appearance. The solution? Just add “-moz-appearance: none;” to your style sheet for this element (or a class instances of it can use). Once I cleared this hurdle, I was able to build something that looked very much like an Excel grid that loaded pretty quickly but was editable. Click a field and it turns into a textbox whose style matches the style of the button (so you don’t see a change in appearance) so that the value can be edited. All the functionality of textboxes without the crippling rendering time.

6 thoughts on “Styling XUL Buttons

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s