Achieve alternate row colours across multiple tbody elements - css

Is there a way in CSS to achieve alternate row shading all rows across multiple tbody elements are treated as one group?
So for example:
<tbody>
<tr>...</tr>
</tbody>
<tbody>
<tr>...</tr>
</tbody>
<tbody>
<tr>...</tr>
</tbody>
I know of nth-child, but that would not work here, since if each tbody only has one row, then they would all get coloured the same.
Anyone know of any ways to achieve this behaviour?

Not with CSS...no. nth-of- doesn't work that way. You would need Javascript.
Jquery makes this easy.
$("#my-table tr:even").css("background-color", "#bbbbff");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="my-table">
<tbody>
<tr>
<td>Row 1</td>
</tr>
</tbody>
<tbody>
<tr>
<td>Row 2</td>
</tr>
</tbody>
<tbody>
<tr>
<td>Row 3.1</td>
</tr>
<tr>
<td>Row 3.2</td>
</tr>
</tbody>
<tbody>
<tr>
<td>Row 4.1</td>
</tr>
<tr>
<td>Row 4.2</td>
</tr>
<tr>
<td>Row 4.3</td>
</tr>
</tbody>
<tbody>
<tr>
<td>Row 5</td>
</tr>
</tbody>
</table>

#my-table tbody
{
display: block;
margin: 20px auto;
}
#my-table tbody tr
{
background-color: #d88;
}
#my-table tbody:nth-child(even) tr
{
background-color: #8d8;
}
#my-table tbody:nth-child(even) tr:nth-child(even)
{
background-color: #d88;
}
#my-table tbody:nth-child(odd) tr:nth-child(odd)
{
background-color: #8d8;
}
<table id="my-table">
<tbody>
<tr><td>Row 1</td></tr>
</tbody>
<tbody>
<tr><td>Row 2</td></tr>
<tr><td>Row 2</td></tr>
</tbody>
<tbody>
<tr><td>Row 3</td></tr>
<tr><td>Row 3</td></tr>
<tr><td>Row 3</td></tr>
</tbody>
<tbody>
<tr><td>Row 4</td></tr>
</tbody>
<tbody>
<tr><td>Row 5</td></tr>
</tbody>
</table>

If the number of rows in your html markup are the same in each tbody you can use following CSS solution:
#my-table tbody:nth-child(odd)
{
background-color: red;
}
#my-table tbody:nth-child(even)
{
background-color: yellow;
}
<table id="my-table">
<tbody>
<tr>
<td>Row 1</td>
</tr>
</tbody>
<tbody>
<tr>
<td>Row 2</td>
</tr>
</tbody>
<tbody>
<tr>
<td>Row 3</td>
</tr>
</tbody>
<tbody>
<tr>
<td>Row 4</td>
</tr>
</tbody>
<tbody>
<tr>
<td>Row 5</td>
</tr>
</tbody>
</table>
Otherwise you can consider using CSS3 :nth-child() Selector, example nth-child(2) to select an element at a specific index.
Alternatively you can use JavaScript, answer from #Paulie_D will solve your issue.
#tb1 tr:nth-child(1){
background-color: green;
}
#tb1 tr:nth-child(2){
background-color: red;
}
#tb2 tr:nth-child(1){
background-color: green;
}
#tb3 tr:nth-child(1){
background-color: red;
}
#tb3 tr:nth-child(2){
background-color: green;
}
#tb3 tr:nth-child(3){
background-color: red;
}
#tb4 tr:nth-child(1){
background-color: green;
}
#tb5 tr:nth-child(1){
background-color: red;
}
<table id="my-table">
<tbody id="tb1">
<tr>
<td>Row 1a</td>
</tr>
<tr>
<td>Row 1b</td>
</tr>
</tbody>
<tbody id="tb2">
<tr>
<td>Row 2a</td>
</tr>
</tbody>
<tbody id="tb3">
<tr>
<td>Row 3a</td>
</tr>
<tr>
<td>Row 3b</td>
</tr>
<tr>
<td>Row 3c</td>
</tr>
</tbody>
<tbody id="tb4">
<tr>
<td>Row 4</td>
</tr>
</tbody>
<tbody id="tb5">
<tr>
<td>Row 5a</td>
</tr>
</tbody>
</table>

