Span alignment trick

This is a bit off my normal track, but it’s a cute little HTML/CSS trick you may find useful.

The neighborhood pool my family belongs to has a water polo team that plays the other pool teams in the area. My boys play on the team, and my wife and I volunteered to do some of the team’s administrative tasks. As the computery person, I’m in charge of maintaining the player database (just a spreadsheet), the parent email list, and the team’s web page.

Until recently, I had the schedule was a simple HTML table that took this form:

DateTimesOpponentLocation
Tue, June 14U11 5:30p
U14 6:15p
West GlenAway
Thu, June 16U11 6:00p
U14 6:45p
White EagleHome
Sun, June 19U11 6:00p
U14 6:45p
BreckenridgeAway
Tue, June 21U14 6:00pWaubonsee ValleyAway
Thu, June 23U11 5:45p
U14 6:30p
SpringbrookHome
Sun, June 26U11 6:00p
U14 6:45p
Rose HillHome
Tue, June 28U11 5:00p
U14 6:15p
StillwaterAway
Thu, June 30U11 6:00p
U14 6:45p
StonebridgeAway
Sun, July 3U11 5:30p
U14 6:15p
TamarackHome
Tue, July 5U11 6:00p
U14 6:45p
HighlandsHome

(I’ve changed the dates, times, and opponents, but the structure is the same.)

We have teams for two age groups: 11 and unders (U11) and 14 and unders (U14). To get the two-line entries for times, I used a <br /> tag in every row, like this:

html:
<tr><td>Sun, July 3</td><td>U11 5:30p<br />U14 6:15p</td><td>Tamarack</td><td>Home</td></tr>

The times lined up perfectly because “U11” and “U14” take up exactly the same horizontal space, even in a proportional font. I took advantage of the fact that all fonts, other than some purely decorative ones, use the same width for all the numerals1 and didn’t have to do any table-with-table crap to get the alignment I wanted.

Unfortunately for your lazy webmaster, one of this week’s opponents has lots of girls and has split its older team into a girls-only and a co-ed team.2 We agreed to field a girls-only team for a third match that day.

This means I needed to add a new line to one of the rows. Simply adding another <br /> and a line to that row,

html:
<tr><td>Thu, June 23</td><td>U11 5:45p<br />G 6:30p<br />U14 7:15p</td><td>Springbrook</td><td>Home</td></tr>

made the information correct, but it looked like crap.

Tue, June 21U14 6:00pWaubonsee ValleyAway
Thu, June 23U11 5:45p
G 6:30p
U14 7:15p
SpringbrookHome
Sun, June 26U11 6:00p
U14 6:45p
Rose HillHome

Adding a few &nbsp;s to push the time to the right,

html:
<tr><td>Thu, June 23</td><td>U11 5:45p<br />G&nbsp;&nbsp;&nbsp;&nbsp; 6:30p<br />U14 7:15p</td><td>Springbrook</td><td>Home</td></tr>

and made the alignment good enough,

Tue, June 21U14 6:00pWaubonsee ValleyAway
Thu, June 23U11 5:45p
G     6:30p
U14 7:15p
SpringbrookHome
Sun, June 26U11 6:00p
U14 6:45p
Rose HillHome

but I figured there had to be a way to insure perfect alignment under any circumstances.

I thought I could fix the problem by using <span>s with a little inline CSS, e.g.,

html:
<span style="width: 2.5em">U11</span>

but that didn’t change the width at all. I learned from this Q&A at Stack Overflow that width styles don’t work on regular <span>s because they’re inline elements. In a perfect world—that is, a world without older versions of Internet Explorer—I could assign the <span>s a display:inline-block style, and then the width would work. But according to this table at Quirksmode, support for inline-block is dicey in IE 6 and 7.

So I went with another solution mentioned on Stack Overflow: assigning a float:left style to the <span>. This apparently creates a box for the span that can be given a width. Not as clean as the inline-block solution, but something that was easy to do.

What I ended up with were table rows that looked like this:

html:
<tr><td>Thu, June 23</td><td><span class="age">U11</span>5:45p<br /><span class="age">G</span>6:30p<br /><span class="age">U14</span>7:15p</td><td>Springbrook</td><td>Home</td></tr>

Combined with this bit of CSS,

css:
table.wpschedule td span.age {
  float: left;
  width: 2.5em;
}

I got a table that looks like this:

DateTimesOpponentLocation
Tue, June 14U115:30p
U146:15p
West GlenAway
Thu, June 16U116:00p
U146:45p
White EagleHome
Sun, June 19U116:00p
U146:45p
BreckenridgeAway
Tue, June 21U146:00pWaubonsee ValleyAway
Thu, June 23U115:45p
G6:30p
U147:15p
SpringbrookHome
Sun, June 26U116:00p
U146:45p
Rose HillHome
Tue, June 28U115:00p
U146:15p
StillwaterAway
Thu, June 30U116:00p
U146:45p
StonebridgeAway
Sun, July 3U115:30p
U146:15p
TamarackHome
Tue, July 5U116:00p
U146:45p
HighlandsHome

Just what I wanted. In fact, the extra space between the age and the time makes it easier to read than what I had before.

Update 6/22/11
If you’re reading via RSS, it’s quite likely that this last table will look even worse than ones before it. That’s an RSS limitation. If you go to my actual post, you’ll see the table the way it’s supposed to look.

As I said, if I didn’t have to worry about IE 6 and 7, I’d’ve used

css:
table.wpschedule td span.age {
  display: inline-block;
  width: 2.5em;
}

and gotten the same look with a more sensible style.


  1. Imagine how difficult it would be to align columns of multi-digit figures if that weren’t the case. 

  2. Is it unfair to have a girls-only team but not a boys-only team? Maybe, but our league’s experience is that some girls will only sign up if they can play on a girls-only team, and the league wants to encourage as many kids to play as possible.