On the surface, attribute selectors seem so very cool. Instead of having to
explicitly define classes, or other selectors, we can use the attributes of
the elements directly to style them. In my experience, by far the most
common use of attribute selectors is in styling INPUT elements.
INPUT is one of the most overloaded elements in HTML, just think about how
different INPUT elements are for the different types: checkbox, radio,
text & file. It’s worse than that though, because as well as having all
those different elements, it also has a bunch of types for which the
rendering is (mostly) the same, eg. the following are all rendered as
buttons: button, input, & reset. HTML5 brings a whole bunch of new
problems into the mix, in HTML4 only text and password types were
rendered as single row text fields, but with HTML5 this will expand
dramatically, conservatively the following are likely to become common:
email, search, number, tel & url.
Add to all of that the problem that IE6 never supported attribute selectors,
and IE7 and above required the DOCTYPE setting to switch IE into standard
mode.
There’s a bucket load of CSS like this which is very soon going to be out of
date:
input[type=text], input[type=password] {
// some style
}
So, what to do?
Well, if we still care about IE6 (which those of us producing software for
money often have to) we need real classes, but wouldn’t it be nice if we
could continue to rely on the attributes?
Javascript to the rescue
I use jQuery, but the same process can be done using
any framework, or in raw JS. What we’re going to do is add classes to all
our input elements, to make styling simpler:
function add_input_classes() {
$('input').each( function(i) {
var type = $(this).attr('type');
switch( type ) {
case 'button':
case 'reset':
case 'submit':
$(this).addClass('button');
case 'checkbox':
case 'radio':
case 'file':
case 'hidden':
case 'image':
$(this).addClass(type);
return;
}
$(this).addClass('text').addClass(type);
});
}
$(function() {
add_input_classes();
}
So, we add the type of each input element as a class, so <input type="radio"> will have ‘radio’ added as a class. Additionally, we add ‘button’ to all the button types. We also add ‘text’ to any type not in the switch list, ie. we assume that anything not listed is a text field. This will soon not be reliable, if you’re using other HTML5 types like the date-pickers, or the color wheel, then you’ll need to add those to the switch statement.
So then our CSS becomes nice and clear:
input.text, textarea {
border: thin solid grey;
}
input.button {
background-color: gray;
color: black;
}
Then also, if we need to, we can style any individual attribute using the type as the class.
What else?
This same process can be expanded to work for all other attribute selectors as well. Javascript is much more powerful than CSS selectors, and by pushing this class assignment off into JS you’re left with much neater and more robust HTML and CSS.