The problem with the line break (BR) tag

We’ve got the <br /> tag all wrong. It’s time to make it right.

We all know the <br /> tag is used to insert a line break in HTML. But what we’ve been missing is that we were too often after something else. Let me explain.

Common reasons to use line breaks

Why would a web writer interrupt a passage of text with a forced line break? Here are a few possibilities.

  • Trying to avoid an orphan
  • Inserting a line break before a 2-word proper noun, like “American Airlines,” so the noun isn’t split
  • Formatting content like a mailing address

The problem with line breaks (<br /> tags)

Forcing a line to break in a document that will be printed is a no-brainer. But web writing has different constraints that we shouldn’t ignore.

Copy on the web has the luxury and burden of being portable. That text can show up anywhere:

  • in an e-mail message
  • on some other web page
  • in an RSS reader
  • copied and pasted into a Tweet
  • in a web browser on a mobile phone

This means that the line length you wrote your text for is simply not reliable. You need to consider how that text will show up in other places too, at unknown line lengths.

A line break may look fine on your screen, but it might look really awkward when that text appears somewhere else beyond your control.

Instead of splitting text, stick text together

Orphans

Avoid orphans especially where the text is most likely to appear, but relax. You can’t prevent them altogether.

Instead of inserting a line break, opt to rephrase the text to change the length and prevent the orphan. But realize that when that text appears elsewhere, it might just have an orphan.

You also have the option of a special white-space character called a non-breaking space. In HTML, it looks like this: &nbsp;. When you put a non-breaking space between two words, those two words will always be on the same line of text.

2+ word proper nouns

If you want to be sure that “American Airlines” remains on the same line in body text, employ a sprinkle of CSS magic. In the markup, a corporate name should be contained within a span element, like this:

<span class="brand_name">American Airlines</span>

And then to make sure that those two words stay on the same line, add a line like this to your CSS file.

.brand_name {white-space: nowrap;}

That will prevent the brand name text from being split at the end of a line. Instead, both words will flip to the next line if there is not enough room for them on the current line of text.

Formatting content like mailing addresses

In this case, I’m actually okay with using <br /> tags. But, left to my own devices, I might use some different markup and some CSS instead.

Let’s say we have an address like this fictional one.

Samuel Clemens
1835 Huckleberry Row
Hannibal, MO 63401

You could just put that text in an address element and use line breaks.

Or you could mark it up in the hcard microformat, and then think about styling it based on that markup. So, it might instead be coded like this.

<address class="vcard">
<span class="fn">Samuel Clemens</span>
<span class="street-address">1835 Huckleberry Row</span>
<span class="locality">Hannibal</span>,
<abbr title="Missouri" class="region">MO</abbr>
<span class="postal-code">63401</span>
</address>

And then a little bit of CSS like this would take care of the line breaks.

.vcard .fn,
.vcard .street-address{
display: block;
}

The point: we overuse line breaks because they don’t require any extra thought

Instead, let’s consider why we actually want a line break the next time we go to use one. There’s probably a better option once you realize that you don’t actually want to break a line of text, you really just want some of the text to stick together.

Google Analytics for WordPress (version 4.09) trips HTML validation when tracking outbound links

When I write HTML, running code through the W3C Validator is part of my process. If the code doesn’t pass the validator, there’s a slim chance I’ll consider that code ready for anything.

So after I upgraded this blog to WordPress 3.01’s Twenty Ten theme, I was mildly irritated to find that I had a few validation errors. I viewed the source code to investigate the offending lines of code, and noted that the code the validator cited was not in the source.

This phantom code led me to suspect that DOM scripting from a plugin caused the errors by inserting more code into the markup. That was it, and this evening I finally took the time to track it down. Here’s the scoop.

First, the phantom code that broke validation

W3C validator error message indicating an empty target attribute
The error indicates an empty target attribute. It turned out, this code was inserted by a plugin.

Honestly, the first time I saw this error message, I didn’t notice the error text that pointed to the target attribute. No, I was first startled by a pattern that looked to me like the tail-end of Javascript code used in an anchor’s href or onclick attribute. I was startled because, having already looked through the code, I thought I would’ve noticed that pattern, since it is one that I avoid.

Where was this code? Well, all 9 errors were in the same area of code: links to other websites (blogroll) in the sidebar. I wanted to see it for myself, so I opened the page and viewed the source code. I used the Find command and pasted in some of the code from the validator error message, but the Find came up empty-handed.

While the offending code was not in the served markup, the validator was certainly picking it up, so I went back to the validator to examine that code in more detail.

