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:


This post was ported from an old host and CMS, so many comments were lost. Below are the comments that I found were most helpful regarding this post that I salvaged. Some links or attributions may not be working correctly.


Ace Calhoon said:
I’ve not used attribute selectors much for essentially the reason you list as primary above (no IE6 support, and a lot of people use that browser). But your secondary reason seems a bit odd.
Couldn’t you write the selector as:
input[type=”text”], input[type=”password”] { /* shared CSS */}
input[type=”password”] { /* password specific CSS */ }
?

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.


This post was ported from an old host and CMS, so many comments were lost. Below are the comments that I found were most helpful regarding this post that I salvaged. Some links or attributions may not be working correctly.


Chris Heilmann said:
Nice, but these are not tables. Tables are data constructs and need a summary, a caption and TH elements with scope attributes to be accessible and useful. All of these are also splendid hooks for styling which I’ve proven with the CSS table gallery: http://icant.co.uk/csstablegallery/

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.

Can deprecated tags become undeprecated?

When certain tags become deprecated, they become so because they are replaced by more favorable ways of achieving their original purpose. (In the case of <blink>, being annoying helped it along the path of deprecation.) But there’s one tag that may be coming back to life.

The value of <u>

The <u>, whose sole purpose was to underline inline text, was deprecated in HTML 4.01, and was destined to remain unsupported in future versions of HTML. However, arguments have recently been made to revive it in HTML 5, warning that <u> has a specific value that no other tag has, and that we never should’ve given <u> up. Watch Tim Berners-Lee defend this proposition to the World Wide Web Consortium in a heated March 2008 discussion.

One pixel notched corners as used by Google Analytics

I use Google Analytics, and I noticed that their left nav has an interesting characteristic: instead of each option being boxed in a clickable rectangle, there is a one pixel notch in each corner. It’s not necessarily a curved corner, but it is a little softer than a normal box.

Google Analytics Nav uses has a one pixel notch in each corner.

I would’ve naturally thought that if someone is going to use background images to create a capsule effect, they would have used anti-aliased images. But upon closer inspection, no background images were used at all. Instead, a couple of nested tags within the link help create the effect. Instead of this:

<ul>
  <li>
    <a href="/">
      Visitors
    </a>
  </li>
</ul>

Some <b> tags are added (likely chosen because because of their length – one letter):

<ul>
  <li>
    <a href="/">
      <b>
        <b>
          <b> 
            Visitors
          </b>
        </b>
      </b> 
    </a>
  </li>
</ul>

Now whether or not this is the purest thing to do is not the subject of this article. Obviously, I don’t support overnesting of tags. But the Analytics designers did this for a specific design purpose. Nesting one tag is quite common for achieving sliding-doors rounded tabs. Perhaps the reasoning was, ‘Why not nest two more and drop the use of images?’

Also, similar techniques exist out there to get rounded borders with a greater radius than just one pixel. However, those techniques involve much more extra markup (or javascript to create it for them) in the form of empty tags, where success comes in the form of a pixelated curve reminiscent of an 8-bit Nintendo display. (I exaggerate, but still.) In the case of a one pixel notch, the effect at least looks intentional.

The notched corner is created by modifying the nested tags’ border and position properties.

Here’s the CSS:

li a {
  display:block; /* a must */ 
  border: solid #666;
  border-width: 0 1px; /* left and right borders only */ 
  text-decoration: none;
  outline:none; /* so as not to distract from the effect */ 
  color: #000;
  background: #e4e4e4;
}
li a b {
  display: block; /* another must */ 
  position:relative; /* because the child elements are positioned */ 
  top: -1px; /* drag it up a little, creates the top notches */ 
  left: 0;
  border:solid #666;
  border-width:1px 0 0; /* top border only */ 
  font-weight:normal;
}
li a b b {
  border-width:0 0 1px; /* bottom border only */ 
  top: 2px; /* pushed down a little to create the bottom notches */ 
}
li a b b b { /* i don't think three-deep tag is even necessary */ 
  top:-1px;
  padding: 1px 6px;
  border-width: 0;
}

To just get the notch, the third-deep <b> tag isn’t needed. I think Google Analytics included it because they wanted to add some background images with it on their buttons. I think this effect can be achieved with one less nested <b>.

