Adding classes to input tags as a matter of course

I felt like sharing a practice that I've been doing for a while now when marking up form elements.

I always assign a class to every input that is the same to the input's type.

<input
  type="text"
  class="text" />

<input
  type="checkbox"
  class="checkbox" />

<input
  type="radio"
  class="radio" />

<input
  type="button"
  class="button" />

For input types that would be similar in presentation, I double up:

<input
  type="submit"
  class="submit button" />

<input
  type="password"
  class="password text" />

It's not uncommon for a project to require specified padding, width, and border colors for text inputs. I don't want to target all input tags, as it could have some unintended consequences for elements I don't want changed. So this practice has helped me greatly. Its html file size impact is miniscule, and it's also easy to remember, since the type value is always the class value.

Attribute selectors vs. class names

Attribute selectors almost remove the need for me to do this, but not quite. By attribute selectors, I mean the following:

input[type="text"] { border:1px solid #000; }

... in which the value of the 'type' attribute is used instead of a class or id.

The main reason attribute selectors don't do the trick is that IE6 doesn't support them. And though I can be persuaded to let a little IE6 wonkiness slip through for some parts of web site projects, forms are where I draw the line. After all, forms are how get feedback and money from customers - why screw with that?

The secondary reason can be found from the password input example above. I want password inputs to inherit the same presentational treatment as text inputs. Using the class names defined above lets me do that.

For me, this practice has proven pretty effective. Your mileage may vary, but I'd love to hear any other tips you have in mind.

See also:

Kotatsu - a simple html table generator

It's been a long time since I've used Dreamweaver for web development. I only find myself missing it when I need to create a table, especially when I want to have all cells in a particular column have a class. (I'm well aware of <colgroup>, I just don't subscribe.)

So I created a tool to help create a table and throw in column classes quickly. I gave it a name so I can put it out there and let others use it, too.

It's called kotatsu.

Prasun asks the CSS Guy how to switch the "on" state of navigation links for dynamic pages

Prasun writes:

I have a list of links in an unordered list. What I want is that when I click a list item, its color should change, and when I click some other list item, the color of the item which I clicked previously should return to its original state.

Can you help me in this regard?

Yes, I can help.

More advanced readers, move along. This is JavaScript beginner territory, but this is one of those steps that is really rich in DOM scripting nutrients, so I'm very pleased to discuss it.

What Prasun is describing, just by itself, is the behavior of a set of radio buttons. You click one, and it takes on the selected state. Then you click on another one, and the new one now becomes selected, while the previous one returns to an unselected state.

But radio buttons are form elements, not navigational elements, and upon clarifying with Prasun, it's navigation that we're after.

This is the fundamental behavior of a site that uses ajax for navigation or tabs, where each "page" is created by loading new content into the content section of the current page.

This is a relatively easy way to get your feet wet with DOM scripting. So I'll first show how to do it with some very basic JavaScript functions. Also, I'll show how to do it with jQuery.

First, the HTML

Let's start with an unordered list of links.

<ul>
  <li><a href="#">Heartbreak Hotel</a></li>
  <li><a href="#">Blue Suede Shoes</a></li>
  <li><a href="#">Hound Dog</a></li>
  <li><a href="#">Don't Be Cruel</a></li>
  <li><a href="#">Teddy Bear</a></li>
</ul>

See example 1.

Who are we kidding? Let's see it with some basic styling - example 2.

Since we're going to be changing around selected links, let's establish what a selected state looks like, and mark one item as selected by default. I'm going to do this by applying class="selected" to one of the links.

<ul>
  <li><a href="#">Heartbreak Hotel</a></li>
  <li><a href="#">Blue Suede Shoes</a></li>
  <li><a href="#" class="selected">Hound Dog</a></li>
  <li><a href="#">Don't Be Cruel</a></li>
  <li><a href="#">Teddy Bear</a></li>
</ul>

See example 3.

The JavaScript

Here's what we want to do in English. When someone clicks a link, remove class="selected" from any of the other links, and assign it to this one.

Another way to say that is "When someone clicks a link, run a function" and later I can be more specific about what that function is. Here's how I'll put that statement in the html.

<ul>
  <li><a onclick="applySelectedTo(this);" href="#">Heartbreak Hotel</a></li>
  <li><a onclick="applySelectedTo(this);" href="#">Blue Suede Shoes</a></li>
  <li><a onclick="applySelectedTo(this);" href="#" class="selected">Hound Dog</a></li>
  <li><a onclick="applySelectedTo(this);" href="#">Don't Be Cruel</a></li>
  <li><a onclick="applySelectedTo(this);" href="#">Teddy Bear</a></li>
</ul>

The "this" mentioned in the parentheses refers to the link that is being clicked. I'm thinking ahead here - I know that I'll want to do something with the link being clicked (assign it class="selected"), so I'm going to go ahead and pass that link as a parameter to the function. The term this is great for that sort of thing.

The function will be called "applySelectedTo()", and I'll write it in just a second. It's going to do exactly what it says it will do: Apply class="selected" to whatever link is given to it. It will also live in head of the document.

Notice that in the html, I'm passing the parameter this. And when I write the function, I'm using a made up term to help tell me what this was - the word link.

<script type="text/javascript">
function applySelectedTo(link) {
  link.className = "selected";
}
</script>

Check out Example 4 to see it in action.

Oh, but we're not done

All that JavaScript function did was add class="selected" to the new link. It didn't remove class="selected" from previously selected links. We need to fix that. Also, when we click a link, it adds the hash mark (#) to our url, and if our page were really long, it would jump to the top of the page again.

We'll tackle the second problem first. That hash mark is telling me something: it's indicating that the link is behaving like a link is supposed to behave. That behavior normally means that it will find the id of whatever I specified after the hash mark and the browser will bring that part of the page in focus. But in this case, we would rather ignore the default behavior of the link, so I'm going to tell my links to ignore their default behavior when clicked.

<ul>
  <li><a onclick="applySelectedTo(this);return false;" href="#">Heartbreak Hotel</a></li>
  <li><a onclick="applySelectedTo(this);return false;" href="#">Blue Suede Shoes</a></li>
  <li><a onclick="applySelectedTo(this);return false;" href="#" class="selected">Hound Dog</a></li>
  <li><a onclick="applySelectedTo(this);return false;" href="#">Don't Be Cruel</a></li>
  <li><a onclick="applySelectedTo(this);return false;" href="#">Teddy Bear</a></li>
</ul>

Example 5

And back to the first problem - removing class="selected" from other links when a new link is selected. How do we get the link that already has class="selected", and remove the class? Well, to make it easy, I'm just going to say remove class="selected" from all links, then I'll add class="selected" to the one just clicked.

<script type="text/javascript">
function applySelectedTo(link) {
  var ul = document.getElementsByTagName("ul")[0];
  var allLinks = ul.getElementsByTagName("a");
  for (var i=0; i<allLinks.length; i++) { 
    allLinks[i].className = ""; 
  }
  link.className = "selected"; 
}
</script>

And so there you have it, Example 6 - final example.

And if you're so inclined, make it do something.

We could go much further

Ideally, you wouldn't even have an onclick attribute in the markup. That kind of thing can be inserted dynamically using more DOM scripting. It makes your html lots more readable and reusable, as well as separating behavior from structure.

Also, for kicks, here's one final example of doing the things mentioned in this article, but using the jQuery library instead of self-written scripts. In the instance that you are already pulling in a hefty JavaScirpt library into your web site, you might as well make use of it.