Highlight rows with rowspan - html

I wish to highlight rows in html tables while using rowspans when hovering over a row. I'd prefer that to be implementable with CSS only with minimal or no javascript.
Right now the Table row gets highlighted, but when having a 'sub' row it highlights only that instead of the row it's visually a 'part' of.
table {
width: 100%;
}
.topLevelRow td {
border-top:double 3px silver;
}
td {
border-top:solid 1px silver;
}
tr:hover {
background-color:lightgray;
}
<html>
<head></head>
<body>
<table>
<tr class="topLevelRow">
<td rowspan="3">1</td>
<td rowspan="3">Text 1</td>
<td>Sub A 1</td>
<td>Sub B 1</td>
</tr>
<tr><td>Sub A 2</td><td>Sub B 2</td></tr>
<tr><td>Sub A 3</td><td>Sub B 3</td></tr>
<!-- . -->
<tr class="topLevelRow">
<td rowspan="5">2</td>
<td rowspan="5">Text 2</td>
<td>Sub A 1</td>
<td rowspan="1">Sub B 1</td>
</tr>
<tr><td rowspan="1">Sub A 2</td><td rowspan="1">Sub B 2</td></tr>
<tr><td rowspan="1">Sub A 3</td><td rowspan="1">Sub B 3</td></tr>
<tr><td rowspan="1">Sub A 4</td><td rowspan="1">Sub B 4</td></tr>
<tr><td rowspan="1">Sub A 5</td><td rowspan="1">Sub B 5</td></tr>
</table>
</body>
</html>
As you can see it only highlights part of the rows. How can I highlight all of it?

You can use multiple <tbody> elements to define areas on your table. In this case you have one <table> element with some groups of rows. Using multiple <tbody> elements in <table> element is also valid HTML5.
table {
width: 100%;
}
td {
border-top: 1px solid silver;
}
tbody tr:nth-child(1) td {
border-top: 3px double silver;
}
tbody:hover tr {
background-color: lightgray;
}
<html>
<head></head>
<body>
<table>
<tbody>
<tr>
<td rowspan="3">1</td>
<td rowspan="3">Text 1</td>
<td>Sub A 1</td>
<td>Sub B 1</td>
</tr>
<tr><td>Sub A 2</td><td>Sub B 2</td></tr>
<tr><td>Sub A 3</td><td>Sub B 3</td></tr>
</tbody>
<tbody>
<tr>
<td rowspan="5">2</td>
<td rowspan="5">Text 2</td>
<td>Sub A 1</td>
<td>Sub B 1</td>
</tr>
<tr><td>Sub A 2</td><td>Sub B 2</td></tr>
<tr><td>Sub A 3</td><td>Sub B 3</td></tr>
<tr><td>Sub A 4</td><td>Sub B 4</td></tr>
<tr><td>Sub A 5</td><td>Sub B 5</td></tr>
</tbody>
</table>
</body>
</html>

The easiest way would be to break the table after each block. This is the simplest way, but it depends, if your template engine (or what ever you are using) allows this.
table {
width: 100%;
}
table:hover {
background-color:lightgray;
}
.topLevelRow td {
border-top:double 3px silver;
}
td {
border-top:solid 1px silver;
}
<html>
<head></head>
<body>
<table>
<tr class="topLevelRow">
<td rowspan="3">1</td>
<td rowspan="3">Text 1</td>
<td>Sub A 1</td>
<td>Sub B 1</td>
</tr>
<tr><td>Sub A 2</td><td>Sub B 2</td></tr>
<tr><td>Sub A 3</td><td>Sub B 3</td></tr>
</table>
<!-- Break table here and start new one -->
<table>
<tr class="topLevelRow">
<td rowspan="5">2</td>
<td rowspan="5">Text 2</td>
<td>Sub A 1</td>
<td rowspan="1">Sub B 1</td>
</tr>
<tr><td rowspan="1">Sub A 2</td><td rowspan="1">Sub B 2</td></tr>
<tr><td rowspan="1">Sub A 3</td><td rowspan="1">Sub B 3</td></tr>
<tr><td rowspan="1">Sub A 4</td><td rowspan="1">Sub B 4</td></tr>
<tr><td rowspan="1">Sub A 5</td><td rowspan="1">Sub B 5</td></tr>
</table>
</body>
</html>