<ul>
  <li>
    <a href="/">
      <b>
        <b> 
          Visitors
        </b>
      </b> 
    </a>
  </li>
</ul>

In my example page, I left it at two deep.


This post was ported from an old host and CMS, so many comments were lost. Below are the comments that I found were most helpful regarding this post that I salvaged. Some links or attributions may not be working correctly.


Simon Käser said:
Nice technique there. But I don’t see the need for more than one nested tag. One nested span tag is enough if you use negative margins rather than top and bottom.

New CSS Off Contest April 5

I’m excited about the upcoming CSS Off contest, even though I won’t be judging this time around. Brad Colbow is the guest designer. I’ve seen a sneak peak of the design, and it looks like it will be a fun challenge. If you want to exercise your markup skills, get feedback on your approach, and possibly win a little something for your favorite charity, consider giving it a go on April 5 (Saturday).

It’s free and open to everyone of any skill level.

Update (23 Mar 2008): I updated the title with the correct date, April 5.

I’m redoing previous articles to use jQuery, you know, just for fun

I like using the jQuery library so much, I started converting my old article examples to use it. I thought it would be interesting to see how much less scripting I would have to write. (A little less, but not much – my examples were never heavy on the scripting anyway). I think it made some more readable, too, in that I can glance at the script code and tell what’s going on.

Here’s a list of what I have converted so far, with a downloadable zip.

The obligatory disclaimer – using any library’s methods is no substitute for learning JavaScript basics. If you haven’t already added JavaScript to your list of things to learn as a web designer, stop mucking around and pick up Jeremy Keith’s DOM Scripting.

For a seasoned html/css person, learning jQuery is arguably much easier than learning JavaScript from scratch, since its selector syntax is based on CSS selectors. Since I’m the CSS Guy, it is my library of choice, but only when a library is needed. Some pages require so little DOM manipulation that self-written functions easily fit the bill, as well as saving some downloaded bits.

On a related note, someone turned my favicon article example into a jQuery plugin.

Pushing a shopping cart full of tea with CSS and JavaScript

While brainstorming for a recent project, I toyed with the idea of having a shopping cart that follows the user on a scrolling page. The idea was partly inspired by Derek Allard’s entry, “Conditionally Sticky Sidebar“.

The idea would be that the cart would only start following the scrolling page if it had a product in it; an empty cart would not. I ended up not using the feature for a variety fo reasons, but I thought I could still share the logic behind the effect.

For those who like to skip ahead: view the final example or download a zip with all the html, CSS, JavaScript, and supporting images.

First, a storefront

To start off, here’s example 1 – a very basic storefront. In this example, our storefront sells tea. The shopping cart, pictured with some items inside, is on the right. The shopping cart is 200 pixels wide, and I’ve reserved the right-side 200 pixels all the way down the page to serve as the shopping cart ‘aisle’.

HTML

<div id="shoppingCartAisle">
  <div id="shoppingCart">
    <h3>Shopping Cart</h3>
    <ul>
      <li>product 1</>
      <li>product 2</>
      <li>product 3</>
    </ul>
  </div>
</div>

CSS

...
#shoppingCartAisle {
  width:200px;
  float:left;
}
#shoppingCartAisle #shoppingCart {
  width:200px;
  position:absolute;
  top:0;
  background:transparent url(images/bottom.gif) no-repeat bottom left;
}
#shoppingCartAisle #shoppingCart h3 	{
  background:transparent url(images/top.gif) no-repeat top left;
  margin-top:0;
  padding:4px;
 }
...

Notice that I have a ‘shoppingCartAisle’, which is the container for the ‘shoppingCart’ div. #shoppingCartAisle is set to position relative, and #shoppingCart is absolutely positioned to stick to the top of #shoppingCartAisle. (I’m using absolute positioning because I’m setting up what is to come.)

Using position:fixed

To illustrate the cart running up and down the page, I’ve created example 2, which has #shoppingCart using position:fixed; instead of position:absolute;. As the user scrolls, the shoppingCart follows the browser. Unfortunately, it overlaps the header area as well. I’d rather my cart stay in the aisle.

Deciding how to do this

