Sliding Doors of CSS (Redux)
A while back, Douglas Bowman wrote an awesome pair of articles for A List Apart called “Sliding Doors of CSS”. The articles described a CSS technique for making a tabbed interface where the tabs scale gracefully as the user changes his or her font size.
Bowman’s sliding doors provided elasticity based on the size of a container’s content. But it’s also desirable to achieve elasticity based on a container’s external constraints. This paradigm is particularly applicable to data sets, where we want one column to expand or contract dynamically to fill the available space.
Gmail and Google Reader give us an example of this technique:
Interestingly, while the end result is essentially the same in these two applications, the implementation is completely different: Gmail uses a table while Reader uses floated divs. Why the implementations are different doesn’t really matter (My guess? Maybe Gmail is on an older version of GWT), but it is an interesting distinction.
I will focus on Reader’s implementation for two reasons. First, it performs much better. Gmail’s interface is jumpy when resizing the browser window (on a recent MacBook—2.4GHz Dual Core with 2GB of RAM), whereas Reader is smooth as could be. Second, while a table may be an appropriate markup choice in terms of semantics, tables are inherently inflexible. Reader illustrates this point; when the user clicks on a row, the entire story expands inline. While this may be possible with a table, it would be more difficult to achieve, and the implementation would awkward at best.
The Markup
For this example, we’ll work with a list of email messages. Each message will appear in its own row, and each row will display the corresponding message’s sender, subject, and date. We’ll use a simple ordered list, where each list item represents one message. Each list item will contain a set of spans—one for each of the properties mentioned.
Here’s the basic markup for each list items:
<ol> <li> <span class="subject">Potluck tomorrow! 7pm</span> <span class="sender">Adrian Mott</span> <span class="date">3:08pm</span> </li> </ol>
The Stylesheet
The theory behind this technique is to position all columns absolutely and with known widths, except for the elastic column. That column is positioned statically and its width is constrained using right and left margins. Since we have a statically positioned element, the containing list item is “propped open”, which means we don’t have to jump through hoops to get things to layout properly. Also, you can visually arrange the columns however your want—order in the markup doesn’t matter.
Here’s the barebones CSS:
ol {
padding: 0;
list-style: none;
}
li {
position: relative;
margin: 0;
padding: 0.152em 0;
height: 1em;
}
li span {
display: block;
overflow: hidden;
height: 100%;
}
.sender {
position: absolute;
left: 0;
top: 0.152em;
width: 11.4em;
}
.date {
position: absolute;
right: 0;
top: 0.152em;
width: 6.84em;
}
.subject {
width: auto;
margin-left: 11.78em;
margin-right: 7.22em;
}
Pretty simple—have a look at the result (enhanced with some additional CSS for looks). What’s cool about this is the flexibility. Want to show the entire subject, letting it wrap onto multiple lines? No problem (just change the height on each list item from 1em to auto).
Cool!

One Comment
I thought I saw you on msnbc this evening at the DNC and wondered what my ol’ roomie was up to. Seeing your photo on this site, I know it wasn’t you in Invesco field, not even close. But my original muse still stands. Send me a line, I’d love to go skiing some time.
Lucas