Related

How to make table with rowspan

I want to make table like this. A has 5row and B has 2.5row. I show another question about rowspan vlaue have to be integer. So I tried to revise totalrow is 6 and A is 6row , B is 3row, C is 1row and one is 2row. But I can't do like this image. If you can solve it, please talk to me.
Here's a basic example for you. You add the rowspan to the TD Tag and then on the subsequent rows, you have 1 less TD tag
table, tr, td { border:1px solid black; border-collapse: collapse }
<table>
<tr>
<td rowspan="2">Row Span 2</td>
<td>Normal Column</td>
</tr>
<tr>
<td>Normal Column</td>
</tr>
</table>
EDIT - Taking into account the fact that column B is 2.5 rows tall, and after review of the other answer, here is complete method, which uses both an extra table and rowspan
table, tr, td { border:1px solid black; border-collapse: collapse }
<html>
<body>
<table border=1 width=100% height=100%>
<tr>
<td rowspan="5">A</td>
<td rowspan="5" height=100%>
<table border=1 width=100% height="100%">
<tr>
<td>B1</td>
</tr>
<tr>
<td>B2</td>
</tr>
</table>
</td>
<td>C1</td>
</tr>
<tr>
<td>C2</td>
</tr>
<tr>
<td>C3</td>
</tr>
<tr>
<td>C4</td>
</tr>
<tr>
<td>C5</td>
</tr>
</table>
</body>
</html>

Avoid page break happening between two specific rows

This answer helps to avoid a page break inside a single row of a table, however I am looking for a way to prevent a page break from occurring between two different rows. Let me explain my situation (apologies for formatting):
header: | Col1 | Col2 | Col3 | Col4 |
row 1: | Val1 | Val2 | Val3 | Val4 |
row 2: | Value relating to 1,2,3,4 |
row 3: | Val5 | Val6 | Val7 | Val8 |
row 4: | Value relating to 5,6,7,8 |
I have a table in which every two rows are related to each other, and should not be shown on separate pages. The second row in each pair has a single value that should be able to span over all the columns of that row.
I have tried the following using page-break-inside: avoid:
Putting the two rows inside a <div> tag
Having Col4 span over both rows (Col4 content just moves to next page)
Putting both rows into a table (loses alignment with headings)
You should use multiple <tbody> tags instead of <div>. The property page-break-inside: avoid must be set on the <tbody>.
In a HTML table you can set only one <thead> and <tfoot>, but several <tbody>.
You could use nested tables, i.e. each of the td cells in your current rows 1 and 3 could contain a table consisting of 1 column and 2 rows with 1 cell each, with the cell in the second row containing the related value to the first row.
So your rows 1 and 2 would become one row with 4 cells, each containing a nested table consisting of 2 rows with 1 cell each. The same for your current rows 3 and 4 etc.
Then you could apply page-break-inside: avoid to these nested tables.
.maintable {
width: 100%;
border-collapse: collapse;
}
.maintable > tbody > tr > th, .maintable > tbody > tr > td {
border: 1px solid #ddd;
}
.maintable > tbody > tr > td > table {
page-break-inside: avoid;
width: 100%;
border-collapse: collapse;
}
.maintable > tbody > tr > td > table tr:first-child td {
border-bottom: 1px solid #ddd;
}
<table class="maintable">
<tr>
<th>Header 1</th>
<th>Header 2</th>
<th>Header 3</th>
<th>Header 4</th>
</tr>
<tr>
<td>
<table>
<tr>
<td>value 1</td>
</tr>
<tr>
<td>related value 1a</td>
</tr>
</table>
</td>
<td>
<table>
<tr>
<td>value 2</td>
</tr>
<tr>
<td>related value 2a</td>
</tr>
</table>
</td>
<td>
<table>
<tr>
<td>value 3</td>
</tr>
<tr>
<td>related value 3a</td>
</tr>
</table>
</td>
<td>
<table>
<tr>
<td>value 4</td>
</tr>
<tr>
<td>related value 4a</td>
</tr>
</table>
</td>
</tr>
<tr>
<td>
<table>
<tr>
<td>value 5</td>
</tr>
<tr>
<td>related value 5a</td>
</tr>
</table>
</td>
<td>
<table>
<tr>
<td>value 6</td>
</tr>
<tr>
<td>related value 6a</td>
</tr>
</table>
</td>
<td>
<table>
<tr>
<td>value 7</td>
</tr>
<tr>
<td>related value 7a</td>
</tr>
</table>
</td>
<td>
<table>
<tr>
<td>value 8</td>
</tr>
<tr>
<td>related value 8a</td>
</tr>
</table>
</td>
</tr>
</table>
<style type="text/css">
table{
border: 1px solid black;
border-collapse: collapse;
}
td{
border: 1px solid black;
}
</style>
<table style="border: 1px solid black">
<tr>
<td>value 1</td>
<td> value 2</td>
<td> value 3</td>
<td>value 4</td>
</tr>
<tr>
<td colspan="4"> Values ralted to 1, 2, 3, 4</td>
</tr>
</table>