Related

CSS pseudo selectors using first-child

I know I could do this easily by specifying an id but I want to practice with pseudo selectors.
I have two tables within a view. Using pseudo selectors:
I want to grab the first table only.
within that first table's <tbody>
I want to grab the first <tr> and color all the text red.
My current implementation almost works. The issue is that it does this styling for every table in the view. I want this styling to happen only for the first table.
tbody tr:first-child {
color: red;
}
<table>
<thead>
<tr>
<th>First Column</th>
<th>Second Column</th>
</tr>
</thead>
<tbody>
<tr>
<td> T1 R1 Col 1</td>
<td>This row should all be red</td>
</tr>
<tr>
<td>T1 R2 Col 1</td>
<td>foobar</td>
</tr>
</tbody>
</table>
<br>
<table>
<thead>
<tr>
<th>First Column</th>
<th>Second Column</th>
</tr>
</thead>
<tbody>
<tr>
<td> T2 R1 Col 1</td>
<td>This row should NOT be red</td>
</tr>
<tr>
<td>T2 R2 Col 1</td>
<td>foobar</td>
</tr>
</tbody>
</table>
Use another pseudo selector for the table:
table:nth-of-type(1) tbody tr:first-child {
color: red;
}
<table>
<thead>
<tr>
<th>First Column</th>
<th>Second Column</th>
</tr>
</thead>
<tbody>
<tr>
<td> T1 R1 Col 1</td>
<td>This row should all be red</td>
</tr>
<tr>
<td>T1 R2 Col 1</td>
<td>foobar</td>
</tr>
</tbody>
</table>
<br>
<table>
<thead>
<tr>
<th>First Column</th>
<th>Second Column</th>
</tr>
</thead>
<tbody>
<tr>
<td> T2 R1 Col 1</td>
<td>This row should NOT be red</td>
</tr>
<tr>
<td>T2 R2 Col 1</td>
<td>foobar</td>
</tr>
</tbody>
</table>
You could take it a step further with the pseudo selectors since you already know you're targeting the first table and use :first-of-type which works similarly as :nth-of-type(1)
table:first-of-type tbody tr:first-child {
color: red;
}
<table>
<thead>
<tr>
<th>First Column</th>
<th>Second Column</th>
</tr>
</thead>
<tbody>
<tr>
<td> T1 R1 Col 1</td>
<td>This row should all be red</td>
</tr>
<tr>
<td>T1 R2 Col 1</td>
<td>foobar</td>
</tr>
</tbody>
</table>
<br>
<table>
<thead>
<tr>
<th>First Column</th>
<th>Second Column</th>
</tr>
</thead>
<tbody>
<tr>
<td> T2 R1 Col 1</td>
<td>This row should NOT be red</td>
</tr>
<tr>
<td>T2 R2 Col 1</td>
<td>foobar</td>
</tr>
</tbody>
</table>
Wrap the tables in a container element and then apply this CSS
.container > :first-child tr:first-child td:last-child {
color: red;
}
<div class="container">
<table>
<thead>
<tr>
<th>First Column</th>
<th>Second Column</th>
</tr>
</thead>
<tbody>
<tr>
<td> T1 R1 Col 1</td>
<td>This row should all be red</td>
</tr>
<tr>
<td>T1 R2 Col 1</td>
<td>foobar</td>
</tr>
</tbody>
</table>
<br>
<table>
<thead>
<tr>
<th>First Column</th>
<th>Second Column</th>
</tr>
</thead>
<tbody>
<tr>
<td> T2 R1 Col 1</td>
<td>This row should NOT be red</td>
</tr>
<tr>
<td>T2 R2 Col 1</td>
<td>foobar</td>
</tr>
</tbody>
</table>
</div>
Note: This will apply the CSS to the first table in every .container element. Just specify an ID instead and it shouldn't be a problem