This is where Derek Allard’s article proved to be of great reference. I varied from his approach in two ways:

  1. My cart does not hug the side of the browser, but instead stays within the right column of a fixed-width layout.
  2. I planned for the distance from the top of the browser to the cart to vary based on promotional messages or whatnot that may/may not line the top of the page, so it was important for the cart to be positioned absolute to the aisle, not the browser window.

It’s helpful for me to state what I want to happen in English before writing the JavaScript. When the browser scrolls, determine if it has scrolled down past where the ‘shoppingCartAisle’ begins. If so, change the ‘shoppingCart’ to position:fixed so that it follows the user down the page. If the browser scrolls back up to where ‘shoppingCartAisle’ starts, then switch ‘shoppingCart’ back to position:absolute so that it doesn’t go into the header space of the page.

The fun part – JavaScript

To determine where the shoppingCartAisle begins, I have a function called establishTopPosition(), which is the first of two functions you see below. The second function, pushMyCart(), does what the above paragraph describes in English. For the parts that look weird, just know that Derek Allard figured that stuff out for me.

<script type="text/javascript">
function establishTopPosition() {
  var shoppingCartAisle = document.getElementById('shoppingCartAisle');
  var y = 0;
  while (shoppingCartAisle!=null) {
    y += shoppingCartAisle.offsetTop
    shoppingCartAisle = shoppingCartAisle.offsetParent;
  }
    return y;
}
function pushMyCart() {
  var shoppingCart = document.getElementById('shoppingCart');
  var topPos = establishTopPosition();
  if( window.XMLHttpRequest ) { // IE 6 hates position fixed
    if (document.documentElement.scrollTop > topPos  || self.pageYOffset > topPos) {
      shoppingCart.style.position = 'fixed';
    } else {
      shoppingCart.style.position = 'absolute';
    }
  }
}
</script>

And I want JavaScript to pushMyCart() when the page is scrolling, so add this to the onscroll event of the body:

<body onscroll="pushMyCart();">

See example 3 where JavaScript is pushing my cart.

Let’s enhance it some more

I only want a rolling shopping cart if there are products in the cart. If it’s empty, I just want it to stay put.

To do this, I’m going to add a class to the shopping cart called ‘rollingCart’ when a product is added. Then I will tweak my JavaScript to only roll the cart if it has a class of ‘rollingCart’.

I also need a way to clear out the items from my cart, so I’ve provided a link, ‘Empty Cart’, than when clicked, removes the class of ‘rollingCart’ from the shopping cart.

Once again, I’m relying on the great work of others to accomplish this, namely Robert Nyman, who wrote the very helpful functions getElementsByClassName, addClassName, and removeClassName, and also one Simon Willison, who wrote the addLoadEvent function. (Yes, I know there are libraries that can do this, but this assumes there are none being used.)

Here are the functions I wrote to accomplish my new task. The first one sets up the ‘add to cart’ links so that once clicked, they give a ‘rollingCart’ class to the cart, then tell the browser to push my cart. The second function sets up the ‘clear cart’ link, so that once clicked, it removes the ‘rollingCart’ class, then tells the browser to parkMyCart(). parkMyCart() attaches the cart to the top of the shoppingCartAisle element again.

function addToCartLinks() {
  var links = getElementsByClassName('addToCart','a',document);
  var cart = document.getElementById('shoppingCart');
  for (var i=0; i<links.length; i++) {
    links[i].onclick = function() {
      addClassName(cart,'rollingCart');
      pushMyCart();
      return false;
    }
  }
}
 
function clearCart() {
  var dumpit = document.getElementById('clearCart');
  var cart = document.getElementById('shoppingCart');
  dumpit.onclick = function() {
    removeClassName(cart,'rollingCart');
    parkMyCart();
    return false;
  }
}
 
function parkMyCart() {
  var cart = document.getElementById('shoppingCart');
  cart.style.position = 'absolute';
}

See it in action with example 4 – remember to ‘add to cart’ and ‘clear cart’ to see the effect. Feel free to download the zip as well.

Note that I kept these functions simple for the sake of demonstration – no products are added or removed from the cart when links are clicked; just the class name changes. Also, this doesn’t work in IE6, and the JavaScript allows IE6 to ‘gracefully degrade’ by always having a positioned absolute cart.

I hope you find the post helpful. I am no JavaScript genius, so if you see anything that could make this better, please leave a comment.

Why tea?