Make 1 table look like 2 on top of each other

I want to make 1 table to look like 2 tables where they are on top of each other with a little space between them. Each table has the same number of columns, but the text they contain can differ. And each table can contain many rows. I need this because i need columns of both tables always to be the same width. How do i achieve this? I need that Empty row's side borders to hide
<table>
<tr> <!-- First table rows --> </tr>
<td>text</td>
<td>text</td>
<tr> <!-- Empty space between tables --> </tr>
<tr> <!-- Second table rows --> </tr>
<td>text</td>
<td>text</td>
Just use a single <td> element with a specific height as a separator, and use border-collapse to mimic what you're looking for:
table {
border-collapse: collapse;
}
table td {
border: 1px solid #000;
}
table td.separator {
border: none;
height: 40px;
}
<table>
<tr>
<td>text</td>
<td>text</td>
</tr>
<tr>
<td>text</td>
<td>text</td>
</tr>
<tr>
<td colspan="2" class="separator"></td>
</tr>
<tr>
<td>text</td>
<td>text</td>
</tr>
<tr>
<td>text</td>
<td>text</td>
</tr>
</table>
You can use css for this. border-spacing
Change 45px for sizing
table {
border-collapse: collapse;
}
th {
background-color: red;
Color:white;
}
th, td {
width:150px;
text-align:center;
border:1px solid black;
padding:5px
}
.geeks {
border-right:hidden;
}
.gfg {
border-collapse:separate;
border-spacing:0 45px;
}
h1 {
color:green;
}
<!DOCTYPE html>
<html>
<head>
<style>
</style>
</head>
<body>
<center>
<h2>Row spacing in a table</h2>
<table>
<tr>
<th>Employee ID</th>
<th>Name</th>
<th>Gender</th>
<th>Age</th>
</tr>
</table>
<table class = "gfg">
<tr>
<td class = "geeks">10001</td>
<td>Thomas</td>
<td>M</td>
<td>32</td>
</tr>
<tr>
<td class = "geeks">10002</td>
<td>Sally</td>
<td>F</td>
<td>28</td>
</tr>
<tr>
<td class = "geeks">10003</td>
<td>Anthony</td>
<td>M</td>
<td>24</td>
</tr>
</table>
</center>
</body>
</html>
You could use something like shown below. The colspan="4" on table-spacing td specifies how many columns the cell should span.
Advice
However if the data is really different from each other I would recommend actually using two different tables instead of two . It make it easier for screen readers to distinct the data from each other. To improve this further you can use table headers to improve your accessibility even more.
Source: https://www.w3schools.com/tags/tag_thead.asp
.table {
border-collapse: collapse;
}
.table-spacing td {
border: none;
height: 15px; /* Increase/descrease for white-space between 'tables' */
}
td {
padding: 6px;
border: 1px solid black;
}
<table class="table">
<tr>
<td> Cel 1</td>
<td> Cel 2</td>
<td> Cel 3</td>
<td> Cel 4</td>
<tr>
<tr>
<td> Cel 5</td>
<td> Cel 6</td>
<td> Cel 7</td>
<td> Cel 8</td>
<tr>
<tr class="table-spacing"><td colspan="4"></td></tr>
<tr>
<td> Cel 1</td>
<td> Cel 2</td>
<td> Cel 3</td>
<td> Cel 4</td>
<tr>
<tr>
<td> Cel 5</td>
<td> Cel 6</td>
<td> Cel 7</td>
<td> Cel 8</td>
<tr>
</table>

