CSS Hell simulating TABLE with DIV
I´m trying to simulate a table using only CSS and DIV. The problem is that nothing that I do can perfectly simulate a table layout behavior.
Below is the table layout that I want and immediately below this one, what I could achieve with CSS/DIV:
Html/CSS
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>Teste</title>
<style type="text/css">
table{
table-layout:fixed;
width: 333px;
border-width: 1px;
border-spacing: 2px;
border-style: solid;
border-color: black;
border-collapse: collapse;
}
table th, table td
{
border-width: 1px;
padding: 1px;
border-style: solid;
border-color: black;
border-collapse: collapse;
}
table th.column1, table td.column1{
width:60px;
background-color:#CCD9FF;
}
table th.column2, table td.column2{
width:100px;
background-color:#ECFFE5;
}
table th.column3, table td.column3{
width:60px;
background-color:#FFEBE5;
}
table th.column4, table td.column4{
width:100px;
background-color: #FFFFCC;
}
div#tablecontainer
{
width: 328px;
}
div.tablecontainerrow
{
clear:both;
}
div#tablecontainer div div.column1
{
width: 60px;
float:left;
border: 1px solid black;
background-color:#CCD9FF;
}
div#tablecontainer div div.column2
{
width: 100px;
float:left;
border: 1px solid black;
background-color:#ECFFE5;
}
div#tablecontainer div div.column3
{
width: 60px;
float:left;
border: 1px solid black;
background-color:#FFEBE5;
}
div#tablecontainer div div.column4
{
width: 100px;
float:left;
border: 1px solid black;
background-color:#FFFFCC;
}
</style>
</head>
<body>
<h1>CSS and TABLE</h1>
<table>
<tr>
<th class="column1">Header 1</th>
<th class="column2">Header 2</th>
<th class="column3">Header 3</th>
<th class="column4">Header 4</th>
</tr>
<tr>
<td class="column1">line 1 column 1</td>
<td class="column2">line 1 column 2</td>
<td class="column3">line 1 column 3</td>
<td class="column4">line 2 column 4</td>
</tr>
<tr>
<td class="column1">line 2 column 1</td>
<td class="column2">line 2 column 2</td>
<td class="column3">line 2 column 3</td>
<td class="column4">line 2 column 4</td>
</tr>
<tr>
<td class="column1">line 3 column 1</td>
<td class="column2">line 3 column 2</td>
<td class="column3">line 3 column 3 (more content)</td>
<td class="column4">line 3 column 4</td>
</tr>
</table>
<h1>CSS and DIV</h1>
<div id="tablecontainer">
<div class="tablecontainerrow">
<div class="column1">Header 1</div>
<div class="column2">Header 2</div>
<div class="column3">Header 3</div>
<div class="column4"开发者_如何转开发>Header 4</div>
<div class="clear" />
</div>
<div class="tablecontainerrow">
<div class="column1">line 1 column 1</div>
<div class="column2">line 1 column 2</div>
<div class="column3">line 1 column 3</div>
<div class="column4">line 1 column 4</div>
</div>
<div class="tablecontainerrow">
<div class="column1">line 2 column 1</div>
<div class="column2">line 2 column 2</div>
<div class="column3">line 2 column 3</div>
<div class="column4">line 2 column 4</div>
</div>
<div class="tablecontainerrow">
<div class="column1">line 3 column 1</div>
<div class="column2">line 3 column 2</div>
<div class="column3">line 3 column 3 (more content)</div>
<div class="column4">line 3 column 4</div>
</div>
</div>
</body>
</html>
What might I modify to allow the CSS/DIV layout resembles the CSS/Table?
Some complementary information
- Think in this as an exercise (a challenge). So please do not provide me answers saying the use of a table is a better solution for this situation.
- In fact I´m wondering a solution that can change completely the tabular layout of data to another one simply changing the CSS. In this case, the use of
<table>
is out of question.- I want compatibility with IE 7+, FF3+, Chrome 4+.
Thanks!
Again, you should use a table.
But if this is just an exercise in CSS, for kicks...
- Ditch the
<div class="clear" />
. - Ditch the background colors and use faux-columns instead.
- Don't put borders around the individual cells; instead put them around the rows.
- Give the rows an
overflow:hidden
Like so: http://jsfiddle.net/39F88/
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>Teste</title>
<style type="text/css">
table{
table-layout:fixed;
width: 333px;
border-width: 1px;
border-spacing: 2px;
border-style: solid;
border-color: black;
border-collapse: collapse;
}
table th, table td
{
border-width: 1px;
padding: 1px;
border-style: solid;
border-color: black;
border-collapse: collapse;
}
table th.column1, table td.column1{
width:60px;
background-color:#CCD9FF;
}
table th.column2, table td.column2{
width:100px;
background-color:#ECFFE5;
}
table th.column3, table td.column3{
width:60px;
background-color:#FFEBE5;
}
table th.column4, table td.column4{
width:100px;
background-color: #FFFFCC;
}
div#tablecontainer
{
width:335px;
border-top:1px solid black;
background:url(http://i.stack.imgur.com/ZsO5U.png) TOP LEFT REPEAT-Y;
}
div.tablecontainerrow
{
clear:both;
overflow:hidden;
border:1px solid black;
border-top:none;
}
div#tablecontainer div div.column1
{
width: 62px;
float:left;
}
div#tablecontainer div div.column2
{
width: 104px;
float:left;
}
div#tablecontainer div div.column3
{
width: 62px;
float:left;
}
div#tablecontainer div div.column4
{
width: 104px;
float:left;
}
</style>
</head>
<body>
<h1>CSS and TABLE</h1>
<table>
<tr>
<th class="column1">Header 1</th>
<th class="column2">Header 2</th>
<th class="column3">Header 3</th>
<th class="column4">Header 4</th>
</tr>
<tr>
<td class="column1">line 1 column 1</td>
<td class="column2">line 1 column 2</td>
<td class="column3">line 1 column 3</td>
<td class="column4">line 2 column 4</td>
</tr>
<tr>
<td class="column1">line 2 column 1</td>
<td class="column2">line 2 column 2</td>
<td class="column3">line 2 column 3</td>
<td class="column4">line 2 column 4</td>
</tr>
<tr>
<td class="column1">line 3 column 1</td>
<td class="column2">line 3 column 2</td>
<td class="column3">line 3 column 3 (more content)</td>
<td class="column4">line 3 column 4</td>
</tr>
</table>
<h1>CSS and DIV</h1>
<div id="tablecontainer">
<div class="tablecontainerrow">
<div class="column1">Header 1</div>
<div class="column2">Header 2</div>
<div class="column3">Header 3</div>
<div class="column4">Header 4</div>
</div>
<div class="tablecontainerrow">
<div class="column1">line 1 column 1</div>
<div class="column2">line 1 column 2</div>
<div class="column3">line 1 column 3</div>
<div class="column4">line 1 column 4</div>
</div>
<div class="tablecontainerrow">
<div class="column1">line 2 column 1</div>
<div class="column2">line 2 column 2</div>
<div class="column3">line 2 column 3</div>
<div class="column4">line 2 column 4</div>
</div>
<div class="tablecontainerrow">
<div class="column1">line 3 column 1</div>
<div class="column2">line 3 column 2</div>
<div class="column3">line 3 column 3 (more content)</div>
<div class="column4">line 3 column 4</div>
</div>
</div>
</body>
</html>
Using tables to layout pages is not very professional but using tables to display tables is perfectly ok - this is for what they should be used. Emulating tables using divs and css is taking css layouting way too far.
This is a horrid answer, I can't believe I'm even suggesting it, BUT, if you are hell bent on making a table out of divs...
As is stated in the comments, if it is a table, use a table, tables are not evil, they were just overused at one time to do things they weren't designed for. They are designed to display tabular data so if you can, use them.
This is only suggested if you MUST make a table with divs
There is a little known display property in CSS to help you with this, read here: table-cell css.
Again, just use a table, if you can.
If you are presenting tabular data (multiple attributes of multiple similar entities, aka tabular data), use a <table>
tag
div#tablecontainer
{
width: 328px;
display:table;
}
div.tablecontainerrow
{
display:table-row;
}
div.tablecontainerrow div{
display:table-cell;
vertical-align:middle;
}
Of course, I think most current browsers handle this, except for MSIE...
As far as I know, the only way to get around this is to explicitly set the height of your 'columns', otherwise the divs will default to height:auto, and will only be as big as the content within them. Setting the height can be dangerous if you have content that requires more space than the height will allow.
Super annoying problem, just came up at work. I usually use an background to solve this problem but since everything needs to be responsive now it is annoying to make images for each Media Query. This is the only time I would use JavaScript to achieve what I want. Stupid that it is not supported.
HTML:
<ul class="table-layout clearfix">
<li>
<p>Header 1</p>
<p>Header 1</p>
<p>Header 1</p>
<p>Header 1</p>
<p>Header 1</p>
<p>Header 1</p>
</li>
<li>
<p>Header 1</p>
</li>
<li>
<p>Header 1</p>
</li>
</ul>
JavaScript:
$(document).ready(function(){
var height = 0;
$(".table-layout li").each(function(i){
if($(this).height() > height)
height = $(this).height();
});
$(".table-layout li").css("height", height + 'px');
});
CSS:
/**
* Markup free clearing.
*
* @see http://perishablepress.com/press/2009/12/06/new-clearfix-hack
*/
.clearfix:after {
content: ".";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
/* IE6 */
* html .clearfix {
height: 1%;
}
/* IE7 */
*:first-child + html .clearfix {
min-height: 1%;
}
ul, li{
margin:0;
padding:0;
list-style-type:none;
}
ul{
width:335px;
overflow:hidden;
}
ul li{
width: 31.5%;
float:left;
border:1px solid #000;
margin-right:4px;
}
http://jsfiddle.net/kXrn5/6/
Here's my attempt. It's probably not perfect, but it's a start. For me, It's working on the newest Chrome, Firefox, Safari, Opera, IE10, and IE9. Sorry, I don't have an IE7 to test with. I doubt it works, as IE7 was hard to deal with.
http://jsfiddle.net/nluis3294/uLuof882/
I think we all agree that you should use tables for tabular data, and divs for non-tabular data. In the ideal world, I think that's what everyone would do.
However, it's also ok to say that I want my non-tabular data to be aligned in a grid and that those rows and columns should stretch like a regular html table. That's a design choice, and it's totally legitimate. That is where the difficulties lie. You can use tables, which are much easier, but technically wrong. Or, you can use divs, and have to rely on tricks like background images, and faux columns, and spacers to get it to look like tables.
Using faux columns doesn't seem "correct" to me either. If you want to change the width of a column, you'd need to edit the background image. And using a background image to set background color seems weird to me. I have similar reservations about other tricks such as Psuedo columns, or tricks regarding negative margins. In my oppinion, they should just change the css to allow a simple way to get something that looks like a grid without tricks.
<div class="testTable">
<div class="testRow">
<div class="testColumn1">
aa
</div>
<div class="testColumn2">
bb<br/>
bbb2
</div>
<div class="testColumn3">
cc<br/>
cccc2
</div>
<div class="testColumn4">
dddddd<br/>
dddddd
</div>
</div>
<div class="testRow">
<div class="testColumn1">
aa
</div>
<div class="testColumn2">
bb<br/>
bbb2
</div>
<div class="testColumn3">
cc<br/>
cccc2
</div>
<div class="testColumn4">
dddddd<br/>
dddddd
</div>
</div>
<div class="testRow">
<div class="testColumn1">
aaa aaa
</div>
<div class="testColumn2">
bb<br/>
bbb2<br/>
bbbbbbbbbbbbbbbbbbbb3
</div>
<div class="testColumn3">
cccccc<br/>
</div>
<div class="testColumn4">
ddddd<br/>
ddd
</div>
</div>
</div>
CSS:
div.testTable{
width: 30%; display: table; table-layout: auto;
padding:0;
margin:0;
}
div.testRow{
display: table-row; width: 100%;
white-space: nowrap;
vertical-align:top;
padding:0;
margin:0;
}
div.testColumn1{
display: table-cell; height:100%; min-width: 25%; background-color: #CCD9FF;
vertical-align:top;
padding: 0.2em;
border: 1px solid black;
margin:0;
}
div.testColumn2{
display: table-cell; height:100%; min-width: 25%;background-color: #ECFFE5;
vertical-align:top;
padding: 0.2em;
border: 1px solid black;
margin:0;
}
div.testColumn3{
display: table-cell; height:100%; min-width: 25%;background-color: #FFEBE5;
vertical-align:top;
padding: 0.2em;
border: 1px solid black;
margin:0;
}
div.testColumn4{
display: table-cell; height:100%; min-width: 25%;background-color: #FFFFCC;
vertical-align:top;
padding: 0.2em;
border: 1px solid black;
margin:0;
}
精彩评论