After explaining in our previous article why it is generally a good idea to get rid of HTML tables it is time to give some practical advise on how to actually convert the tables to tableless HTML and CSS code. In this article we describe a couple of conversion methods that are generic and can be applied to any web page.
First we need to decide which HTML tag or tags could be used to replace the table elements - TABLE, TR, TD (for simplicity's sake we will ignore other seldom used table elements like THEAD, TFOOT, TH and TBODY). We choose the replacement tag based on the following criteria:
From all HTML elements DIV and SPAN elements are the only two tags that do are used purely for grouping child elements and text and do not affect the CSS style of their nested elements. Of these two elements DIV is a block element and SPAN is an inline element. This leaves us with DIV as the natural replacement for the table elements.
So lets say that we have this sample HTML code:
<html> <body> <table width="600"> <tr> <td width="50%">Cell 1</td> <td width="50%">Cell 2</td> </tr> <tr> <td>Cell 3</td> <td>Cell 4</td> </tr> <tr> <td>Cell 5</td> <td>Cell 6</td> </tr> </table> </body> </html>
We will try to convert the HTML tables in this sample code to DIV tags using CSS styles for layout.
(this was the approach used by the first version of our Table2CSS converter)
We will try to mimic the table layout as closely as possible using DIV elements. It is quite easy to replace the TABLE and TR tags:
<html> <body> <div style="width: 600px;"> <div> ... </div> <div> ... </div> <div> ... </div> </div> </body> </html>
The TD elements however are a bit more problematic to convert. Each DIV element forms a new block so it is not so easy to place more than one DIV element on the same line. Applying floating style however allows us to change the DIV element behavior and to place several DIVs side by side:
<html> <body> <div style="width: 600px;"> <div> <div style="float: left; width: 50%;">Cell 1</div> <div style="float: left; width: 50%;">Cell 2</div> </div> <div style="clear: both;"> <div style="float: left; width: 50%;">Cell 3</div> <div style="float: left; width: 50%;">Cell 4</div> </div> <div style="clear: both;"> <div style="float: left; width: 50%;">Cell 5</div> <div style="float: left; width: 50%;">Cell 6</div> </div> </div> </body> </html>
Please note that our pseudo table from the example above shows the following peculiarities:
(this is the approach used by the second version of our Table2CSS converter)
Another possible solution is to use DIV elements only for the table and the cells and completely ignore the TR elements. In this case we will have to use absolute positioning in order to place the cells and our sample table will be converted to:
<html> <body> <div style="position: relative; width: 600px; height: 60px;"> <div style="position: absolute; left: 0px; top: 0px; width: 300px; height: 20px;">Cell 1</div> <div style="position: absolute; left: 300px; top: 0px; width: 300px; height: 20px;">Cell 2</div> <div style="position: absolute; left: 0px; top: 20px; width: 300px; height: 20px;">Cell 3</div> <div style="position: absolute; left: 300px; top: 20px; width: 300px; height: 20px;">Cell 4</div> <div style="position: absolute; left: 0px; top: 40px; width: 300px; height: 20px;">Cell 5</div> <div style="position: absolute; left: 300px; top: 40px; width: 300px; height: 20px;">Cell 6</div> </div> </body> </html>
This solution has its own set of peculiarities worth noting:
<html> <head> <link href="style.css" rel="stylesheet" type="text/css"> <head> <body> <div class="main"> <div class="cell_1_1">Cell 1</div> <div class="cell_1_2">Cell 2</div> <div class="cell_2_1">Cell 3</div> <div class="cell_2_2">Cell 4</div> <div class="cell_3_1">Cell 5</div> <div class="cell_3_2">Cell 6</div> </div> </body> </html>And we would have an external file called style.css that would contain:
.main {position: relative; width: 600px; height: 60px;}
.cell_1_1 {position: absolute; left: 0px; top: 0px; width: 300px; height: 20px;}
.cell_1_2 {position: absolute; left: 300px; top: 0px; width: 300px; height: 20px;}
.cell_2_1 {position: absolute; left: 0px; top: 20px; width: 300px; height: 20px;}
.cell_2_2 {position: absolute; left: 300px; top: 20px; width: 300px; height: 20px;}
.cell_3_1 {position: absolute; left: 0px; top: 40px; width: 300px; height: 20px;}
.cell_3_2 {position: absolute; left: 300px; top: 40px; width: 300px; height: 20px;}
<table width="600"><tr><td width="50%">Cell</td></tr></table>can be replaced with the following tableless code:
<div style="position: relative; width: 600px; height: 20px;"> <div style="position: absolute; left: 0px; top: 0px; width: 300px; height: 20px;">Cell 1</div> </div>which after we merge the nested DIVs will become:
<div style="width: 600px; height: 20px;">Cell</div>