Part I - A Pure CSS "Tableless" Table

By Chris Maxwell  10/19/07

I used to be a CSS purist, but because of accessibility and screen reader issues, for tabular data I use tables. Still, not everything that fits in a grid belongs in a table so lets explore a tableless table / grid.

Your basic structure

To begin, I like to use a div to contain my table, paragraphs for each row of my table, and spans for the columns. If I have three columns, I use three spans per line, each with a class corresponding to the column it represents, e.g. class="col1" for all spans that represent the first column of the table.

	<div id="table">
		<p><span class="col1">  </span><span class="col2">  </span><span class="col3">  </span></p>
		<p><span class="col1">  </span><span class="col2">  </span><span class="col3">  </span></p>
	</div> <!-- eof #table -->


For my CSS I use the following:


You can choose any width for your table, just remember that your columns along with any padding and border widths must equal the table width. For the container only define a border for the top side of the table, the left and bottom borders will be defined in the column cells (spans), and the right border in the cells of the last column of your table.

	#table {
		width: 470px;
		border-top: 4px solid #e3e7e7;


For table rows reset your paragraph margins to 0, clear each paragraph so that any cells from the previous row - which will be floated next - do not spill over, and finally set your width to 100% so that rows expand the entire width of your table container.

	#table p {
		clear: both;
		width: 100%;
		margin: 0;


Create your columns by floating spans to the left, this way they can sit side by side on a single row. The majority of table borders are defined here gloabally. Define only the right and bottom borders. Each border will become the left and bottom border respectively of the adjacent cell. I give each span some padding to keep the contents off of the borders.

	#table span {
		float: left;
		padding: 0 10px;
		border-left: 1px solid #e3e7e7;
		border-bottom: 1px solid #e3e7e7;

Finally, specify a width for each column, and in your last column add the right border.

	#table span.col1 {
		width: 110px;

	#table span.col2 {
		width: 186px;
	#table span.col3 {
		width: 110px;
		border-right: 1px solid #e3e7e7;


And there you have it, a tableless table. Remember that everything inside the containing div (id="table") should add up to its width. Here is a summary of all the widths, padding, and borders:

Widths: 110 + 186 + 110 = 406
Padding: 10 + 10 + 10 + 10 + 10 + 10 = 60
Borders: 1 + 1 + 1 + 1 = 4
Total: 406 + 60 + 4 = 470

Here is the finished code and an example of how it renders.

This code works well for grids in which all the cells are the same size, however, it breaks down when cell content requires liquid heights. To see the problem and learn about the fix read my article: "Part II - In Search of a Pure, Liquid, CSS 'Tableless' Table...".