How to change table layout depending on resolution?

So this is targeted toward IE 10 and 11 and I'm also using Bootstrap 3.
If I have a desktop monitor, I'd like my table to have this layout:
<table class="table table-responsive">
<thead>
<tr>
<td>Header 1</td>
<td>Header 2</td>
<td>Header 3</td>
</tr>
</thead>
<tfoot></tfoot>
<tbody>
<tr>
<td>Data 1</td>
<td>Data 2</td>
<td>Data 3</td>
</tr>
</tbody>
</table>
On a phone (or similar device), I'd like to have the layout like this:
<table class="table table-responsive">
<thead>
<tr>
<td>Header</td>
<td>Data</td>
</tr>
</thead>
<tfoot></tfoot>
<tbody>
<tr>
<td>Header 1</td>
<td>Data 1</td>
</tr>
<tr>
<td>Header 2</td>
<td>Data 2</td>
</tr>
<tr>
<td>Header 3</td>
<td>Data 3</td>
</tr>
</tbody>
</table>
Is there some or CSS that will allow me to do this? Or can this only be done with javascript (and css)?
To be clear, I want the code to detect the resolution and display one of the two layouts.
You can create two tables and use css media queries to toggle between the two, see fiddle https://jsfiddle.net/5f3pbg8b/17/
.table.mobile {
display: none
}
.table.desktop {
display: inline
}
#media (max-width: 600px) {
.table.desktop {
display: none
}
.table.mobile {
display: inline
}
}

pure CSS - Zebra-stripe table only if it has more than 2 rows

I'm trying to apply a css only zebra stripe style to a table, but only if it has more than 2 rows.
Is this possible with css only? IE9 and upwards is required - so good to go for all css3 selectors.
So far this is what I came up with, but I'm not quite there...
Should have Zebra:
<div class="select">
<table>
<tr class="clickable">
<td>row 1</td>
</tr>
<tr class="clickable">
<td>row 2</td>
</tr>
<tr class="clickable">
<td>row 3</td>
</tr>
<tr class="clickable">
<td>row 4</td>
</tr>
<tr class="clickable">
<td>row 5</td>
</tr>
<tr class="clickable">
<td>row 6</td>
</tr>
</table>
</div>
<hr>
Should have Zebra:
<div class="select">
<table>
<tr class="clickable">
<td>row 1</td>
</tr>
<tr class="clickable">
<td>row 2</td>
</tr>
<tr class="clickable">
<td>row 3</td>
</tr>
</table>
</div>
<hr> Since only 2 elements: shouldnt have Zebra
<div class="select">
<table>
<tr class="clickable">
<td>row 1a</td>
</tr>
<tr class="clickable">
<td>row 2a</td>
</tr>
</table>
</div>
CSS:
.clickable:nth-child(odd):not(:nth-last-child(2)) {
background: rgba(230, 230, 230, 1);
color: red;
}
.clickable:nth-child(even):not(:nth-last-child(1)) {
background: rgba(180, 180, 180, 1);
}
http://codepen.io/anon/pen/zqEWYO
You can use CSS Quantity Queries.
Simply add:
.clickable:only-child,
.clickable:nth-last-child(2):first-child,
.clickable:nth-last-child(2):first-child ~ .clickable {
background: none;
}
Example on Codepen
Or you can apply styles only when there 3+ elements:
Example on Codepen
You can also select (increasing selector weight meantime):
/* single tr being first and last */
table tr.clickable:nth-child(odd):first-child:last-child ,
/* last being right after first */
table tr.clickable:nth-child(odd):first-child + tr.clickable:nth-child(even):last-child ,
/* first being right before last */
table tr.clickable:nth-child(odd):first-child:nth-last-child(2) {
background:none;
color:gray;
}
codepen fork
table tr.clickable:nth-child(odd) {
background: rgba(230, 230, 230, 1);
color: red;
}
table tr.clickable:nth-child(even) {
background: rgba(180, 180, 180, 1);
}
table tr.clickable:nth-child(odd):first-child:last-child,
table tr.clickable:nth-child(odd):first-child + tr.clickable:nth-child(even):last-child,
table tr.clickable:nth-child(odd):first-child:nth-last-child(2) {
background:none;
color:gray;
}
Should have Zebra:
<div class="select">
<table>
<tr class="clickable">
<td>row 1</td>
</tr>
<tr class="clickable">
<td>row 2</td>
</tr>
<tr class="clickable">
<td>row 3</td>
</tr>
<tr class="clickable">
<td>row 4</td>
</tr>
<tr class="clickable">
<td>row 5</td>
</tr>
<tr class="clickable">
<td>row 6</td>
</tr>
</table>
</div>
<hr>
Should have Zebra:
<div class="select">
<table>
<tr class="clickable">
<td>row 1</td>
</tr>
<tr class="clickable">
<td>row 2</td>
</tr>
<tr class="clickable">
<td>row 3</td>
</tr>
</table>
</div>
<hr> Since only 2 elements: shouldnt have Zebra
<div class="select">
<table>
<tr class="clickable">
<td>row 1a</td>
</tr>
<tr class="clickable">
<td>row 2a</td>
</tr>
</table>
</div>
<hr> Since only 1 element: shouldnt have Zebra Css rules
<div class="select">
<table>
<tr class="clickable">
<td>row 1a</td>
</tr>
</table>
</div>

