XUL has a checkbox widget, which you are expected to use like this:
<checkbox label="Account Locked" />
That will give you a perfectly functional checkbox with a label to the right of it (add dir=”rtl” if you want the label to the left of the checkbox). The image below shows how they appear on my Linux machine – the top part is an unselected checkbox, whereas the lower one has been clicked on, which has the effect of both checking the checkbox and focussing the widget:
It’s the focussing that’s the important bit here – notice how the label gets surrounded by a dotted border. A similar effect is used on a Windows machine, and is generally “a good thing” as it makes it clear which widget will be affected by keyboard presses (such as using the space bar to toggle the checkbox state).
Sometimes, however, the presence of this focus border is not “a good thing”, and can in fact become “a confusing thing”. Consider a user interface which has labels and widgets all neatly aligned using a XUL grid. In that case you might not want to have a label directly on the checkbox element at all, in which case you can find that a focussed checkbox takes on a most disconcerting appearance:
The focus border is still being drawn around the non-existent label text. In this case it’s made worse by the checkbox being the second item in the row of a XUL grid with two columns. Because the field in the row below is much wider than the checkbox, the non-existent label flexes to fill the space, making an already odd looking widget seem even weirder. Incidentally, the field below is an XBL widget of my own devising, which is why it doesn’t look like a normal XUL textbox.
Putting the checkbox inside a XUL hbox element has the effect of curtailing its flexing habits, so that the focus border, while still present, is a little less offensive:
But wouldn’t it be better to get rid of the focus border altogether? A little digging with the DOM inspector revealed that the checkbox label is being targetted with the following CSS selectors – the first on my Linux installation, and the second on Windows XP:
checkbox:focus > .checkbox-label-center-box > .checkbox-label-box
checkbox:focus > .checkbox-label-box
It’s possible to hit both of these by losing the immediate child selector (the “>”) and the “checkbox-label-center-box” class, so that the rule matches any descendent of a focussed checkbox which has a class of “checkbox-label-box”. A blunt approach would be to just disable the focus border altogether, by adding this to your CSS file:
checkbox:focus .checkbox-label-box
{
-moz-appearance: none;
border: none;
}
That does disable the focus border, but it disables it completely – even if the checkbox is used in a situation where it does have a label. Thankfully Firefox’s CSS engine is rich enough to let us use the [label] selector, to match elements which have the “label” attribute, as well as the :not() pseudo-class to negate the match. The result is this chunk of CSS, which will disable the focus border on checkboxes which don’t have a “label” attribute, but leave it untouched on those that do:
checkbox:focus:not([label]) .checkbox-label-box
{
-moz-appearance: none;
border: none;
}
Of course the proof of the pudding is in the slightly doctored screenshot (only doctored in that I pasted two together). In this you can see that the top row contains a checkbox with no label, and no focus border, and the bottom row contains a checkbox with a label which gets the default focus border that we all know and tolerate:
Thank you for this post.
I was just starting to do research on this same issue. Your article was the third one I found. Straightforward and concise. Thank you.
You’re more patient than me – I’d have given up searching after the first two articles 😉
Glad it helped.