When to Use Events vs. Pageviews for Google Analytics

How to set up a schema for tracking certain things on a website is a polarizing topic. I’ve seen numerous schema that rely solely on pageviews to track everything—outbound link clicks, downloads, modal dialogs, etc—and the creator is dogmatic about the approach. But, semantically speaking, one of those three actions is a legitimate pageview; two aren’t. They’re events. I’m admittedly zealous when it comes to semantic use of Web technologies, but let’s face it: it makes for intelligent information architecture.

A good philosophy for tracking is: if new information is shown in the browser, at an address owned by you, it is a pageview. Everything else is an event.

Tracking link clicks

The short answer: tracking a link is tracking an event.

For instance, clicking on an outbound link does not result in a pageview for your website. Viewers are not looking at content on your site. Thus, an outbound link click is an event.

Clicking on a related link—such as to another similar blog post—is not a pageview, it is an event. The pageview itself will be tracked when the new page loads, but if you want to track the actual link click, you should register an event. Otherwise, you’ll be double tracking pageviews or tracking pageviews for a single page under multiple paths. Neither is ideal or desirable in an intelligent tracking schema.

Clicking a link that triggers a popup is covered in:

Tracking pop-up, modal, or ajax-inserted content

Are you tracking this based on link clicks? Why?

When tracking a popup, you should add tracking code to the popup file. The new window is a pageview. There’s no reason to track the link click as the pageview when you can add basic code to the popup and let Google handle it all.

For modal or ajax-inserted content, proper tracking means triggering a pageview when the content is shown. This is different from when the triggering link is clicked. Most plugins that allow modal dialogs or on-screen popups have an API that features some sort of onShow or afterRendering hook. This is the best place to put your pageview tracking. And yes, this is a pageview, because it is showing new content.

There are some cases where the link should be tracked, and those should be tracked as events. For instance, if you have a modal or popup contact form, you’ll want to track a pageview when the form is displayed, and an event to track which page the form is on or which link is used to display the form. Two different types of tracking that happen at two different (but very close together) points in the interaction.

The tricky case of PDF documents

PDF documents are one case where I entertain either option, but that is because there are two possible ways that PDFs extend the website: as downloadable content or as browser-viewable content. Older browsers and the default installation of Firefox treat PDFs as downloads. They are not displayed in-browser. Thus, under my definition of a pageview, clicking on a PDF link is an event. Think of it this way: we know that the user clicked the link, but we can’t be sure that the user actually downloaded or opened the document, so there’s no empirical evidence that there was a pageview.

However, modern browsers like Safari and Chrome, and certain mobile platforms will open PDF files seamlessly. In that case, for most intents and purposes, clicking a link results in a definite pageview.

Example cases:

Server forces PDF download, will not serve in browser
Event. There is no possibility the page is viewed in the browser. Any content is downloadable, not viewable.
PDF is provided because resources/desire/ability to convert to Web are not available, but is considered Web content
Pageview. There is a possibility that the page will be viewed in the browser, and that is the intended functionality anyway.
File is of a form or tutorial intended for printing
Event. The intent is not to view the content, but to provide a format for printing and interacting with outside of the Web. This is not pageview content.

In most situations where I’ve implemented tracking for PDFs, their use has fallen under the event philosophy, but I do see instances where a pageview does make sense.

How do you make decisions about pageviews or events? How do you use the resulting data?

This post follows , a post about debugging your events and pageview code. I hope to follow this with a tutorial about implementing JavaScript for this tracking.

The Many Faces of the Hyperlink

The World Wide Web is built on links. It thrives because links are everywhere. There are links to the various pages on individual sites. There are links from one site to another. There are links in e-mails to websites. There are links in PDFs and documents and presentations to Web pages. Chances are, you used a link to get to this article. Yet, when it comes to setting up a website, styling and consideration of links is often overlooked. Or worse, specific choices for links are made that end up hurting the usability and interaction of your website.

Link states and their selectors

A link isn’t just an element with one look. It has five different states that can be styled with CSS (and to some degree basic HTML, but you should be separating your styling from your content). Here are the different link states and their associated CSS selectors.

a:link
The link state is the basic state for a link. It’s the blue, underlined text default. A link that hasn’t had and isn’t currently having any action on it should look like this.
a:hover
The hover state is what happens when you move your mouse over a link. Typically, this involves a change in color or decoration. The mouse cursor also changes.
a:focus
Perhaps the most often overlooked state, the focus state is to keyboard navigability what the hover state is to mouse users. When a link is focused on using the keyboard, or after being clicked, it will use the definitions of this state to style it. Default styling generally puts a dotted outline around the element.