CSS table alternate row colors and hover colors [duplicate]

This question already has answers here:
Alternate table row color using CSS?
(11 answers)
Closed 6 years ago.
I have a table with class table. The only styling so far is the table th. I'd like to use a CSS value to alternate between white and silver for the rows, and hover silver for the entire row. Does anyone have the code for that?
<table class='table'>
<tr>
<th>heading</th>
<th>heading 2</th>
<th>heading 3</th>
</tr>
<tr class='table'>
<td>col 1</td>
<td>col 2</td>
<td>col 3</td>
</tr>
<tr class='table'>
<td>col 1</td>
<td>col 2</td>
<td>col 3</td>
</tr>
<tr class='table'>
<td>col 1</td>
<td>col 2</td>
<td>col 3</td>
</tr>
</table>
That is the html example (as it's written in php)
CSS
.table {
background-color: #FFFFFF;
color: #000000;
}
.table th {
background-color: #333333;
color: #FFFFFF;
}
That's it so far. Looking for the values to use for I'm guessing the table tr css.
Saying different because even/odd doesn't work & it's dynamic php not strict html.
If you've already set the background color of your table to white, you just need to set the alternate row and hover backgrounds, like so:
.table tr {
transition: background 0.2s ease-in;
}
.table tr:nth-child(odd) {
background: silver;
}
.table tr:hover {
background: silver;
cursor: pointer;
}
Additionally, you probably don't need to repeat the table class on each row, FWIW. You can just target those rows using .table tr as I have done. If you're trying to make sure the table header and body styles don't interfere with each other, it's more semantic and just cleaner to wrap those elements in a thead and tbody:
<table class='table'>
<thead>
<tr>
<th>heading</th>
<th>heading 2</th>
<th>heading 3</th>
</tr>
</thead>
<tbody>
<tr>
<td>col 1</td>
<td>col 2</td>
<td>col 3</td>
</tr>
<tr>
<td>col 1</td>
<td>col 2</td>
<td>col 3</td>
</tr>
<tr>
<td>col 1</td>
<td>col 2</td>
<td>col 3</td>
</tr>
</tbody>
</table>
You can achieve this with a little bit css, just use the n-th child selector, like this:
HTML:
<table class="alternate">
<tr>
<td>Row Col 1 </td>
<td>Row Col 2 </td>
</tr>
<tr>
<td>Row Col 1 </td>
<td>Row Col 2 </td>
</tr>
<tr>
<td>Row Col 1 </td>
<td>Row Col 2 </td>
</tr>
<tr>
<td>Row Col 1 </td>
<td>Row Col 2 </td>
</tr>
</table>
CSS:
.alternate tr:nth-child(2n) {
background-color: silver;
}
.alternate tr {
background-color: white;
}
.alternate tr:nth-child(2n):hover, .alternate tr:hover {
background-color: grey;
}
And here is a working fiddle, I hope that is what you were looking for.

How to remove TD borders in only first TR in TABLE

I am styling table for my website. I want to have a table where first TR doesn't have border while others TR and their TD's have a border.
Code: http://jsfiddle.net/azq6xfnr/ or here:
.table2 {
border: 1px solid black;
border-collapse: collapse;
text-align: center;
}
.table2 .header {
background-color: #d8ff93;
color: #126f06;
border: 0;
}
.table2 td {
border: 1px solid #53f673;
padding: 10px;
}
.table2 tr:not(.header):nth-child(odd) {
background-color: #3cde53;
}
<table class="table2">
<tr class="header">
<td>Lp.</td>
<td>Column 1</td>
<td>Column 2</td>
</tr>
<tr>
<td>1</td>
<td>Row 1</td>
<td>Row 1</td>
</tr>
<tr>
<td>2</td>
<td>Row 2</td>
<td>Row 2</td>
</tr>
<tr>
<td>3</td>
<td>Row 3</td>
<td>Row 3</td>
</tr>
<tr>
<td>4</td>
<td>Row 4</td>
<td>Row 4</td>
</tr>
<tr>
<td>5</td>
<td>Row 5</td>
<td>Row 5</td>
</tr>
</table>
Use the CSS first-child selector. Here is a fiddle http://jsfiddle.net/r8p061hs/ or http://jsfiddle.net/r8p061hs/1/
.table2 {
border: 1px solid black;
border-collapse: collapse;
text-align: center;
}
.table2 .header {
background-color: #d8ff93;
color: #126f06;
border: 0;
}
.table2 td {
border: 1px solid #53f673;
padding: 10px;
}
.table2 tr:not(.header):nth-child(odd) {
background-color: #3cde53;
}
.table2 tr:first-child {
border: 1px solid #53f673;
}
.table2 tr:first-child td {
border: none;
}
<table class="table2">
<tr class="header">
<td>Lp.</td>
<td>Column 1</td>
<td>Column 2</td>
</tr>
<tr>
<td>1</td>
<td>Row 1</td>
<td>Row 1</td>
</tr>
<tr>
<td>2</td>
<td>Row 2</td>
<td>Row 2</td>
</tr>
<tr>
<td>3</td>
<td>Row 3</td>
<td>Row 3</td>
</tr>
<tr>
<td>4</td>
<td>Row 4</td>
<td>Row 4</td>
</tr>
<tr>
<td>5</td>
<td>Row 5</td>
<td>Row 5</td>
</tr>
</table>
I think css pseudo class :first-child could help you: http://www.w3schools.com/cssref/sel_firstchild.asp
You need to remove the border from both your table, and the cells in the .header row, no need to use :first-child or :first-of-type as you've given the row the class header
Demo Fiddle
.table2 {
border-collapse: collapse;
border-spacing:0;
text-align: center;
/* remove the border from here */
}
.table2 .header td{
border:none; /* and from here */
}
As an alternative to the other answers, if your intention is that the first row be styled this way to be a header row, you could also consider using the more semantic <thead> grouping with <th> elements, if that's practical. You could then class them (advisable) or just rely on the tag names (less advisable due to selector performance, but still possible).
By then grouping subsequent rows within a <tbody>, you could also simplify your alternate row colouring selector, as you would be able to avoid the :not pseudo-selector.
Example of adjusted code:
<table class="table2">
<thead class="header">
<tr><th>Lp.</th><th>Column 1</th><th>Column 2</th></tr>
</thead>
<tbody>
<tr><td>1</td><td>Row 1</td><td>Row 1</td></tr>
<tr><td>2</td><td>Row 2</td><td>Row 2</td></tr>
<tr><td>3</td><td>Row 3</td><td>Row 3</td></tr>
<tr><td>4</td><td>Row 4</td><td>Row 4</td></tr>
<tr><td>5</td><td>Row 5</td><td>Row 5</td></tr>
</tbody>
</table>

Resources