Multiple row span in HTML data

I am trying to create a table similar to the one shown in the attached screenshot. Data for this table is coming through the python script, but I need some inputs on HTML side on how to create a table that can span through multiple rows
With my little knowledge on HTML, I tried creating the table with the following code, but it doesn't appear like its working as expected. It would be highly helpful if anyone can throw some light on what could be wrong here
table,
td,
th {
font-family: Verdana;
border: 2px solid black;
}
table {
border-collapse: collapse;
width: 100%;
}
th {
background-color: green;
color: white;
}
th,
tr {
height: 50px;
}
td {
font-family: Verdana;
font-size: 15pt;
text-align: center;
}
body {
background-color: lightgreen
}
<table style="width:100%">
<table>
<tr>
<th>Project</th>
<th>Environment</th>
<th>Data1</th>
<th>Multiple Data</th>
</tr>
<tr>
<td rowspan="4">project1</td>
<td rowspan="4">prod</td>
<td rowspan="4">project1data</td>
<td rowspan="4">project1 multi row data1</td>
<td rowspan="4">project1 multi row data2</td>
</tr>
<tr>
<td rowspan="4">project2</td>
<td rowspan="4">stage</td>
<td rowspan="4">project2data</td>
<td rowspan="4">project2 multi row data1</td>
<td rowspan="4">project2 multi row data2</td>
</tr>
<tr>
<td rowspan="4">project3</td>
<td rowspan="4">test</td>
<td rowspan="4">project3data</td>
<td rowspan="4">project3 multi row data1</td>
<td rowspan="4">project3 multi row data2</td>
</tr>
<tr>
<td rowspan="4">project4</td>
<td rowspan="4">dev</td>
<td rowspan="4">project4data</td>
<td rowspan="4">project4 multi row data1</td>
<td rowspan="4">project4 multi row data2</td>
</tr>
<tr>
<td rowspan="4">project5</td>
<td rowspan="4">qa</td>
<td rowspan="4">project5data</td>
<td rowspan="4">project5 multi row data1</td>
<td rowspan="4">project5 multi row data2</td>
</tr>
</table>
The mistake is that you have rowspan="4" even in the last td. You will need to avoid a rowspan there:
<table>
<tr>
<th>Project</th>
<th>Environment</th>
<th>Data1</th>
<th>Multiple Data</th>
</tr>
<tr>
<td rowspan="3">project1</td>
<td rowspan="3">prod</td>
<td rowspan="3">project1data</td>
<td>project1 multi row data1</td>
</tr>
<tr>
<td>project1 multi row data2</td>
</tr>
<tr>
<td>project1 multi row data3</td>
</tr>
<tr>
<td rowspan="3">project2</td>
<td rowspan="3">stage</td>
<td rowspan="3">project2data</td>
<td>project2 multi row data1</td>
</tr>
<tr>
<td>project2 multi row data2</td>
</tr>
<tr>
<td>project2 multi row data3</td>
</tr>
<tr>
<td rowspan="3">project3</td>
<td rowspan="3">test</td>
<td rowspan="3">project3data</td>
<td>project3 multi row data1</td>
</tr>
<tr>
<td>project3 multi row data2</td>
</tr>
<tr>
<td>project3 multi row data3</td>
</tr>
<tr>
<td rowspan="3">project4</td>
<td rowspan="3">dev</td>
<td rowspan="3">project4data</td>
<td>project4 multi row data1</td>
</tr>
<tr>
<td>project4 multi row data2</td>
</tr>
<tr>
<td>project4 multi row data3</td>
</tr>
<tr>
<td rowspan="3">project5</td>
<td rowspan="3">qa</td>
<td rowspan="3">project5data</td>
<td>project5 multi row data1</td>
</tr>
<tr>
<td>project5 multi row data2</td>
</tr>
<tr>
<td>project5 multi row data3</td>
</tr>
</table>
Please check this :
Basically you can use simple <div> inside the td to accomplish this for 3rd table column.
https://jsfiddle.net/ryb0w54a/
table { border:1px solid #000;border-collapse:collapse;}
th {border:1px solid #000;}
td { border:1px solid #000;}
div { border-bottom : 1px solid #000}
div.last { border-bottom : 0;}
<table>
<th>Project</th>
<th>Environment</th>
<th>Data1</th>
<th>Multiple Data</th>
<tr>
<td>Project 1</td>
<td>Env 1</td>
<td>Project 1 Data</td>
<td>
<div>project1 multi row data1</div>
<div>project1 multi row data2</div>
<div class="last">project1 multi row data3</div>
</td>
</tr>
<tr>
<td>Project 1</td>
<td>Env 1</td>
<td>Project 1 Data</td>
<td>
<div>project1 multi row data1</div>
<div>project1 multi row data2</div>
<div class="last">project1 multi row data3</div>
</td>
</tr>
</table>
remove rowspan=4 for your multiple data column and add them to another <tr> with rowspan=1 after relative no. of empty divs.
I think this will help you what you require
table,
td,
th {
font-family: Verdana;
border: 2px solid black;
}
table {
border-collapse: collapse;
width: 100%;
}
th {
background-color: green;
color: white;
}
th,
tr {
height: 50px;
}
td {
font-family: Verdana;
font-size: 15pt;
text-align: center;
}
body {
background-color: lightgreen
}
<table>
<thead>
<tr>
<th>Project</th>
<th>Environment</th>
<th>Data</th>
<th>Multiple Data</th>
</tr>
</thead>
<tbody>
<tr>
<td>A1</td>
<td>A2</td>
<td>A3</td>
<td>
<table>
<tbody>
<tr>
<td>B1</td>
</tr>
<tr>
<td>B2</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
Your approach was correct but the way you implemented it has a small mistake. I think this code will give you the proper way to address your problem. The code is pretty basic but will help you to understand how it works.
<table>
<thead>
<tr>
<th>Head 1</th>
<th>Head 2</th>
<th>Head 3</th>
</tr>
</thead>
<tbody>
<tr>
<td rowspan="4">Data 1</td>
<td rowspan="4">Data 2</td>
</tr>
<tr>
<td>Data 2.1</td>
</tr>
<tr>
<td>Data 2.1</td>
</tr>
<tr>
<td>Data 2.1</td>
</tr>
</tbody>
</table>
You can do this simply without using rowspan and just adding another table in the last td where the multiple rows will come.
Here we go :
table,
td,
th {
font-family: Verdana;
border: 2px solid black;
}
table {
border-collapse: collapse;
width: 100%;
}
th {
background-color: green;
color: white;
}
th,
tr {
height: 50px;
}
td {
font-family: Verdana;
font-size: 15pt;
text-align: center;
}
body {
background-color: lightgreen
}
table tr td table {
border: none;
}
table tr td table td {
border-left: none;
border-right: none;
}
table tr td table tr:first-child td {
border-top: none;
}
table tr td table tr:last-child td {
border-bottom: none;
}
<table>
<tr>
<th>Project</th>
<th>Environment</th>
<th>Data1</th>
<th>Multiple Data</th>
</tr>
<tr>
<td>project1</td>
<td>prod</td>
<td>project1data</td>
<td>
<table>
<tr>
<td>project1 multi row data2</td>
</tr>
<tr>
<td>project1 multi row data2</td>
</tr>
<tr>
<td>project1 multi row data2</td>
</tr>
<tr>
<td>project1 multi row data2</td>
</tr>
</table>
</td>
</tr>
<tr>
<td>project2</td>
<td>prod</td>
<td>project1data</td>
<td>
<table>
<tr>
<td>project1 multi row data2</td>
</tr>
<tr>
<td>project1 multi row data2</td>
</tr>
<tr>
<td>project1 multi row data2</td>
</tr>
<tr>
<td>project1 multi row data2</td>
</tr>
</table>
</td>
</tr>
<tr>
<td>project3</td>
<td>prod</td>
<td>project1data</td>
<td>
<table>
<tr>
<td>project1 multi row data2</td>
</tr>
<tr>
<td>project1 multi row data2</td>
</tr>
<tr>
<td>project1 multi row data2</td>
</tr>
<tr>
<td>project1 multi row data2</td>
</tr>
</table>
</td>
</tr>
</table>

How to put spacing between TBODY elements

I have a table like this:
<table>
<tfoot>
<tr><td>footer</td></tr>
</tfoot>
<tbody>
<tr><td>Body 1</td></tr>
<tr><td>Body 1</td></tr>
<tr><td>Body 1</td></tr>
</tbody>
<tbody>
<tr><td>Body 2</td></tr>
<tr><td>Body 2</td></tr>
<tr><td>Body 2</td></tr>
</tbody>
<tbody>
<tr><td>Body 3</td></tr>
<tr><td>Body 3</td></tr>
<tr><td>Body 3</td></tr>
</tbody>
</table>
I'd like to put some spacing between each tbody element, but padding and margin have no effect. Any ideas?
Something like this will work, depending on your browser support requirements:
tbody::before
{
content: '';
display: block;
height: 15px;
}
Try this, if you don't mind not having borders.
<style>
table {
border-collapse: collapse;
}
table tbody {
border-top: 15px solid white;
}
</style>
<table>
<tfoot>
<tr><td>footer</td></tr>
</tfoot>
<tbody>
<tr><td>Body 1</td></tr>
<tr><td>Body 1</td></tr>
<tr><td>Body 1</td></tr>
</tbody>
<tbody>
<tr><td>Body 2</td></tr>
<tr><td>Body 2</td></tr>
<tr><td>Body 2</td></tr>
</tbody>
<tbody>
<tr><td>Body 3</td></tr>
<tr><td>Body 3</td></tr>
<tr><td>Body 3</td></tr>
</tbody>
</table>
People will always have controversial opinions about using empty table elements to layout a page (as evidenced by this answer's downvote). I recognize this, but sometimes its easier to use them this way when you are working in a "quick and dirty" way.
I've used empty rows in past projects to space groups of table rows. I assigned the spacer rows a css class of their own and defined a height for that class that acted as a top and bottom margin for that group of table rows.
.separator{
height: 50px;
}
<table>
<tr><td>Cell 1</td><td>Cell 2</td></tr>
<tr><td>Cell 1</td><td>Cell 2</td></tr>
<tr><td>Cell 1</td><td>Cell 2</td></tr>
<tr class="separator" colspan="2"></tr>
<tr><td>Cell 1</td><td>Cell 2</td></tr>
<tr><td>Cell 1</td><td>Cell 2</td></tr>
<tr><td>Cell 1</td><td>Cell 2</td></tr>
<tr class="separator" colspan="2"></tr>
tr><td>Cell 1</td><td>Cell 2</td></tr>
<tr><td>Cell 1</td><td>Cell 2</td></tr>
<tr><td>Cell 1</td><td>Cell 2</td></tr>
</table>
If you don't have borders on your table cells, you could also define a height to your typical cell or row in your style sheet that evenly spaces out all rows of your table.
tr{
height: 40px;
}
I had been having trouble with cross-browser support for spacing multiple <tbody>'s using the ::before pseudo-selector if any <td>'s had a rowspan.
Basically, if your <tbody> is structured like this:
<tbody>
<tr>
<td>td 1</td>
<td rowspan"2">td 2</td>
<td>td 3</td>
<td>td 4</td>
</tr>
<tr>
<td>td 1</td>
<td>td 2</td>
<td>td 4</td>
</tr>
</tbody>
...and your ::before pseudo-selector displays the content as a block like this:
tbody::before
{
content: '';
display: block;
height: 10px;
}
...then this will cause the table to cut off any columns that use rowspan.
The solution is to style ::before pseudo as a table-row:
tbody::before
{
content: '';
display: table-row;
height: 10px;
}
This should have good cross-browser support.
Here's a fiddle
Here's another possibility that relies on :first-child which is not available in all browsers:
<style>
table {
border-collapse: collapse;
}
td {
border: 1px solid black;
}
tbody tr:first-child td {
padding-top: 15px;
}
</style>
<table>
<tfoot>
<tr><td>footer</td></tr>
</tfoot>
<tbody>
<tr><td>Body 1</td></tr>
<tr><td>Body 1</td></tr>
<tr><td>Body 1</td></tr>
</tbody>
<tbody>
<tr><td>Body 2</td></tr>
<tr><td>Body 2</td></tr>
<tr><td>Body 2</td></tr>
</tbody>
<tbody>
<tr><td>Body 3</td></tr>
<tr><td>Body 3</td></tr>
<tr><td>Body 3</td></tr>
</tbody>
</table>
Just set display as block and it will work.
table tbody{
display:block;
margin-bottom:10px;
border-radius: 5px;
}
Of all of the answers given above, only djenson47's answers retain separation of presentation and content. The drawback of the collapsed border model method is that you can no longer use the table's border or cellspacing attributes to separate the individual cells. You could argue that this is a good thing, and there are some workarounds, but it can be a pain. So I think the first-child method is the most elegant.
Alternatively, you could also set your TBODY class' overflow property to anything other than "visible." This method allows you to retain a separated borders model as well:
<style>
tbody {
overflow: auto;
border-top: 1px solid transparent;
}
</style>
<table>
<tfoot>
<tr><td>footer</td></tr>
</tfoot>
<tbody>
<tr><td>Body 1</td></tr>
<tr><td>Body 1</td></tr>
<tr><td>Body 1</td></tr>
</tbody>
<tbody>
<tr><td>Body 2</td></tr>
<tr><td>Body 2</td></tr>
<tr><td>Body 2</td></tr>
</tbody>
<tbody>
<tr><td>Body 3</td></tr>
<tr><td>Body 3</td></tr>
<tr><td>Body 3</td></tr>
</tbody>
</table>
You can use border-spacing in a table with table row groups to add a space between those groups. Though, I don't think there is a way to specify which groups are spaced and which are not.
<table>
<thead>
...
</head>
<tbody>
...
</tbody>
<tbody>
...
</tbody>
<tfoot>
...
</tfoot>
</table>
CSS
table {
border-spacing: 0px 10px; /* h-spacing v-spacing */
}
Because padding can be applied to TD's, you can do a trick with the + sign. Then it will be possible to give a top padding to the TD's of the first TR of a tbody:
// The first row will have a top padding
table tbody + tbody tr td {
padding-top: 20px;
}
// The rest of the rows should not have a padding
table tbody + tbody tr + tr td {
padding-top: 0px;
}
I have added the "tbody + tbody" so the first tbody won't have a top padding. However, it's not required.
As far as I know there are no drawbacks :), though didn't test the older browsers.
NEW ANSWER
You can use as many <tbody> tags as you like. I didn't realize that was ok by W3C until now. Not to say my below solution doesn't work (it does), but to do what you're trying to do, assign your <tbody> tags classes and then reference their individual <td> tags through CSS like so:
table tbody.yourClass td {
padding: 10px;
}
and your HTML thusly:
<table>
<tbody>
<tr><td>Text</td></tr>
<tr><td>Text</td></tr>
<tr><td>Text</td></tr>
</tbody>
<tbody class="yourClass">
<tr><td>Text</td></tr>
<tr><td>Text</td></tr>
<tr><td>Text</td></tr>
</tbody>
<tbody>
<tr><td>Text</td></tr>
<tr><td>Text</td></tr>
<tr><td>Text</td></tr>
</tbody>
</table>
Try that guy out :)
OLD ANSWER
whatever you do, DON'T insert blank rows...
you shouldn't have more than 1 tbody element in your table. what you can do is set the class or id attribute in your <tr> elements and give their corresponding <td> tags padding:
table {
border-collapse: collapse;
}
tr.yourClass td {
padding: 10px;
}
You can even assign the top and bottom <tr>'s an additional class so that they only do top or bottom padding, respectively:
tr.yourClass.topClass td {
padding: 10px 0 0 0;
}
tr.yourClass.bottomClass td {
padding: 0 0 10px 0;
}
and in your HTML, your <tr> tag would look like this:
<table>
<tbody>
<tr><td>Text</td></tr>
<tr><td>Text</td></tr>
<tr><td>Text</td></tr>
<tr class="yourClass topClass"><td>Text</td></tr>
<tr class="yourClass"><td>Text</td></tr>
<tr class="yourClass bottomClass"><td>Text</td></tr>
<tr><td>Text</td></tr>
<tr><td>Text</td></tr>
<tr><td>Text</td></tr>
</tbody>
</table>
Hope this helps!
djensen47 answer works great for newer browsers, however, as it was pointed out, IE7 it does not work in.
My workaround for this issue to support the older browsers was to wrap each cells contents inside a div. Then add a margin-top to the div.
<table class="tbl">
<tr></tr>
<tr></tr>
<tr></tr>
<tr><td><div></div></td></tr>
</table>
CSS
.tbl tr td div {
height:30px;
margin-top:20px;
}
The height setting keeps the cells at least 30px high to prevent any cell coloring used inside the div from collapsing around the text. The margin-top creates the desired space by making the entire row taller.
Came across this while trying to solve it myself. I had success with putting a <br> tag right before the closing </tbody> tag. It is a purely visual fix, but seems to work on most browsers I tested.
<table>
<tbody>
<tr>
<td></td>
</tr>
<br>
</tbody>
<tbody>
<tr>
<td></td>
</tr>
</tbody>
</table>
Should be accessible as well.
With credit to everyone else who answered first ...
table {
border-collapse: collapse;
table-layout: fixed;
width: 50%;
}
tbody:before {
content: "";
display:block;
border-top: 15px solid white;
}
tbody tr {
border-color: #000;
border-style: solid;
}
tbody tr:first-of-type{
border-width: 2px 2px 0 2px;
}
tbody tr:nth-of-type(1n+2){
border-width: 0 2px 0 2px;
}
tbody tr:last-of-type{
border-width: 0 2px 2px 2px;
}
tbody tr:nth-child(odd) {
background-color: #ccc;
}
tbody tr:hover {
background-color: #eee;
}
td {
text-align: right;
}
<table>
<tbody>
<tr>
<th colspan="3">One</th>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
</tbody>
<tbody>
<tr>
<th colspan="3">Two</th>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
</tbody>
</table>