You can change the color, style and width of dotted outline (or remove it altogether, although that’s not recommended) in CSS with the outline property (ex. outline: #f00 solid thick;). In newer browsers, other elements can have outlines as well (allowing for double borders), although IE will only display an outline on links only.

a:active
The active state controls how the link appears right after being clicked (while the action is taking place, such as requesting a new page). This gives feedback to the user that their click was registered by the browser, and that something is happening, even if it isn’t readily apparent. The default for this is typically a red text color.
a:visited
If a user has viewed the destination page, the link is considered visited. This is important feedback for the user so that they can know which pages on your or external sites they’ve already seen, thus not needing to click on the link. Default styling of visited links usually colors the link an eggplant or dark purple color.

Each one of these selectors should have a different style. Why? It’s all about usability.

Usability

The Internet as we know it—that is, the one available to the public—was born right around 1992. That was 18 years ago. (Think about it, the majority of students in this years incoming college freshman class were born that same year.) In that time, visitors have come to expect certain things on the Web. For instance, what is the first thing that comes to mind when you see blue, underlined text? You said “a link,” didn’t you. Blue, underlined text has become synonymous with a hyperlink. People see it, instantly recognize “ooh, a link!”, then click on it if they think it looks interesting to them. They die a little inside if it doesn’t do anything. They rejoice if it takes them to another page. That is usability.

Usability: the ease with which a visitor can accomplish basic tasks on your site. Navigation is the most basic task on the web, after reading content.

If you’re only willing to put a minimum amount of consideration into link styling in your design or development, the best thing you can do is dont do anything to the browser defaults. Ok, so maybe those colors would be a little difficult to read on say, a black background, but at least users would understand that they’re links.

Users need to know four basic things:

  1. Specific text is actionable (that is, it is a link)
  2. They are hovering or focusing on it (taking action will do something and they’re clicking on what they intend to)
  3. Something is happening once they’ve clicked on it
  4. Whether they’ve already seen the destination

If your link looks like plain text, no one is going to try to click on it. They don’t have any cues to know that they can take action.

If your link doesn’t change when the visitor is hovering or focusing (via keyboard), they can’t be sure that when they click (or hit enter) something is going to happen. What if they do click but cause something else to happen? That’s bad usability. These two states (hover and focus) are perhaps the only two that I can consider ok to have the exact same styling. Both states indicate that pressing a button (on the mouse or keyboard) will activate the link. If you remove the default outline for the focus state, make sure to do something else that makes it very obvious to a keyboard user that the link is being focused on. Some browsers, like older versions of Opera don’t do anything with the focus state, and others, like IE6, end up meshing focus and active together, so having slight differences between hover and focus might be best for browsers that get confused.

If nothing immediately happens when a user clicks, they might think they missed the link or it is broken. They need feedback to know something is happening in the background, especially if it takes a noticeable amount of time to request the new page.

If they’ve seen a page on the site already, they might not want to visit it again right now. Or, if they’re clicking on various links to read after they’ve finished scanning your content, they might want to know if two links go to the same location. If your visited links look exactly the same as unvisited links, users have no indication of this. Give them some.

Consistency

I’m sure plenty of Web designers are cursing at me right now about stifling their creativity, saying “that color scheme looks like total dog-poo with my design.” And I totally understand that sentiment. You can style your links differently than the browser defaults. I do it. But if you do, at least keep it consistent.

If links on your website are say, bold orange text with no underline, people will probably pick up on the fact that bold orange text with no underline are the links on your site. But if you also use bold orange text for some other type of emphasis, people will be confused when they try to click and nothing happens. Or if another link is suddenly italic red text with an underline, they might think they’ve visited the link, or it’s not a link, or who knows what. It’s unlikely that they’ll click on it. Consistency is key. If you want your users to memorize a new paradigm, make sure you always use your new paradigm.

And please, for the sake of all things holy and unholy, don’t use blue, underlined text unless it is a link. (Or if you are a sadistic developer who takes pleasure in frustrating and confusing your users.)

Exceptions to the rule

There are always exceptions to the rule. The major one here has to do with in-site navigation. Obvious site navigation, like menus and footer links can be styled differently than normal hyperlinks. If users expected your navigation to be blue underlined text, the Internet would be a far more homogeneous place, and that would be boring. When you have obvious menus, your users are going to understand that those are links to other pages in your site. But when you have links within your content, they need to know immediately that they are looking at a link.

A side rule to this: don’t link to external sites from your site navigation without clear indication of what is happening. That is really jarring, and a good way to get people away from your website so that they don’t come back. Site nav links should almost never open in a new page, either.

What link styling strategies have you found work best for you?

You Are Not a Web Developer

Yes, I’m talking to you, Dreamweaver user. You. Are. Not. A. Web. Developer. You’re just the person that is screwing up the nice, pretty, semantic, standards-based Internet for the rest of us. The one that devalues our hard work with your naive undercutting. The one who makes our life hell when our project managers quote maintenance or design-tweaking projects not realizing that we can’t just reuse your code and keep our dignity intact. You. I really hate you, you MM_preloader using, nested-tables employing you.

But it’s not because you use Dreamweaver. It’s the fact that you use it as a crutch. Yes, you call it a tool.  A great tool that lets you create these awesome sites without knowing how to do any coding. That, my enemy, is a crutch, not a tool. And p.s. your sites aren’t awesome; they’re bloated, inefficient and have nasty, nasty code under the hood because you don’t know the two types of markup that a developer uses daily: CSS and HTML.

Why is it so wrong?

Don’t worry, I’m not going to just berate you and not try to back myself up a bit.

You can’t fix it when it doesn’t work right

So, you tell Dreamweaver to lay something out in a specific way, but then it doesn’t look right in a certain browser. But, you don’t know how to fix the code and make it work right, do you? Yeah, didn’t think so. Don’t get me wrong, developers spend time debugging and don’t always know how to fix it, but we do know what we’re looking at when we take a gander at the code, and can understand what the code is doing when we find a fix from some other resource.

You’re ignoring SEO

Sure, you might be using header tags, and may even have the right meta tags in there. But you’re not coding for search-based optimization. First, your code is bloated. Search engines sometimes parse the first hundred or fewer lines of code, and your bloated code might not have anything of interest until far later in the code. Second, if you are using rollovers or drop-down menus, you’re using code that search engines can’t do anything with. Much of Dreamweaver’s built in code for things like drop-down menus and rollover images is based on JavaScript, even though it’s not generally needed to do either of those things. Both can be accomplished with CSS.

You’re letting your users get bored

Have I mentioned that your code is inefficient and bloated? Yes? Well, I don’t mind saying it again and again and again. Because all that inefficient, bloated code is extra bytes for your users to download. Extra bytes that really increase loading time. People get bored waiting for a site to load. Then they leave. Without seeing your content. In this new world of 2010, where it seems like everyone has mobile Web access, small, efficient sites are back in vogue. Who wants to pull down three different JavaScript libraries and hundreds of extra lines of code on 3G? (Gods forbid a user is still on EDGE) Slow sites mean fewer visitors willing to stick around long enough for the chance to visit. Svelte code is sexy. Your overweight code is as bad as the obesity epidemic plaguing America.

And this point isn’t just true of Dreamweaver-based sites. iLife, Frontpage, Microsoft Word, whatever other WYSIWYG editor du jour you can name… they all create truly horrendous code that is terribly bloated.

Hey Kettle, you’re black!

Yeah, Pot, that’s right, I do use Dreamweaver. Eight hours a day, more or less. But you know, for a while there, I actually forgot it had something called design view, until my preferences got all screwed up and reset themselves, causing a project to load up in design view. That was a shocker. See, I use it because it’s a decent text editor and code completion speeds up development time. It has a built in project system with an FTP tool that keeps me from having to run two or three programs at a time. But ultimately, I use it because it is what is on my system at work.

Curtis McHale said it well in an article reprimanding hiring managers for saying “Dreamweaver users need not apply”:

At my fulltime job it simply comes down to cost. I use Dreamweaver because it is in CS3. There is no real break through feature that I could find to justify to my boss so that they would purchase Coda.

And Curtis is lucky. He posted that over a year ago and had CS3 at work. Here it is Aug. 2010 and I’m still stuck with CS2 at my 9-5. It’s a sore point for me. But hey, I’m employed, I’m not going to complain too awful much. But there’s probably a snowball’s chance in hell that my company is going to pony up cash for a different program.

I could write a site up in Text Edit or Notepad if that is all that was available to me, then pull up an FTP program to upload to the server. It’d decrease my efficiency, but I could do it. But if you’re paying me, don’t you want me to be as efficient with my time as possible? Of course, if you aren’t the company I work for, you’re not paying me to use Dreamweaver because I use Coda at home. But you, you’re not efficient. It takes me less time to type it all out, because I know the code, than it does for you to go through all the WYSIWYG dialogs.

Are you willing to defend Dreamweaver WYSIWYG? Go ahead, play Devil’s advocate in the comments.

Online Retailers: Help Your Customers Find Your Products

The Web is ever changing, and this article is relatively ancient having been published 7 years ago. It is likely out of date or even blatantly incorrect in relation to modern better practices, so proceed at your own risk.

Aisle of products One of my favorite (only because it has the best, low-price selection) sources of quality fabrics has horrible UX on their store site. Horrible to the point that I’m only able to do rudimentary filtering because I understand the GET variables they use to display their catalog. In fact, I wrote a post to help non-developer users figure out how to filter the catalog by changing the URL. The fact that I had to do either of those things really bothers me as a front-end developer; your users should never have to resort to manipulating the URL in order to filter or find products.

If a user can’t easily figure out that you carry a certain product, you just lost a sale. Think about that and what it means to your business.

Say a customer walks into your brick-and-mortar store wanting a specific type of whatchamacallit with a budget of $5. They see that there is a whatchamacallit aisle, but it’s just overwhelming: you have have 200 different colors of that specific type of whatchamacallit. There are different sizes, weights, and patterns. The customer’s not too picky about some of the finer points, or maybe they are, but it doesn’t matter because they only have $5 that they want to spend. So, they want to quickly narrow it down to all whatchamacallits under $5. They could go down the aisle looking at every one, but it’s easier for them to find a store employee and ask, “can you show me the whatchamacallits that are under $5?”

Being a store that cares about making a sale, your employee says yes, helps the customer, maybe even upsells them, and the customer makes a purchase. Money in the bank for the store.

Now stop. Why should this interaction be any different in your online store? That’s right, it shouldn’t be. Sure, it’s a bit difficult to have a person there, so to speak (you could have a live chat function). But there are alternatives:

  • An obvious search box that accepts queries like “whatchamacallits under $5” and returns useful, intuitive results.
  • Obvious, intuitive filtering and sorting options for search results with obvious, intuitive controls.
  • Obvious, intuitive filtering and sorting options within categories with obvious, intuitive controls.
  • An obvious, intuitive way to change the number of items shown on a page.

Notice the similarities up there: obvious and intuitive. It’s not simply adequate to provide those controls; people need to be able to find them and use them easily—just like they’d need to be able to easily find a knowledgeable employee. Good online store software will have all of those things out of the box or your developer will set it up as a standard part of your store creation. All of these filters should persist until the user says to remove it, as well: if a user filters to blue whatchamacallits then applies a $5 filter, they should be shown blue, $5 whatchamacallits not just $5 ones in any color. Sounds like common sense, right? Too many online stores don’t seem to get it.

Now, back to the earlier example. What if your employee said to the customer, “no, find it yourself.” Maybe the customer would spend time looking, but more likely they’d realize that you don’t care about their patronage and they’d go somewhere else to find the whatchamacallit. You just lost the sale. You’d probably fire an employee that did that consistently.

That’s exactly what’s happening at the fabric store. And many other online stores with outdated store software that has no filtering. There’s no provided way to easily narrow the products down to a specific one you’re searching for. There’s a search function, but it’s not that great, and there’s no way to narrow down the results. There’s absolutely no way to sort of filter the category item listings at all. They need to fire their store software.

Keep in mind that simple categorization is not sufficient criteria browsing or searching. Just because I want a whatchamacallit doesn’t mean I’m interested any whatchamacallit you carry. Shoppers, whether they’re just browsing or are looking for a very specific item, are more likely to buy from you if they can find what they are looking for. If they can’t find it, they can’t buy it. If they’re browsing a sales listing hoping to find something they think they need, you’ll have more success on a conversion if they can narrow down that sales list to items they are interested in. Sure, they can start at the top—viewing everything—but maybe they see a coolthing that intrigues them, but it’s not the perfect coolthing they want to buy. If they can easily narrow that listing to all coolthings, your ability to sell them something just increased. They know you carry the type of item, and are easily able to drill down to all items of that type. If they can’t, then maybe they keep looking, or maybe they get bored after going through another 2 pages with no more coolthings because all the other coolthings are 12 pages into the sales. A bored visitor leaves, and so does their money.

What do you expect from online shopping user interfaces? What makes you go to another store? Stay at the current store? Feel free to share good or bad experiences and examples in the comments.

Advanced HTML Tables: Columns

Last week, we discussed table basics for the year 2010 (as opposed to 1995). We set up a simple semantic table with a caption, header and footer. Today, we’re going to go over two lesser-known elements: the colgroup and col elements. I had grand plans of going into some little-known attributes for other table elements, but we’ll leave that to next week.

So, my columns feel left out

In the last article, you saw how thead, tfoot and tbody allowed for groupings of rows in a table. But often times, it’s useful to group columns as well. A couple uses I can think of include highlighting a totals column or perhaps a sales option that you want to promote. Other uses include the ability to set explicit widths for individual columns without much extra markup.

So, where do these elements go? When using column and column-group elements, you place the tags after the caption but before any row-groups or rows in the table. Modern user agents will then determine which cells belong to the appropriate column or column-group.

<table>
    <caption>Elements To Use in Proper Tables</caption>
    <colgroup span="2" width="100px">
        <col width="90px" />
        <col class="attribs" />
    </colgroup>
    <colgroup span="1" width="0*"></colgroup>
    <thead>
    ... 

colgroup: grouping columns

As you may have guessed by the “group” part of the element name, colgroup designates a structural grouping of columns. Semantically, you’re saying that the columns are related somehow.

col: sharing attributes without structural grouping

Unlike colgroup, col does not specify structure, it merely allows you to share attributes across multiple columns. In fact, for purists, one might argue that col is purely layout-driven. I’ll let you judge of that on your own.

Only two attributes?

The use of colgroup and col in HTML is limited to two attributes: span and width.

Span specifies the number of columns the group encompasses for colgroup or the attribute should apply to in the case of col. When using these two elements, make sure that the number of elements and their span attributes don’t equal more than the number of cells you have per row.

Width allows you to set the width of a column or columns in a column-group. When used in colgroup elements, remember that it specifies width of each column in the group not the total width of the grouping. If a child col also has width set it will override the parent colgroup setting. General width values are accepted, but there’s also a strange format available: the zero-asterisk (0*) value, which sets each column to be the minimum width needed to display the full cell content. You can also use an asterisk with a numerical value to designate proportional widths. For instance, if you want three columns to be set up proportionally, you could designate them as such:

<colgroup span="2" width="100px"></colgroup>
    <colgroup span="3">
        <colgroup width="1*" />
        <colgroup width="4*" />
        <colgroup width="2*" />
    </colgroup>
    <thead>
    ... 

That structure would take the total remaining width after assigning 100px to the first two columns, divide it into seven portions (1+4+2 = 7), and then apply the correct width based on portion width multiplied by number of designated portions.

Beyond these two attributes, you can use most common attributes such as id, class, align, etc.

Tell me about styling.

Here’s the drawback: colgroup and col have limited styling. You can only use four CSS attributes, and even they are limited:

  • background: you can set a background, but it is only honored if both the row and cell backgrounds are transparent.
  • border: borders work if the table has borders set to collapse (border-collapse: collapse;), at which point the borders appear based on the border conflict algorithm. If the table is set to have separated borders, no dice.
  • width: works as expected, no explicit limitations.
  • visibility: will only work with the collapse value.

But despite the limitations, these two elements can come in handy for informative tables. Let’s put it together with our table code from last time:

<table id="elements-for-tables">
    <caption>Elements To Use in Proper Tables</caption>
    <colgroup span="2" width="100px">
        <col width="90px" />
        <col class="attribs" />
    </colgroup>
    <colgroup span="1"></colgroup>
    <thead>
         <tr>
             <th>Tag </th>     <th>Attributes</th>     <th>Description</th>
         </tr>
     </thead>
     <tfoot>
         <tr>
             <td colspan="3">* denotes optional child elements</td>
         </tr>
     </tfoot>
     <tbody>
         <tr>
            <th>caption*</th>
            <td>common attributes</td>
            <td>A succinct description or title for the table.</td>
         </tr>
         ...
     </tbody>
</table>

table {
    margin: 1em auto;
    border-collapse: collapse;  /* note that this is required for using border on columns */
    }
caption { font-size: 1.2em; }
th, td {
    padding: .25em;
    border: 1px solid #000;
    font-family: sans-serif;
    }
caption, th {
    color: #004900;
    font-weight: bold;
    text-align: left;
    }
thead tr, tfoot tr { background-color: #aaa; }
thead th {
    border-bottom: 3px double #000;
    background-color: #ccc;
    text-align: center;
    }
tfoot td {
    border-top: 3px double #000;
    color: #333;
    font-style: italic;
    font-size: .8em;
    text-align: right;
    }
tbody th { color: #000; }
col.attribs {
    background-color: #B6FFBD;
    border: 2px dotted #004900;
}

The result:

Elements To Use in Proper Tables
Tag Attributes‡ Description
* denotes optional child elements
† denotes tags to be discussed in part two, next week.
‡ only tag-specific attributes are included. In general common attributes are also allowed. See the W3C HTML 4.01 Attribute Table for a complete list.
caption* A succinct description or title for the table.
colgroup* span, width A way to group columns for semantic accessibility, progressive enhancement and styling.
col* span, width A child element of colgroup, used to share attributes amongst multiple columns.
thead* A group of rows comprising a header for the table.
tfoot* A group of rows comprising a footer for the table.
tbody* A group of rows comprising the body of the table. There can be multiple tbody elements.
tr A table row. If thead, tfoot, and tbody are not used, this will be a child element of the table, otherwise it is a child element of the rowgrouping elements.
th* †abbr, axis, colspan, headers, rowspan, scope A table heading. A child element of tr. Most commonly used to signify column headings when used in a thead element, but can be used as a row heading as well.
td †abbr, axis, colspan, headers, rowspan, scope, Table data. A child element of tr. The most numerous element in a table, it contains data.

Notice the funky border collapsing in the footer and that the heading background color overrides the column background color. But don’t let that limit you: be creative, and you can accomplish great feats.

Just think of how that could be useful in extremely large data sets, accounting tables, or product tables. The possibilities are endless. Next week, we’ll discuss attributes galore for semantic, accessible table creation.

How to Use the Table Element Correctly

First, how not to use the table element: as a layout tool. Repeat after me: “Tables are for tabular data. Tables are for tabular data. I will not use tables for laying out a Web page. Tables are for tabular data.” So, now that we’ve gotten that bit out the way, let’s talk about what comprises a semantic, valid table. This is basic table creation 101. Next week, we’ll talk about advanced table features.

Forget the old paradigm

Remember back in the day when this was a complete table? Perhaps one you used as a layout tool? Or one you’ve seen recently in live code and then cried a little inside?

<table>
     <tr>
        <td>
            Hi! I’m some table content. In poorly-developed sites, this might actually be where all of the site content is!
        </td>
    </tr>
</table>

Great. Enough nostalgia. That is not an OK table for 2010.

The new paradigm: semantic, accessible, complete

What was that mantra? “Tables are for tabular data.” When presenting tabular data, we need some more information about that data. Modern HTML tags help us out there. First, let’s talk about what information we need for a good data table.

Distinction between headings (<th>) and data (<td>)

When you’re looking at a table, some cells are heading information. They don’t describe actual data, they describe what the data is. Those cells are table headings (th).

Of course, the bulk of the table cells are table data (td).

You should use the correct cell element for the right type of information.

A title (<caption>)

Your users need to be able to look at the table and know what it’s about. A descriptive, succinct title helps with that.

Important notes:

  • <caption> must be the first child element of the table.
  • There can only be one <caption> element inside of a table.
<table>
    <caption>Elements To Use in Proper Tables</caption>
    ...

Headings (<thead>)

We talked about using <th> element above, now let’s talk about where to use them. Short answer: mostly in the <thead> element.

The <thead> element is one of three rowgroup elements (the others are <tfoot> and <tbody>—more on them later). It gives semantic meaning to a grouping of rows, saying “these rows are the heading of the table.” Combining it with <th> elements allows you to create a semantic section to describe columns.

Important notes:

  • The <thead> element isn’t required, however any data that deserves to be in a table deserves to have headings, right? So semantically, you should use it. And again, don’t forget about its use in selectors for progressive enhancement and CSS.
  • An empty <thead> is invalid. It must contain a <tr> and the same number of header or data cells as the body of the table.
  • You can use <td> elements in it, but again, remember the distinction between those and <th>. Chances are, you’re definining a heading in the <thead>.
<table>
    <caption>Elements To Use in Proper Tables</caption>
     <thead>
         <tr>
             <th>Tag </th>     <th>Attributes</th>     <th>Description</th>
         </tr>
     </thead>
    ... 

Table Footer (<tfoot>)

The second of three rowgroup elements, the <tfoot> element designates a group of table row elements as the footer. I can’t harp on about how you should use the <tfoot> element in every. Single. Table. Because, I admit, you don’t always need a footer for data. Semantically, it can have a few different uses. I use it for things like a total line, footnotes for data, etc. Like <thead>, it’s not a required child element.

Important notes:

  • An empty <tfoot> is invalid. It must contain a <tr> and the same number of header or data cells as the body of the table.
  • It must come before the <tbody> element(s). Straight from the W3C:

    <tfoot> must appear before <tbody> within a <table> definition so that user agents can render the foot before receiving all of the (potentially numerous) rows of data.

    In other words, if you have a lot of data, the <tfoot> should be rendered before all of the data.

  • The <tfoot> should be displayed after all <tbody> elements, despite the fact that it appears before them in the code. However, this is sadly untrue for some older user agents and most HTML as PDF rendering vehicles. It sucks, but those older clients’ use is decreasing, at least.
<table>
    <caption>Elements To Use in Proper Tables</caption>
     <thead>
         <tr>
             <th>Tag </th>     <th>Attributes</th>     <th>Description</th>
         </tr>
     </thead>
     <tfoot>
         <tr>
             <td colspan="3">* denotes optional child elements</td>
         </tr>
     </tfoot>
    ...  

Table Body (<tbody>)

The final rowgroup element, <tbody> defines the body of your table—the section that contains all of your data. There can be multiple <tbody> elements in the table, if such a grouping makes sense for your data.

Important notes:

  • In any table that uses <thead> and <tfoot> elements, <tbody> is required. Otherwise, it is implicit. You should include it anyway.
  • For the most part, <tbody> will contain a bunch of <td> elements nested inside of <tr> elements. <th> elements are also appropriate if you want to add a heading for that row.
  • Using multiple <tbody> elements is not appropriate for zebra-striping. That should be a progressive enhancement with Javascript.

So, to wrap it up, code for a complete simple, semantic table will look something like this:

<table id="elements-for-tables">
    <caption>Elements To Use in Proper Tables</caption>
     <thead>
         <tr>
             <th>Tag </th>     <th>Attributes</th>     <th>Description</th>
         </tr>
     </thead>
     <tfoot>
         <tr>
             <td colspan="3">* denotes optional child elements</td>
         </tr>
     </tfoot>
     <tbody>
         <tr>
            <th>caption*</th>
            <td>common attributes</td>
            <td>A succinct description or title for the table.</td>
         </tr>
         ...
     </tbody>
</table>

Using Progressive Enhancement and Styling

The best argument for using complete semantic tables is for progressive enhancement and styling selectors. In the old paradigm, you’d need to add classes everywhere to style things; a class for the headings, a class for the footer, a class for row groups, etc. Instead, view this simple example of styling without any classes using only the elements:


table {
    margin: 1em auto;
    border-collapse: collapse;
    }
caption { font-size: 1.2em; }
th, td {
    padding: .25em;
    border: 1px solid #000;
    font-family: sans-serif;
    }
caption, th {
    color: #004900;
    font-weight: bold;
    text-align: left;
    }
thead tr, tfoot tr { background-color: #aaa; }
thead th {
    border-bottom: 3px double #000;
    background-color: #ccc;
    text-align: center;
    }
tfoot td {
    border-top: 3px double #000;
    color: #333;
    font-style: italic;
    font-size: .8em;
    text-align: right;
    }
tbody th { color: #000; }
Elements To Use in Proper Tables
Tag Attributes‡ Description
* denotes optional child elements
† denotes tags to be discussed in part two, next week.
‡ only tag-specific attributes are included. In general common attributes are also allowed. See the W3C HTML 4.01 Attribute Table for a complete list.
caption* A succinct description or title for the table.
colgroup*† span, width A way to group columns for semantic accessibility, progressive enhancement and styling.
col*† span, width A child element of colgroup, used to share attributes amongst multiple columns.
thead* A group of rows comprising a header for the table.
tfoot* A group of rows comprising a footer for the table.
tbody* A group of rows comprising the body of the table. There can be multiple tbody elements.
tr A table row. If thead, tfoot, and tbody are not used, this will be a child element of the table, otherwise it is a child element of the rowgrouping elements.
th* †abbr, axis, colspan, headers, rowspan, scope A table heading. A child element of tr. Most commonly used to signify column headings when used in a thead element, but can be used as a row heading as well.
td †abbr, axis, colspan, headers, rowspan, scope, Table data. A child element of tr. The most numerous element in a table, it contains data.

Hey, we have some different stuff going on, and not a single styling class to be found! Now, that, my dear readers, is good, modern (X)HTML.

As for progressive enhancement, I’m not going to cover anything here, but things like zebra striping, column sorting, scrolling, etc. are possible with the addition of semantic elements. In fact, in the W3C documentation on HTML tables, they give the following reasons for having <thead> and <tfoot> elements:

This division enables user agents to support scrolling of table bodies independently of the table head and foot. When long tables are printed, the table head and foot information may be repeated on each page that contains table data.

Sounds like a good reason to use semantic tables to me!

Why?

Because it’s good development.

More importantly, having a solid semantic framework for your table makes it better for accessibility, progressive enhancement and styling. It’s the same argument for any semantic, valid code. It’s better. It makes your life easier in the long run. It’s the right thing to do.

Stay tuned for next week, when I expand on the topics we discussed today and show you how to use little-known attributes and a few more elements to really make your tables “pop.” Okay, they won’t pop, per se, but they’ll provide very important instructions for non-visual browser clients and provide a few more hooks for progressive enhancement and CSS styling.

Semantic, Accessible (Good) Forms: the Label Element

One of the most common issues I see with forms is the improper (or lack of) use of label elements. Admittedly, I too am guilty of misuse, but even after becoming aware of them, I was very confused about how to do radio and checkbox elements. Why? I learned incorrectly that the for attribute of the label referred to the name attribute of the input. Wipe that from your memory this instant. The label’s for attribute is a reference to the input’s id.

Wait, back up. What is the label element?

The label element in HTML provides a way to give semantic meaning to the text describing or labeling form control elements. Using the element not only gives you an element to style around your labels, but also provides accessibility and functional advantages.

By using a properly constructed label element along with your input, textarea, or select element, you give

  • screen readers information on which form control the label belongs to,
  • manually maladroit visitors an increased click area (clicking on the label focuses on the element), and
  • yourself a semantic element to target with CSS and Javascript to use in design and enhancement.

Add this element and its use to your list of best practices for forms.

How do I use the label element?

The label element is simple to use and shouldn’t cause any additional headaches while setting up forms. Its usage is simple:

<label for="visitor-email">E-mail address</label>
      <input type="text" name="email" id="visitor-email" size="32" />

It can go either before or after your element. In a real form, you would most likely have the entire line wrapped in a list item or paragraph element, but I left those off for purposes of demonstration.

For checkboxes and radio buttons, the usage is very similar. You provide a label for each individual element, keyed to that element’s id attribute:

<label for="contact-by-email">e-mail</label>
      <input type="radio" name="contact-how" id="contact-by-email"  checked="checked" />
<label for="contact-by-phone">phone</label>
      <input type="radio" name="contact-how" id="contact-by-phone"  />

Incorrect use, a demonstration

The following are improper uses of the label element:

<label>E-mail address</label> <input type="text" name="email" id="visitor-email" size="32" />
In this example, the label does not have a for attribute declared, so its semantic value and aid in accessibility is lost.
<label for="contact-how">Contact by</label>
       phone <input type="radio" name="contact-how" id="contact-by-phone"  checked="checked" />
       e-mail <input type="radio" name="contact-how" id="contact-by-email"  />
Here, the for attribute is referring to the name attribute of the inputs. This is incorrect. The for attribute is a reference to the id attribute of the input.
<label>Phone <input type="radio" name="contact-how" id="contact-by-phone" checked="checked" /></label>
While technically correct according to W3C recommendations, this method should not be used. The reason being, certain browsers, particularly mobile browsers, handle this code incorrectly and will often cause the element to be un-clickable. You are better off using the method of labeling checkboxes/radio buttons I described above.

For detailed information on the label element and other form information, check out the W3C Recommendations on Forms.