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?

Dictionary Lists: Child Elements and How to Use

One thing I see far more often than is excusable in code that I inherit is improperly used and structured dictionary lists. Certain elements in HTML are limited to having only a few specific children, and dictionary lists are no exception. Putting incorrect elements as direct children can cause display issues, parsing issues, compatibility issues and headaches for future development (whether it’s a new developer or your own updates). When developing, it should be a priority to use the correct—and only the correct—children in parent elements. Here’s how to properly use dictionary lists.

Dictionary Lists (<dl>)

The dictionary list element is meant to be used for a list of items containing terms and their definitions. That doesn’t mean you’re restricted to using this element only for word lists. For instance, the structure of the element is perfect for frequenty asked questions (FAQs): the question is a term, the answer is a definition. Dialog is another option: the speaker is the term, the words spoken are the definition.

So, let’s repeat: dictionary lists are lists of items containing terms (<dt>) and their definitions (<dd>).

A dictionary list can only have two types of child elements: dictionary term (<dt>) and dictionary definition (<dd>). Semantically, each definition can have multiple terms, and each term can have multiple definitions. That said, the first child should always be a term and the last child should always be a definition.

But <dt> and <dd>—that’s it. No other immediate children are allowed. Of course, you can put other elements inside of those two child elements. But even they have restrictions.

Dictionary Terms (<dt>)

Dictionary term elements can only contain inline elements. That means you can use things like <a>, <strong>, <em> or <span>. You can not use <hn>, <p>, <div>, etc.

Dictionary Definitions (<dd>)

Dictionary definition elements can contain any flow elements— inline or block. That means you can use things like <a>, <strong>, <em> or <span> and <hn>, <p>, <div>, etc. You can have a dictionary list inside of a dictionary definition. You can have a form inside of a dictionary definition. You can basically have anything that is allowed inside the <body> element inside of a dictionary definition.

Valid vs. invalid

The following is an invalid list (with shorthand code showing only elements, not required attributes). Don’t do it.

<dl>
<form>
<dt>Name</dt>
<dd><input></dd>
...
</form>
<dl>

Here’s a valid list.

<dl>
<dt>Ginormous</dt>
<dt>Gargantuan</dt>
<dd>Both are words that mean “enormous,” but sound way cooler.</dd>
<dl>

Get it? Good. Go forth and dev.

What tips do you have for using dictionary lists?

Accessible HTML Tables: Element Attributes

The , we covered some lesser-used child elements. Between that and the first article on tables, we’re set on table elements. But what about table-specific attributes? There are quite a few, some which you may not even be familiar with. These can help non-visual user agents as well as semantics. Read on to learn more.

A good table should generally be visually designed such that a visitor can look at it and use visual cues to understand the most important data, if any, or be guided visually toward whatever data are the focus of the table. Non-visual visitors do not receive those visual cues, however. The majority of these attributes focus on non-visual user agents. They give additional information or auditory cues to allow the table to be better understood.

Please note that when I reference “the attributes of an element” in this article, I’m referring to the element/table-specific attributes. Like most elements, these can have classes, ids, and other common attributes. No need to cover those here. Additionally, I’m from the school of separate content from presentation, as you should be, and so any attributes that are visual—and thus can be set using CSS—will also be ignored for the purposes of this article. Leave a comment if you want me to cover styling tables with CSS in the future.

table element attributes

Despite this series of articles focusing on tables, we haven’t really talked about the table element, have we? It’s pretty straight forward; you put all the important bits inside the <table> tag, maybe add a class or id, and don’t think about the actual table element again. However, for good table design, we should be putting a little more thought into that. There is at least one table element-specific attribute that is smart to use.

summary
The summary attribute allows you to provide a summary of the table for non-visual user agents. Visual users may be able to look at a table and understand instantly that such and such lines total a specific amount, thanks to visual design cues, but what about non-visual visitors? By providing that sort of information in the summary attribute, you allow them to quickly gain the understanding that visual visitors have. Example:

