Part II - In Search of a Pure, Liquid, CSS "Tableless" Table...

By Chris Maxwell  10/19/07

That works for all content cases!

Well as it turns out CSS tables are great until you add content. If you want to learn how to make a basic CSS table or grid read my article "Part I - A Pure CSS 'Tableless' Table". Read on to learn what goes wrong with this basic CSS table and how to fix it...

So what's wrong?

Tableless Table

Row 1Wow!12345

Row 2This table looks great.12345

Row 3...but what would happen12345

Row 4if a cells content expanded12345

Row 5onto two lines or more?12345

   


Content in the real world is never so predictable and tidy...

Row 1Everything works fine on this line.12345

Row 2However, run onto more than one line like this and the table breaks in columns 1 and 3 (those cell heights do not expand with this cell).12345

Row 3Notice that the bottom borders of row 2 are not in synch.12345

Row 4Try the same exercise on column 3 of this row and -->the table breaks on columns 1 and 2.

Row 5Lets reset the table.12345

Row 6
Line 2
The only way things work correctly for a pure CSS "tableless" table is if the cell heights for all cells in a row match.12345
12345

The Solution

So how are we going to solve this problem? I almost gave up on this one, and then it came to me. Here is the solution:


Tableless Table "Hack"

Row 1So how do we solve the problem?12345

Row 2With a little image trickery of course. Applying this trickery to this table lets see what happens if we try to break the cells like we did above? Hey look at that, it works, in fact I can keep going and it will not break.12345

Row 3So how did I do it?12345

Row 4Look Mom, columns 1 and 2 don't break!

Row 5The way I do this is via a background image repeating vertically. Yup, it's just a little image trickery (hackery)...nothing super smart in the code. You can try that path but I think you will be hard pressed to find something that will solve the problem consistently and across all browsers without an external java script and a lot of code.12345

Row 6To create the image I use I take a snap shot of a portion of the table above like this (I'm only showing the left side of the image)...
12345

Row 7Then I slice a thin (~5px) portion of the image with Photoshop - make sure you miss all the text and horizontal lines, and capture slightly beyond the outer most vertical borders...
12345

Row 8I then chop off the left and right areas of the image past the borders (for this rounded corner table I chop off the outer borders as well)...

...and trim the remaining transparent pixels (Image > Trim...)
12345

Row 9What I am left with is a thin image that I repeat across the table paragraphs with a little CSS:
background: url(images/borders.gif) 0 0 repeat-y;

Because I took a snap shot of the table with the cell widths I wanted, the image will line up with the actual cell borders. The key is to start with Table 1, take the image, and then finish with Table 2.
12345

Code Changes

To implement the image hack the only thing we changed in the HTML of our table has been to add the following tag after the last row along with its class:

	<div class="lastLine"></div>
.lastLine { /* you need this class on the empty last line to create an even border on the last row of the table */ clear: both; width: 470px; border-top: 1px solid #e3e7e7; }

Here are the changes we made to the CSS:

	#table p {
		float: left; /* needs to float in order for lines to catch in ff and opera */
		clear: both;
		width: 100%;
		margin: 0;
		background: url(images/borders2.gif) 0 0 repeat-y; /* add an image to create left and right borders */
		}
	
	#table span {
		float: left;
		padding: 0 10px;
		/* border-left: 1px solid #e3e7e7; removed this because the image now replaces the borders */
		border-top: 1px solid #e3e7e7; /* switched this from border-bottom to border-top so that all row lines are even */
		}
	
	#table p.firstLine span { /* to get rid of the top border caused by the border switch above */
		border-top: none;
		}
	
	#table span.col1 {
		width: 111px; /* added 1px to this column from lost border */
		}
	
	#table span.col2 {
		width: 187px; /* added 1px to this column from lost border */
		}
	
	#table span.col3 {
		width: 112px; /* added 2px to this column from lost borders */
		/* border-right: 1px solid #e3e7e7; removed this because the image now replaces the borders */
		}
	

End Result

Here you can see the code in action using the table style described in my article "Part I - A Pure CSS 'Tableless' Table or Grid". If you would like to see how I created the rounded borders table above, just take a look at the source code for this page and the CSS. It's not much different.

Hope this helps. For image content that expands beyond the columns width limits you may need to use overflow and some kind of right border tweak. I strongly recommend using tables for tabular data though...it works better with screen readers and visually impaired users will appreciate it.