Code with an onclick javascript snippet inserted for Google Analytics tracking.
Code with an onclick Javascript snippet inserted for Google Analytics tracking. Note the target attribute.

The value of the onclick attribute was the immediate tell for where this code came from. It was the Google Analytics plugin I’m using.

Investigating the plugin that caused the validation error

Google Analytics for WordPress is a fantastic plugin. It makes integrating Google Analytics easy, and it has some excellent advanced settings.

One setting is to track outbound clicks and downloads as events so they are are viewable in Google Analytics.

Checkbox to track outbound links in WordPress.
Checkbox to track outbound links in WordPress.

To test the theory, I unchecked that box, saved the settings, and revalidated the web page.

It passed with flying colors.

Validation error identified, but I’m actually curious about tracking downloads

For the time being, I’m okay with leaving that feature turned off. I’ll let the plugin author know about it and hope the problem will be resolved soon.

Yes, I lose a feature to get back to valid code. Perhaps there is a support group for this kind of behavior.

But in my defense, this is just a personal site. I don’t make any money on it, and my interest in tracking downloads is just curiosity. I only have a few downloads or outbound links I’m interested in, and I have nothing riding on that knowledge beyond satisfied curiosity.

Still, the entirety of this problem can be laid to rest on a simple, meddlesome, and empty target="" attribute. That’s irritating.

Marking up breadcrumb navigation

Breadcrumb navigation is a secondary navigation system that usually represents a site visitor’s current position in the site, showing other pages above the current one in the site’s hierarchy.

In some sites, like those built with Dokuwiki, breadcrumbs actually show the history of the user’s session instead of the hierarchy of the user’s current position in the website.

Breadcrumb navigation is typically found at the top of a content region, and usually below primary tabbed navigation.

History? Bah, yesterday’s newspaper.

In his April 10, 2007 Alertbox, Breadcrumb Navigation Increasingly Useful, Jakob Nielsen declares, Breadcrumbs should show the site hierarchy, not the user’s history.

For the purposes of conceiving of solid, semantic markup, let’s agree with Nielsen. Breadcrumbs represent position in a site’s hierarchy.

Semantic values: hierarchy, location, current position

In hierarchical breadcrumb navigation, the following aspects of information are important.

  • Steps in the hierarchy that show broader sections of the site related to current position, i.e., the ancestors of the current page
  • The order of those steps
  • The ability to immediately jump to any ancestor page
  • Indication of the current page, which should not be linked

The markup

So, with those in mind, here is an example that provides just enough code and semantics, and little else.


<ol id="breadcrumbs">
<li><a href="../../../../../../">Kim Jong Il’s Favorite Widgets, LLC</a></li>
<li><a href="../../../../../">Military</a></li>
<li><a href="../../../../">Nuclear</a></li>
<li><a href="../../../">Warheads</a></li>
<li><a href="../../">Just for funsies</a></li>
<li><a href="../">2006</a></li>
<li class="current_page">Gilju, Hamgyong province, 0136 GMT</li>
</ol>

This markup is fairly lean, yet does communicate the order of steps via the ordered list.

Note that the Project Cerbera website provides a nice discussion and some other examples of breadcrumbs markup that are in line with this approach.

The examples at Project Cerbera also show nested lists to indicate the nested nature of the links, but that is over-the-top. The simple ordered list sufficiently communicates the order of steps in the hierarchy, without providing additional markup noise for a screen reader to announce or a designer to style.

Style

The breadcrumbs should strive to follow conventions.

  • Take up one line
  • Use a standard separator between steps, like >
  • Each step links to an appropriate page using standard link indicators (underlined and colored)
    • Except for the last step, which should be unlinked and represent the current page

Unstyled example

  1. Kim Jong Il’s Favorite Widgets, LLC
  2. Military
  3. Nuclear
  4. Warheads
  5. Just for funsies
  6. 2006
  7. Gilju, Hamgyong province, 0136 GMT

Styled example

Minor variations could include having the current page item be in a bold font, however, breadcrumbs are secondary navigation. They don’t need to attract much attention.

To reference the Project Cerbera site again, the examples there use a greater-than background-image on the list items. That technique may stand better in cross-browser tests than the use of the after pseudo-class used here.

HTML form fields that, when not selected, do not even send a field name upon submit

Checkboxes and radio buttons that have not been checked and multiple select lists that have no selection submit nothing upon submission of the form. It’s as though they aren’t even there.

At first, this may seem obvious (Well, yeah, you didn’t select them, dummy!), except that it runs counter to every other form field.