<table summary="The data show that sales are increasing steadily, rising almost $1000 per quarter, with a year end total of $12,000 this year as opposed to $8,000 at the end of last year.">
cellspacing
This attribute controls the space in between cells—not just padding on the cells, but actual spacing between the cells, borders and all. Modern Web development generally calls for a separation of content and presentation. As such, most display attributes for table are either deprecated or better set though CSS. cellspacing is the one remaining attribute that can’t be set through CSS reliably. Truthfully, I’ve never found need for it—I always want a cell spacing of 0, which is easily accomplished through CSS by specifying border-collapse: collapse; on the table. However if you do need spacing between your cells, the closest CSS comes is a border-spacing property that is ignored by IE. cellspacing is not deprecated, so go ahead and throw it in if you really need it. Its sister attribute cellpadding is not neccessary; you can add padding to any or all cells.

Cell attributes (th and td)

In How to Use the Table Element Correctly, we explored the difference between the two cell elements, th and td. While their use in semantic tables may differ, they share many attributes.

colspan, rowspan
The two spanning attributes allow you to create a cell that spans multiple columns or rows. For instance, <td colspan="5"> would span the entire width of a 5-column table. Likewise, <th rowspan="2"> would create a heading cell that spans two rows.

It is important to note that using these two attributes requires that you leave out cells that would overlap. Here is an example:

<tr>
    <th rowspan="2">Cells</th>
    <td>data</td>
    <td>spanning, headers, axis, abbr</td>
    <td>id, class, etc</td>
</tr>
<tr>
    <td>header</td>
    <td colspan="2">Same as above</td>
</tr>

Note that there are only two cells in the second row. The first cell is not declared, as it is spanned from the row above. And the last cell is also left undeclared, because the third (second defined) spans over the final cell.

The value of these two attributes is numeric. A value of “0” is perfectly valid; this value tells the user agent to span from the current location to the end of the row group (thead, tbody, tfoot), if rowspan, or end of the current colgroup, if colspan.

axis
The axis attribute is an interesting creature. It allows for categorization of data, which enables user agents to calculate answers to queries. For instance, in a table of expenses, if you label a cell with axis="entertainment", a user can query the user agent with something like “What did I spend on entertainment”. The user agent can ascertain which data are categorized as entertainment and then calculate an answer.

Cell attributes that are mainly useful for th

There are a few attributes that are perfectly legal to use on td elements, but if used properly, they really make more sense being restricted to th elements. They are immensely helpful to non-visual user agents, especially when the contents of the table are being read out loud.

scope
Used primarily on th elements, the scope attribute designates which cells the header refers to. Allowed values are:

  • row
  • col
  • rowgroup
  • colgroup

Adding the scope attribute to the first td in a row will cause it to act like a header with non-visual user agents. But since we’re being semantic, we’d never do that, right?

abbr
This attribute is immensely useful for non-visual agents, especially auditory ones. It allows you to specify an abbreviation of the cell contents for use when reading multiple times. It mostly pertains to th elements, which are repeated before data, however it can be used for td as well. Example usage:

<th abbr="Density">Population Density (1-100)</th>

For non-visual users, the full header would be read on the first encounter, but any repetition would use the abbreviation.

Cell attributes that are mainly useful for td

The headers attribute is the sibling of scope. Whereas scope defines which data a header pertains to, headers allows for explicit indication of which headers pertain to a given data cell. Its value is a space-separated list of ids, so you must make sure to use the id attribute on any headers referenced in this way. An example:

<tr>
    <th colspan="0" id="h1">Shared Attributes</th>
</tr>
<tr>
    <th rowspan="2">Cells</th>
    <td>data cell</td>
    <td>spanning, headers, axis, abbr</td>
    <td>id, class, etc</td>
</tr>
<tr>
    <td>header cell</td>
    <td colspan="2" headers="h1">Same as above</td>
</tr>

In the above example, we see that the cell with contents “Same as above” is marked as being headed by the “Shared Attributes” header. According to the W3C, this attribute is to be used by non-visual agents, but can also be useful to visual agents through the use of CSS styling.

Other table element attributes

The attributes for other elements, such as rows, rowgroups and columns have either been covered in or are merely design aids. The latter should be done through CSS rather than HTML attributes. If you want to learn more about those or any of the attributes discussed here, the W3C Recommendation on Tables is a great place to learn virtually everything about them. It includes plenty of examples as well.

And thus concludes the series on tables. Do you have any questions, or care to expand on what I’ve said here?

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.