HTML Table Alternating Row THBody Usage - html

I have several html tables in my content area of my page. The style is weird because it doesn't start the alternating row color fresh at the start of each table, it carries it on through out the list of tables.
<table>
<tr>
Blue
</tr>
<tr>
White
</tr>
<tr>
Blue
</tr>
</table>
<table>
<tr>
White
</tr>
<tr>
Blue
</tr>
<tr>
White
</tr>
</table>
The colour in the rows is a representation of what the css would set as the row background. But I want css to start the alternating again for the next table. So it would be:
<table>
<tr>
Blue
</tr>
<tr>
White
</tr>
<tr>
Blue
</tr>
</table>
<table>
<tr>
Blue
</tr>
<tr>
White
</tr>
<tr>
Blue
</tr>
</table>
Does THBODY have anything to do with it?
Thanks,
CSS Code
table { border-collapse:collapse; text-align:center; }
table th, td { border:1px solid #759EC7; padding:3px 7px 2px; }
th { color: #fff;
background-color: #5c87b2; text-align:center; }
tr:nth-child(odd) { background-color: #CEE1F5; }
tr:nth-child(even) { background-color: #fff; }
Update
It may be a bug that has crept in, I've look on the suggested fiddles and it works perfectly so it is just some buggy code somewhere.

You can easily achieve it using combinations of :nth-child() by passing even and odd values. For eg. see this fiddle.
where, the CSS is
body {
background-color: black;
color: red;
}
table tr:nth-child(odd) {
background-color: blue;
}
table tr:nth-child(even) {
background-color: #ffffff;
}

The only problem you have is missing the tag in the table.
It works perfectly if you add it. It shouldnt have anything to do with the tbody tag.
<table>
<tr>
<td>Blue</td>
</tr>
<tr>
<td>White</td>
</tr>
<tr>
<td>Blue</td>
</tr>
</table>
<table>
<tr>
<td>Blue</td>
</tr>
<tr>
<td>White</td>
</tr>
<tr>
<td>Blue</td>
</tr>
</table>
here is the fiddle: http://jsfiddle.net/rBwBm/

I think you're doing it using javascript, right ? Probably getting a collection of tr through jquery with $('tr') ? Try using CSS nth-child(odd) and nth-child(even) instead, most modern browsers won't have any problem with that.

The issue I was having was with two <TH> rows, which through off the alternating row colouring. So for example:
<tr>
<th colpsan="2">Name</th>
</tr>
<tr>
<th>First</th>
<th>Last</th>
</tr>
This would have the Blue start on the Name row and then start alternating. So the first line of the table body would be Blue
<tr>
<th>Name</th>
</tr>
This would have the Blue start on the Name row like before and then start alternating, However, the first line of the table body would be White
In these situations it would show a changing style which is not what I wanted to achieve. So all I did to fix this is:
<thead>
<tr>
<th colpsan="2">Name</th>
</tr>
<tr>
<th>First</th>
<th>Last</th>
</tr>
</thead>
<tbody>
<!-- Table Content in Here -->
</tbody>
And I then changed the style sheet to be:
tbody tr:nth-child(odd) {}
tbody tr:nth-child(even) {}
So basically I used the TBody and THead tags to make a more specific css style which is brilliant. More control, flexibility. So in my new example, you can have as many rows in the THead as you like, the content should always start on White, and to answer my question:
Does THead have anything to do with it?
Yes, it has EVERYTHING to do with it.

Related

How to override a specific table border CSS style while using Bootstrap table formatting

I'm using Bootstrap with tables, and trying to make some minor overrides to the default CSS with limited success.
In the table below, I'm able to add a dark border at the bottom of the table head (thead), and to the bottom of the table rows in the footer (tr in tfoot), but I cannot add a border to the bottom of the last table row (tr:last-child), or alternately the bottom of the table body (tbody), or I suppose the top of the table footer (tfoot).
I've had limited success with this:
.table-sm.event-table tbody > tr:last-child {
border-bottom: 2px solid #999;
}
However this doesn't render in all browsers, and only 'works' by making the single pixel light grey line a 2 pixel dark line, which I don't want, I just want a single pixel dark border between the last row of the body and the first row of the footer (between Row Two and Total Expense).
I know this has to do with the specificity of the CSS rules, and Bootstrap's rule taking precedent over my own, but even though I was able to make the other rules work, I cannot for the life of me figure out how to specify this one.
.event-table {
width: 100%;
}
.table thead > tr > th {
border-bottom: 1px solid #333;
}
.table tfoot > tr > td {
border-bottom: 1px solid #333;
}
<table class="table table-bordered table-sm event-table">
<thead>
<tr>
<th>Unit</th>
<th>Total</th>
</tr>
</thead>
<tfoot>
<tr>
<td>Total Expense $</td>
<td class="text-right">$200</td>
</tr>
<tr>
<td>Total Revenue $</td>
<td class="text-right">$300</td>
</tr>
</tfoot>
<tbody>
<tr>
<td>Row One</td>
<td>$100</td>
</tr>
<tr>
<td>Row Two</td>
<td>$100</td>
</tr>
</tbody>
</table>
Specificity is the name of the game and if you deal with Bootstrap, you'll quickly learn that it get's very complicated and even nigh impossible. While using #ids and !important may be an immediate remedy to your situation, it will bite you in the #rse if they are used even if only moderately. Try using only a few #id if you must and avoid !important at all costs.
A safer solution is to double up on a class:
As a nonsense special case for (2), duplicate simple selectors to increase specificity when you have nothing more to specify.
MDN - The !important exception
The following demo has each table section (i.e. <thead>, <tbody>, and <tfoot>) with it's last row border-bottom a different color. Note that the bootstrap.css file is loaded as well, so it does work to the best of my knowledge and evidence at hand.
Demo
.event-table {
width: 100%;
}
.table thead>tr.rowA1.rowA1>th {
border-bottom: 1px solid red;
}
.table tbody>tr.rowB2.rowB2>td {
border-bottom: 1px solid lime;
}
.table tfoot>tr.rowC2.rowC2>td {
border-bottom: 1px solid blue;
}
<link rel='stylesheet' href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css'>
<table class="table table-bordered table-sm event-table">
<thead>
<tr class='rowA1'>
<th>Unit</th>
<th>Total</th>
</tr>
</thead>
<tbody>
<tr class='rowB1'>
<td>Row One</td>
<td>$100</td>
</tr>
<tr class='rowB2'>
<td>Row Two</td>
<td>$100</td>
</tr>
</tbody>
<tfoot>
<tr class='rowC1'>
<td>Total Expense $</td>
<td>$200</td>
</tr>
<tr class='rowC2'>
<td>Total Revenue $</td>
<td>$300</td>
</tr>
</tfoot>
</table>
Give your tags an id instead of a class. This way, when you go to style the certain element with the id in your css, it will be at a higher priority than the Bootstrap style, which would erase the need for !important in most cases
So say you add an id to your table tag in the html like so
<table class="table table-bordered table-sm event-table" id="main-table">
You should be able to do this with success
#main-table {
width: 100%;
}
#main-table thead > tr > th, #main-table tfoot > tr > td {
border-bottom: 1px solid #333;
}
Sometimes you will have to use !important to override Bootstrap styles like so
border-bottom: 2px solid #999 !important;

Table styling with CSS

I made a simple HTML table for this question.
I want to have a different style for the text and a different one for the numbers in the <td> and in the <tfoot>.
Can I style text differently from numbers in <td> and the <tfoot>?
and
What is the best way in the web practice to style a more complex table?
Update
Like this?
<td> 12<b>x</b>6 </td>
Here is my fiddle.
HTML
<table>
<caption>Woah</caption>
<thead>
<tr>
<th></th>
<th>Animalistic</th>
<th>People</th>
</tr>
</thead>
<tfoot>
<td>Run</td>
<td>1 x 92</td>
<td>1 x 92</td>
</tfoot>
<tbody>
<tr>
<td>John</td>
<td>9889 x 92</td>
<td>9889 x 92</td>
</tr>
</tbody>
<tbody>
<tr>
<td>Bill</td>
<td>9889 x 92</td>
<td>9889 x 92</td>
</tr>
</tbody>
</table>
CSS
table {
width:300px;
background:#f5f7f3;
}
caption {
background:#000;
color:#fff;
}
th {
border:1px solid #000;
height:40px;
background:#b2b2b2;
}
td {
border:1px solid #b2b2b2;
}
add a < span > tag to the text with the style you want.
<td><span style="some style" or class = "some class"> some text </span></td>
You can't set different color for numeric value and text if they are in same tag. You have to give them separate tag. Like:
<td><span>1</span> text <span>92</span></td>
Then add css:
td span{
color:red;
}
Note: numeric values are in span tag and text value don't have any
tag. so with this css we can set color for numeric value and text
value different
There are numerous ways to target table elements. Here is an excellent list of available CSS selectors.
Example of the below.
Basic HTML structure (only one <tbody>):
<table>
<thead>
<tr>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td>9999 x 9999</td>
</tr>
</tbody>
<tfoot>
<tr>
<td></td>
</tr>
</tfoot>
</table>
To target the numbers separately, use a <span>:
<td>9999 <span>x</span> 9999</td>
OR
<td><span>9999</span> x <span>9999</span></td>
Target in the CSS with:
tbody td span {
/* styles */
}
Target every second row in the tbody with nth-child:
tbody tr:nth-child(even) {
background: #F00;
}
Target every td in the tbody:
tbody td {
text-align: center;
}
Target the first td of each row:
tbody td:first-child {
text-align: right;
}
Target the tfoot itself
tfoot {
background: #CCC;
}

Wrong CSS is generated when using rich:dataTable with nested rich:tooltip

I use Richfaces and have a rich:datatable with nested rich:tooltip-s.
You can imagine the generated HTML looks like this:
<table style="width: 400px; border: 3px solid #000; caption-side: bottom; border-collapse:collapse;">
<caption align="bottom">Table 1.1: A record of the fur shed annually by Jennifer's dog Shasta</caption>
<thead>
<tr>
<th>Month</th>
<th>Fur Shed (mm)</th>
</tr>
<thead>
<tbody style="background-color: #ff3;">
<tr>
<td>April</td>
<td>20</td>
</tr>
<tr>
<td>May</td>
<td>19</td>
</tr>
<tr>
<td>June</td>
<td>10</td>
</tr>
<tr>
<td>July</td>
<td>6</td>
</tr>
<tr>
<td>August</td>
<td>8</td>
</tr>
<tr>
<td>September</td>
<td>14</td>
</tr>
</tbody>
<tbody>
<tr>
<td style="display:none;">
<script type="text/javascript">
new RichFaces.ui.DataTable("form1:table1:0:j_idt227",{"ajaxEventOptions":{}} )
</script>
</td>
</tr>
The problem with this html is in the 2nd (generated from RF) tbody: td has style="display:none;" and in Google Chrome this causes the bottom border being not shown.
My question is: do you know if it is possible to find a workaround to fix this? Moving the display:none; at tr or tbody level would already be a solution.
Thanks!
You can add a footer to the table (<f:facet name="footer">) which will render under the hidden row but if you don't want to you can use this CSS:
table > tbody > tr:last-child {
border-bottom: 3px solid #000;
}
this will find the last row and add a border at the bottom, of course this will affect every table on your page so you should use some identifiers. Also note that the :last-child selector may not be supported by all browsers (it does work in Chrome).
Other alternative is to wrap the table in a div but you'd need to play a little with the CSS to make it look the way you want.

Html column group and title

What would be the html markup to achieve the same result as the first table in http://reference.sitepoint.com/css/tableformatting#tableformatting__tbl_table-objects-display-values
I am looking for how they specified the column group and how to set the title (Women, Men). Also, how to target the specific column group in css.
thanks,
bsr.
Good question. I sat down and reflected on the last time I addressed table formatting issues, then navigated to following links:
http://www.w3.org/TR/html4/struct/tables.html#h-11.2.4
http://www.w3.org/TR/CSS2/tables.html
After some meditation and drinking water, wrote some code for you to refer:
body {
background: #e4e4e4;
font-family: sans-serif;
}
th {
background: #d5d6d6;
}
td {
background: #fff;
}
table {
border-collapse: separate;
border-spacing: 1em 0.5em;
background-color: #ddd;
}
th, td {
border: 1px solid #000;
padding: 4px;
}
tfoot {
font-weight: bold;
}
<table>
<thead>
<tr><th rowspan="2">Question</th><th colspan="2">Women</th><th colspan="2">Men</th></tr>
<tr><th>Yes</th><th>No</th><th>Yes</th><th>No</th></tr>
</thead>
<tbody>
<tr><th>Question1</th><td>42%</td><td>58%</td><td>61%</td><td>39%</td></tr>
<tr><th>Question2</th><td>53%</td><td>47%</td><td>69%</td><td>31%</td></tr>
<tr><th>Question3</th><td>26%</td><td>74%</td><td>51%</td><td>49%</td></tr>
</tbody>
<tfoot>
<tr><th>Average</th><td>40%</td><td>60%</td><td>60%</td><td>40%</td></tr>
</tfoot>
</table>
Mostly when I try to see such layouts, I attempt to count how many rows and how many columns will be necessary in the final html. This helps to construct the html properly.
CSS then simply becomes a selection of those elements with either classes or elements. For your question I chose elements.
HTH!
#gsvolt
I just write the same table as you mentioned in a link. I hope it'll help you out. Thanks
thead th,
tbody tr td:first-child {
background-color: #ccc;
}
<table border="1" style="border-collapse: collapse;">
<thead>
<tr>
<th rowspan="2">Question</th>
<th colspan="2">Women</th>
<th colspan="2">Men</th>
</tr>
<tr>
<th>Yes</th>
<th>No</th>
<th>Yes</th>
<th>No</th>
</tr>
</thead>
<tbody>
<tr>
<td>Question 1</td>
<td>42%</td>
<td>58%</td>
<td>61%</td>
<td>39%</td>
</tr>
<tr>
<td>Question 2</td>
<td>53%</td>
<td>47%</td>
<td>69%</td>
<td>31%</td>
</tr>
<tr>
<td>Question 3</td>
<td>26%</td>
<td>74%</td>
<td>51%</td>
<td>49%</td>
</tr>
<tr>
<td>Average</td>
<td>40%</td>
<td>60%</td>
<td>60%</td>
<td>40%</td>
</tr>
</tbody>
</table>
To make a <th> span a set of rows, give it a rowspan attribute. For collumns, a colspan attribute.
To then target that <th> element, use the normal CSS selector methods, such as .class, #id, tag, etc.
you can use <colgroup> and <col class="men">
see: http://www.smashingmagazine.com/2008/08/13/top-10-css-table-designs/
5. Vertical Zebra Style

Border around specific rows in a table?

I'm trying to design some HTML/CSS that can put a border around specific rows in a table. Yes, I know I'm not really supposed to use tables for layout but I don't know enough CSS to completely replace it yet.
Anyways, I have a table with multiple rows and columns, some merged with rowspan and colspan, and I'd like to put a simple border around parts of the table. Currently, I'm using 4 separate CSS classes (top, bottom, left, right) that I attach to the <td> cells that are along the top, bottom, left, and right of the table respectively.
.top {
border-top: thin solid;
border-color: black;
}
.bottom {
border-bottom: thin solid;
border-color: black;
}
.left {
border-left: thin solid;
border-color: black;
}
.right {
border-right: thin solid;
border-color: black;
}
<html>
<body>
<table cellspacing="0">
<tr>
<td>no border</td>
<td>no border here either</td>
</tr>
<tr>
<td class="top left">one</td>
<td class="top right">two</td>
</tr>
<tr>
<td class="bottom left">three</td>
<td class="bottom right">four</td>
</tr>
<tr>
<td colspan="2">once again no borders</td>
</tr>
<tr>
<td class="top bottom left right" colspan="2">hello</td>
</tr>
<tr>
<td colspan="2">world</td>
</tr>
</table>
</html>
Is there any easier way to do what I want? I tried applying top and bottom to a <tr> but it didn't work. (p.s. I'm new to CSS, so there's probably a really basic solution to this that I've missed.)
note: I do need to have multiple bordered sections. The basic idea is to have multiple bordered clusters each containing multiple rows.
How about tr {outline: thin solid black;}? Works for me on tr or tbody elements, and appears to be compatible with the most browsers, including IE 8+ but not before.
Thank you to all that have responded! I've tried all of the solutions presented here and I've done more searching on the internet for other possible solutions, and I think I've found one that's promising:
tr.top td {
border-top: thin solid black;
}
tr.bottom td {
border-bottom: thin solid black;
}
tr.row td:first-child {
border-left: thin solid black;
}
tr.row td:last-child {
border-right: thin solid black;
}
<html>
<head>
</head>
<body>
<table cellspacing="0">
<tr>
<td>no border</td>
<td>no border here either</td>
</tr>
<tr class="top row">
<td>one</td>
<td>two</td>
</tr>
<tr class="bottom row">
<td>three</td>
<td>four</td>
</tr>
<tr>
<td colspan="2">once again no borders</td>
</tr>
<tr class="top bottom row">
<td colspan="2">hello</td>
</tr>
<tr>
<td colspan="2">world</td>
</tr>
</table>
</body>
</html>
Output:
Instead of having to add the top, bottom, left, and right classes to every <td>, all I have to do is add top row to the top <tr>, bottom row to the bottom <tr>, and row to every <tr> in between. Is there anything wrong with this solution? Are there any cross-platform issues I should be aware of?
If you set the border-collapse style to collapse on the parent table you should be able to style the tr:
(styles are inline for demo)
<table style="border-collapse: collapse;">
<tr>
<td>No Border</td>
</tr>
<tr style="border:2px solid #f00;">
<td>Border</td>
</tr>
<tr>
<td>No Border</td>
</tr>
</table>
Output:
I was just playing around with doing this too, and this seemed to be the best option for me:
<style>
tr {
display: table; /* this makes borders/margins work */
border: 1px solid black;
margin: 5px;
}
</style>
Note that this will prevent the use of fluid/automatic column widths, as cells will no longer align with those in other rows, but border/colour formatting still works OK. The solution is to give the TR and TDs a specified width (either px or %).
Of course you could make the selector tr.myClass if you wanted to apply it only to certain rows. Apparently display: table doesn't work for IE 6/7, however, but there's probably other hacks (hasLayout?) that might work for those. :-(
Here's an approach using tbody elements that could be the way to do it. You can't set the border on a tbody (same as you can't on a tr) but you can set the background colour. If the effect you're wanting to acheive can be obtained with a background colour on the groups of rows instead of a border this will work.
<table cellspacing="0">
<tbody>
<tr>
<td>no border</td>
<td>no border here either</td>
</tr>
<tbody bgcolor="gray">
<tr>
<td>one</td>
<td>two</td>
</tr>
<tr>
<td>three</td>
<td>four</td>
</tr>
<tbody>
<tr>
<td colspan="2">once again no borders</td>
</tr>
<tbody bgcolor="gray">
<tr>
<td colspan="2">hello</td>
</tr>
<tbody>
<tr>
<td colspan="2">world</td>
</tr>
</table>
The only other way I can think of to do it is to enclose each of the rows you need a border around in a nested table. That will make the border easier to do but will potentially creat other layout issues, you'll have to manually set the width on table cells etc.
Your approach may well be the best one depending on your other layout rerquirements and the suggested approach here is just a possible alternative.
<table cellspacing="0">
<tr>
<td>no border</td>
<td>no border here either</td>
</tr>
<tr>
<td>
<table style="border: thin solid black">
<tr>
<td>one</td>
<td>two</td>
</tr>
<tr>
<td>three</td>
<td>four</td>
</tr>
</table>
</td>
</tr>
<tr>
<td colspan="2">once again no borders</td>
</tr>
<tr>
<td>
<table style="border: thin solid black">
<tr>
<td>hello</td>
</tr>
</table>
</td>
</tr>
<tr>
<td colspan="2">world</td>
</tr>
</table>
Based on your requirement that you want to put a border around an arbitrary block of MxN cells there really is no easier way of doing it without using Javascript. If your cells are fixed with you can use floats but this is problematic for other reasons. what you're doing may be tedious but it's fine.
Ok, if you're interested in a Javascript solution, using jQuery (my preferred approach), you end up with this fairly scary piece of code:
<html>
<head>
<style type="text/css">
td.top { border-top: thin solid black; }
td.bottom { border-bottom: thin solid black; }
td.left { border-left: thin solid black; }
td.right { border-right: thin solid black; }
</style>
<script type="text/javascript" src="jquery-1.3.1.js"></script>
<script type="text/javascript">
$(function() {
box(2, 1, 2, 2);
});
function box(row, col, height, width) {
if (typeof height == 'undefined') {
height = 1;
}
if (typeof width == 'undefined') {
width = 1;
}
$("table").each(function() {
$("tr:nth-child(" + row + ")", this).children().slice(col - 1, col + width - 1).addClass("top");
$("tr:nth-child(" + (row + height - 1) + ")", this).children().slice(col - 1, col + width - 1).addClass("bottom");
$("tr", this).slice(row - 1, row + height - 1).each(function() {
$(":nth-child(" + col + ")", this).addClass("left");
$(":nth-child(" + (col + width - 1) + ")", this).addClass("right");
});
});
}
</script>
</head>
<body>
<table cellspacing="0">
<tr>
<td>no border</td>
<td>no border here either</td>
</tr>
<tr>
<td>one</td>
<td>two</td>
</tr>
<tr>
<td>three</td>
<td>four</td>
</tr>
<tr>
<td colspan="2">once again no borders</td>
</tr>
</tfoot>
</table>
</html>
I'll happily take suggestions on easier ways to do this...
Group rows together using the <tbody> tag and then apply style.
<table>
<tr><td>No Style here</td></tr>
<tbody class="red-outline">
<tr><td>Style me</td></tr>
<tr><td>And me</td></tr>
</tbody>
<tr><td>No Style here</td></tr>
</table>
And the css in style.css
.red-outline {
outline: 1px solid red;
}
the trick is with outline property thanks to enigment's answer with little modification
use this class
.row-border{
outline: thin solid black;
outline-offset: -1px;
}
then in the HTML
<tr>....</tr>
<tr class="row-border">
<td>...</td>
<td>...</td>
</tr>
and the result is
hope this helps you
An easier way is to make the table a server side control. You could use something similar to this:
Dim x As Integer
table1.Border = "1"
'Change the first 10 rows to have a black border
For x = 1 To 10
table1.Rows(x).BorderColor = "Black"
Next
'Change the rest of the rows to white
For x = 11 To 22
table1.Rows(x).BorderColor = "White"
Next