This post is so themed to raise awareness for Ron Paul in honor of this weekend’s fundraiser event, which purposefully coincides with the anniversary of the Boston Tea Party. If you don’t know who Ron Paul is, I encourage you to google him or search YouTube for supporter-made videos. Or start with these: one, two, three. Thanks.


This post was ported from an old host and CMS, so many comments were lost. Below are the comments that I found were most helpful regarding this post that I salvaged. Some links or attributions may not be working correctly.


Jennifer C. said:
At first I thought it wasn’t working, but then I actually read the article and noted that it works only after adding an item to the cart, clicking the add links. I too am using Firefox 2.0.0.11 on XP Pro.
Try adding an item, then scroll down. Then, clear cart – poof, the cart will revert to the top of the screen.
Now, you could get really wild and crazy and add some mootools transforms for a visual frenzy!

Mike asks the CSS Guy for recommendations on rounded corners

Mike writes:

I have a request: could you PLEASE tackle the rounded corner issue? I seem to get a request all the time to add some rounded corners to
sites and I have looked at at least a dozen different solutions and
was never happy. What do you recommend? How do you create rounded
corners?

Let’s cut to the chase – I have no new or special method for rounded corners. Also, there is no one way that I can recommend, as some methods are better suited than others based on context and need. I have no intention of doing a rundown of every method, but I’d still be happy to share how I’ve created rounded corners in the past.

Simplest way I know

I’ve been fortunate enough to work on projects that have only required rounded corners on elements with a fixed width and a solid color (no gradients). That makes it pretty easy for me – I just use a giant gif.

Gif’s are relatively light-weight, even big ones if it’s a solid color. For this example, I’ll create one at a fixed width of 380px, and make it long – 780px. See example.

Then I’ll markup my box.

<div class="roundBox">
  <p>beautifully-encapsulated paragraph</p>
</div>

And give it the background.

.roundBox {
  background:transparent url(roundBox.gif) no-repeat top left;
  width:340px;
  padding:20px;
}

Note that the width of my box is set to 340px in the CSS, because I have left and right padding of 20px, totalling the width of my image: 380px.

To get the bottom corners to show up, more markup is needed:

<div class="roundBox">
  <p>beautifully-encapsulated paragraph</p>
  <div class="boxBottom"></div> 
</div>

The ‘boxBottom’ div should be styled to fit at the bottom and stretch to the full 380px.

.roundBox .boxBottom {
  background:white url(roundBox.gif) no-repeat bottom left;
  font-size:1px;
  line-height:1px;
  height:14px;
  margin:0 -20px -20px -20px;
}

And now I’ve got a rounded corner box that can stretch down pretty far – in this case, 780px.

Other methods I’ve used (besides… um… tables)

Another way I’ve made rounded corners is illustrated on this very website, in the upper right-hand corner of the content. It’s using the -moz-border-radius-topright, and since it’s just a trivial presentational dollop, I couldn’t care less than it’s mozilla-only.

In the past, I’ve attempted to use absolutely positioned divs with negative margins to make each corner of a bordered box, but that didn’t go well with IE (not even 7), so IE didn’t get rounded corners that day. When I redid the project, I used the gif method described above.

Flexible alternative

If dynamic width and height are required, I’d recommend checking out this article.


This post was ported from an old host and CMS, so many comments were lost. Below are the comments that I found were most helpful regarding this post that I salvaged. Some links or attributions may not be working correctly.


With a few minor tweaks, you should be able to apply the box bottom to the paragraph instead of an empty div. Functionally the same idea, but just that much less markup.

Job Opportunity in Memphis, Tennessee

work at Hilton Hotels, and for a big project, we’re needing help for front-end web development.

We need someone who can write HTML, CSS, and JavaScript. The well-structured, valid, semantic, accessible, progressive enhancement/graceful degradation kind of stuff.

It’s a plus, but not a requirement, if you’re familiar with jQuery and have worked on gargantuan international travel web sites.

It’s full-time work, but a temporary position, lasting a minimum of six months. The candidate must play well with others, and must be able to commute to Memphis, TN.

Send a resumes, links to some of your work (descriptions would be helpful), and hourly rates to askthecssguy+hiltonjob@gmail.com.

Update Nov 7, 2007: time frame added.

Update Nov 23, 2007: The position has been filled.