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 21 U14 6:00p Waubonsee Valley Away Thu, June 23 U11 5:45pG 6:30pU14 7:15p Springbrook Home Sun, June 26 U11 6:00pU14 6:45p Rose Hill Home

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 21 U14 6:00p Waubonsee Valley Away Thu, June 23 U11 5:45pG     6:30pU14 7:15p Springbrook Home Sun, June 26 U11 6:00pU14 6:45p Rose Hill Home

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.

7 Responses to “Span alignment trick”

1. I’m pretty sure your inline-block solution would work for IE6/7 too. From quirksmode:

“IE 6/7 accepts the value only on elements with a natural display: inline.”

has a natural inline display.

2. Oops, my last line was meant to read:

The span element has a natural inline display.

3. Flavin says:

I don’t want to detract from your victory and all, but the solution you found isn’t supported by Google Reader. The final table is aligned the same as all the previous tables, except there isn’t even a space between the age and the time. (I thought you were crazy when you said it was just what you wanted, until I clicked through to check the formatting here.)

4. Calvin,

Since I’ve already admitted to laziness in the post, I’ll double down here. I saw the Quirksmode note on inline-block you quoted and assumed that it applied to <span>, but decided to go with the float solution anyway because I don’t have access to IE 6/7 and couldn’t run tests to be sure.

That wasn’t the laziness; the laziness came when I wrote the post. Instead of writing out an explanation like I just did, I simply said IE 6/7 support was “dicey” and moved on. I should have taken more of my time and not wasted yours.

Flavin,

Normally, I care how the RSS gets formatted, but in this case I don’t, because what’s important is how the table is formatted on the water polo page (a static page with no RSS feed), and what I want to show here is what I did on that page.

I’m glad you pointed out the RSS problem, though, and I’ll add a note to the end of the post.

You probably know this, but not all numerals in all fonts are the same width. In most fonts, the default numerals are the same width, so called “tabular” numerals, for exactly the reason that you mention, but some OpenType fonts offer both tabular (all same width) and proportional (varying widths) numerals.

You probably also know that many OpenType fonts also offer both “lining” (uppercase) numerals, the default, which are all the same height as upper case letters and have no descenders or ascenders, and “old style” (lowercase) numerals, which have varying heights plus ascenders and descenders.

As a result of these variations, some OpenType fonts offer up to four styles of numerals. I’m not sure if any of the system fonts offer all four variations, though I would bet that at least one of them does, as Apple loves to show off OpenType features, but I’m too lazy to look. Most of the Adobe Pro fonts seem to offer all four.

The preferences for the different numeral types, like most advanced OpenType features, are usually deeply buried. In Pages, you have to open the Font pane, click the “Gear” button, and choose “Typography…” The resulting Typography pane is also not a polished UI experience. Changing options only effects the current selection, but the buttons don’t change to indicate the current state of the selection…

6. And of course there is the question of what to use where…

You don’t really need tabular numerals unless you are looking for vertical alignment. But after years of seeing tabular numerals, I find that proportional numerals look squished to me. So, I basically never use proportional numerals. But YMMV.

Similarly, lining numerals are only really needed when you are seeking horizontal alignment, as in a table. I still tend to rely on them most of the time, mostly because of inertia, but I think that old style numerals look really classy in body text.

7. Allen,

You’re giving me too much credit. I knew that some fonts have old-style variants, but I didn’t know how common it was or about the Typography pane.

One thing I thought someone would pick up on was the fact that the font I use here, Georgia, has proportional numerals even though it’s not a “decorative font.”

1234567890
1111111111
2222222222
3333333333
4444444444
5555555555
6666666666
7777777777
8888888888
9999999999
0000000000

They’re also old-style, which is one of the reasons I like Georgia. As you say, classy in body text.