If you have a text field named “surname” and you submit the form with no value in “surname”, the submission still includes the variable name “surname” but it has no corresponding value. You have the key with a null value.

It’s the same with textareas, any other type of input element, and select lists (where you are limited to a single selection). Even named buttons submit their values.

So, the stealthy cuplrits:

  • input type=”radio”
  • input type=”checkbox”
  • select multiple=”multiple”

Adam and I learned this in the midst of discussing and testing code this evening.

Clean XHTML of shooting ranges data

My goal is to upload a comprehensive list of shooting ranges to Google Maps (see prior posting). So, to accomplish this, here are the steps I’ve thought of.

My goal is to upload a comprehensive list of shooting ranges to Google Maps (see prior posting).

Why? I just think it would be cool to visualize places to shoot in Michigan.

Plus, once they are in there, I can see next steps, like creating a custom map of just the ranges that host matches for the Central Michigan Rifle and Pistol League shoots.

So, to accomplish this, here are the steps I’ve thought of.

  1. Clean the source code from the NRA page of ranges in Michigan into a valid codebase that can be more easily parsed
  2. Create a prototype of the form that data needs to take to be uploaded to a Google Map (looks like a KML file will do)
  3. Write an XSL document to use to transform the cleaned code (#1) to match the structure for the KML doc (#2)
  4. Run the XSL tranformation and then upload the resulting KML document to Google Maps

Just for the record, here’s the cleaned source code (#1): 2007.12.16-shooting-ranges.html

We need a “credit” attribute in XHTML

The XHTML 2.0 draft document by the W3C includes some promising attributes for elements. For instance, a navigation list could have a role with a value of sitemap. I.e.: <nl role="sitemap">

That’s cool. Think on that a bit, o ye of semantic persuasion. The potential benefits of this type of specificity in standard markup is great.

Now, that said, I was working on a site that I hope to launch tomorrow, and I would have loved to use an attribute like credit for image elements. It would be used to specify photo credits for a couple images I’m using, plus on some banners, I could have credited the designer who put them together.

It would look something like this: <img src="cool.jpg" alt="Illustration of a calico cat in a beret playing the saxophone." credit="J. Smith, Illustrator for Cool Colors, Inc." />

We could throw this information into the alt text, but it doesn’t really belong there, since the alt text is supposed to describe the contents of the image. We could also use the title attribute, but it would be nice to reserve that for slightly more pertinent information.

Today, I just added credit information in as comments in the markup. It was an adequate solution, I think, but will never be picked up by any user-agent.

Diagram of XHTML, CSS, JavaScript as types of code in a web page

XHTML, CSS, Javascript as part of a web page
XHTML, CSS, Javascript: Cumulative aspects of a web page. Click the image for a larger version.

I’m thinking of using this diagram in an XHTML class I may be teaching in a couple weeks. The idea is to put XHTML, CSS, and Javascript in context with each other—yet to also illustrate that they are separate types of code and often are actually different files altogether.

Semantic vs. valid markup

Scott Pennington of Matrix at Michigan State University emailed an interesting link to me. The SimpleBits blog has a post and discussion of semantic markup of a page heading. A fairly elementary quiz starts it off, but the range of perspectives in the discussion starts to show the complexity of semantic markup.

On the one hand, if something is a paragraph, mark it up as a paragraph. If it is a list, mark it up as a list. Pretty straightforward.

But, semantic markup is not the same as valid markup. You can write markup that is perfectly valid, but not at all semantic.

For instance, when I worked at Michigan State University I was working on a pretty large web project, and we had just deployed a near-final version as most of the team went on a holiday break. While on vacation I got a few calls: one from my boss and another from a consultant they were bringing in to do a little more work.

I figured everything was fine, but when I came back I found out that all of the semantic, valid paragraph markup in the web site had been replaced with double line breaks between “paragrahs.” There wasn’t an actual paragraph left in the whole site. Sure, visually there was, but in terms of semantic markup, they had vanished.

Upon asking the rationale, the answer was that line breaks gave you more control over spacing between page elements. Anyone who has a clue will realize, of course, that you don’t control spacing on web sites with line breaks, you control it with CSS.

After trying to explain the issues to my boss, I ended up having to live with the non-semantic markup. The issue was deemed as a difference of opinion between two programmers, and neither position was wrong. How very diplomatic. I personally think it devalued the end product we gave the client.

This was just at the beginning of semantic markup becoming a big issue in the web community, so I had very little literature or other examples to draw upon. I feel somewhat validated as my stance on the issue has since been backed up by some of the leading names in the web field.