I've got a table
<table id="mytable">
<tr style="display: none;"><td> </td></tr>
<tr><td> </td></tr>
<tr style="display: none;"><td> </td></tr>
<tr><td> </td></tr>
<tr><td> </td></tr>
<tr><td> </td></tr>
</table>
I'm trying to set the table striping to use nth-child selectors but just can't seem to crack it.
table #mytable tr[#display=block]:nth-child(odd) {
background-color: #000;
}
table #mytable tr[#display=block]:nth-child(odd) {
background-color: #FFF;
}
I'm pretty sure I'm close ... can't quite seem to crack it.
anyone pass along a clue?
Here's as close as you're going to get. Note that you can't make the nth-child count only displayed rows; nth-child will take the nth child element no matter what, not the nth child that matches a given selector. If you want some rows to be missing and not affect the zebra-striping, you will have to remove them from the table entirely, either through the DOM or on the server side.
#mytable tr:nth-child(odd) {
background-color: #000;
}
#mytable tr:nth-child(even) {
background-color: #FFF;
}
<table id="mytable">
<tr><td> </td></tr>
<tr><td> </td></tr>
<tr><td> </td></tr>
<tr><td> </td></tr>
<tr><td> </td></tr>
<tr><td> </td></tr>
</table>
Here are the fixes that I made:
table #mytable tr[#display=block]:nth-child(odd) {
background-color: #000;
}
There's no need to specify an ancestor selector for an id based selector; there is only ever one element that will match #table, so you're just adding extra code by adding the table in.
#mytable tr[#display=block]:nth-child(odd) {
background-color: #000;
}
Now, [#display=block] would match elements which had an attribute display set to block, such as <tr display=block>. Display isn't a valid HTML attribute; what you seem to be trying to do is to have the selector match on the style of the element, but you can't do that in CSS, since the browser needs to apply the styles from the CSS before it can figure that out, which it's in the process of doing when it's applying this selector. So, you won't be able to select on whether table rows are displayed. Since nth-child can only take the nth child no matter what, not nth with some attribute, we're going to have to give up on this part of the CSS. There is also nth-of-type, which selects the nth child of the same element type, but that's all you can do.
#mytable tr:nth-child(odd) {
background-color: #000;
}
And there you have it.
If you are using JQuery to change the visibility of rows you can apply the following function to the table to add an .odd class where appropriate. Call it each time the rows visible is different.
function updateStriping(jquerySelector){
$(jquerySelector).each(function(index, row){
$(row).removeClass('odd');
if (index%2==1){ //odd row
$(row).addClass('odd');
}
});
}
And for the css simply do
table#tableid tr.visible.odd{
background-color: #EFF3FE;
}
While you can't Zebra stripe a table with hidden rows using CSS3 you can do it with JavaScript. Here is how:
var table = document.getElementById("mytable");
var k = 0;
for (var j = 0, row; row = table.rows[j]; j++) {
if (!(row.style.display === "none")) {
if (k % 2) {
row.style.backgroundColor = "rgba(242,252,244,0.4)";
} else {
row.style.backgroundColor = "rgba(0,0,0,0.0)";
}
k++;
}
}
For a jquery way, you could use this function which iterates through the rows in your table, checking the visbility of the row and (re)setting a class for visible odd rows.
function updateStriping(jquerySelector) {
var count = 0;
$(jquerySelector).each(function (index, row) {
$(row).removeClass('odd');
if ($(row).is(":visible")) {
if (count % 2 == 1) { //odd row
$(row).addClass('odd');
}
count++;
}
});
}
Use css to set a background for odd rows.
#mytable tr.odd { background: rgba(0,0,0,.1); }
Then you can call this zebra-striper whenever by using:
updateStriping("#mytable tr");
I came up with a sort of solution but it's reliant on the fact that the table can only ever have a maximum number of hidden rows and comes with the downside of requiring 2 additional CSS rules for each possible hidden row. The principle is that, after each hidden row, you switch the background-color of the odd and even rows around.
Here's a quick example with just 3 hidden rows and the necessary CSS for up to 4 of them. You can already see how unwieldy the CSS can become but, still, someone may find some use for it:
table{
background:#fff;
border:1px solid #000;
border-spacing:1px;
width:100%;
}
td{
padding:20px;
}
tr:nth-child(odd)>td{
background:#999;
}
tr:nth-child(even)>td{
background:#000;
}
tr[data-hidden=true]{
display:none;
}
tr[data-hidden=true]~tr:nth-child(odd)>td{
background:#000;
}
tr[data-hidden=true]~tr:nth-child(even)>td{
background:#999;
}
tr[data-hidden=true]~tr[data-hidden=true]~tr:nth-child(odd)>td{
background:#999;
}
tr[data-hidden=true]~tr[data-hidden=true]~tr:nth-child(even)>td{
background:#000;
}
tr[data-hidden=true]~tr[data-hidden=true]~tr[data-hidden=true]~tr:nth-child(odd)>td{
background:#000;
}
tr[data-hidden=true]~tr[data-hidden=true]~tr[data-hidden=true]~tr:nth-child(even)>td{
background:#999;
}
tr[data-hidden=true]~tr[data-hidden=true]~tr[data-hidden=true]~tr[data-hidden=true]~tr:nth-child(odd)>td{
background:#999;
}
tr[data-hidden=true]~tr[data-hidden=true]~tr[data-hidden=true]~tr[data-hidden=true]~tr:nth-child(even)>td{
background:#000;
}
<table>
<tbody>
<tr><td></td><td></td></tr>
<tr><td></td><td></td></tr>
<tr data-hidden="true"><td></td><td></td></tr>
<tr><td></td><td></td></tr>
<tr><td></td><td></td></tr>
<tr><td></td><td></td></tr>
<tr><td></td><td></td></tr>
<tr data-hidden="true"><td></td><td></td></tr>
<tr data-hidden="true"><td></td><td></td></tr>
<tr><td></td><td></td></tr>
<tr><td></td><td></td></tr>
<tr><td></td><td></td></tr>
<tr><td></td><td></td></tr>
<tr><td></td><td></td></tr>
<tr><td></td><td></td></tr>
<tr><td></td><td></td></tr>
</tbody>
</table>
in jquery ..
var odd = true;
$('table tr:visible').each(function() {
$(this).removeClass('odd even').addClass(odd?'odd':'even');
odd=!odd
});
You can easily fake the zebra stripes if you apply a vertically repeating gradient on the parent table, positioned exactly to match the rows' height (the rows would have to be transparent). That way the table won't care if anything's hidden, it will repeat no matter what.
If anyone tries to do something like me, where I have alternating hidden and visible rows, you can do this:
.table-striped tbody tr:nth-child(4n + 1) {
background-color: rgba(0,0,0,.05);
}
This will get every 4th element starting with the 1st one, and allows you to maintain striping with hidden rows between each visible row.
Here is a 2022 version of a javascript version
let cnt = 0;
document.querySelectorAll("#mytable tbody tr").forEach(tr => {
cnt += tr.hidden ? 0 : 1;
tr.classList.toggle("odd",cnt%2===0);
});
.odd { background-color: grey; }
<table id="mytable">
<thead><tr><th>Num</th></tr></thead>
<tbody>
<tr><td>1</td></tr>
<tr><td>2</td></tr>
<tr><td>3</td></tr>
<tr hidden><td></td></tr>
<tr><td>5</td></tr>
<tr><td>6</td></tr>
</tbody>
</table>
I add in css:
tr[style="display: table-row;"]:nth-child(even) {
background-color: #f3f6fa;
}
and on create tr add in tag
style="display: table-row;"
Jquery codes for zebra color in html table
$("#mytabletr:odd").addClass('oddRow');
$("#mytabletr:even").addClass('evenEven');
And CSS you can do
.oddRow{background:#E3E5E6;color:black}
.evenRow{background:#FFFFFF;color:black}
Related
I've got a table that needs to be striped but it has some rows that may become hidden later on. After hiding some of the rows re-striping does not occur so the striping is off. How can I force the table to re-stripe itself? Here is my css that I feel should work, but it's not. And then also my html.
.isHidden {
display:none;
}
tbody {
tr:not(.isHidden):nth-child(odd) {
background: rgb(238, 238, 238);
}
}
<tbody>
<tr [ngClass]="{'isHidden': !line.get('isVisible').value}" *ngFor="let line of lineDetailsArray.controls; let i=index;">
...
</tr>
</tbody>
At present, you won't be able to solve the problem with CSS only, unfortunately. True, there's a potentially useful addition in the spec - :nth-child(An+B of S). The following example exactly matches your case:
Normally, to zebra-stripe a table’s rows, an author would use CSS
similar to the following:
tr {
background: white;
}
tr:nth-child(even) {
background: silver;
}
However, if some of the rows are hidden and not displayed, this
can break up the pattern, causing multiple adjacent rows to have the
same background color. Assuming that rows are hidden with the [hidden]
attribute in HTML, the following CSS would zebra-stripe the table rows
robustly, maintaining a proper alternating background regardless of
which rows are hidden:
tr {
background: white;
}
tr:nth-child(even of :not([hidden])) {
background: silver;
}
The caveat? Support of this option in browsers is not even limited: it's non-existent.
But still, there's a way out of this misery. Even though Angular won't just let you place ngIf and ngFor on a single element (it'll be way too simple I suppose), there's a workaround - using <ng-container> as a placeholder:
<ng-container *ngFor="let item of list">
<ng-container *ngIf="!item.hidden">
<tr>
<td>{{item.name}}</td>
<td><input type="checkbox"
[checked]="item.hidden"
(change)="item.hidden = !item.hidden" /></td>
</tr>
</ng-container>
</ng-container>
Demo (kudos to #imkremen for helping to create this one).
I've got a table
<table id="mytable">
<tr style="display: none;"><td> </td></tr>
<tr><td> </td></tr>
<tr style="display: none;"><td> </td></tr>
<tr><td> </td></tr>
<tr><td> </td></tr>
<tr><td> </td></tr>
</table>
I'm trying to set the table striping to use nth-child selectors but just can't seem to crack it.
table #mytable tr[#display=block]:nth-child(odd) {
background-color: #000;
}
table #mytable tr[#display=block]:nth-child(odd) {
background-color: #FFF;
}
I'm pretty sure I'm close ... can't quite seem to crack it.
anyone pass along a clue?
Here's as close as you're going to get. Note that you can't make the nth-child count only displayed rows; nth-child will take the nth child element no matter what, not the nth child that matches a given selector. If you want some rows to be missing and not affect the zebra-striping, you will have to remove them from the table entirely, either through the DOM or on the server side.
#mytable tr:nth-child(odd) {
background-color: #000;
}
#mytable tr:nth-child(even) {
background-color: #FFF;
}
<table id="mytable">
<tr><td> </td></tr>
<tr><td> </td></tr>
<tr><td> </td></tr>
<tr><td> </td></tr>
<tr><td> </td></tr>
<tr><td> </td></tr>
</table>
Here are the fixes that I made:
table #mytable tr[#display=block]:nth-child(odd) {
background-color: #000;
}
There's no need to specify an ancestor selector for an id based selector; there is only ever one element that will match #table, so you're just adding extra code by adding the table in.
#mytable tr[#display=block]:nth-child(odd) {
background-color: #000;
}
Now, [#display=block] would match elements which had an attribute display set to block, such as <tr display=block>. Display isn't a valid HTML attribute; what you seem to be trying to do is to have the selector match on the style of the element, but you can't do that in CSS, since the browser needs to apply the styles from the CSS before it can figure that out, which it's in the process of doing when it's applying this selector. So, you won't be able to select on whether table rows are displayed. Since nth-child can only take the nth child no matter what, not nth with some attribute, we're going to have to give up on this part of the CSS. There is also nth-of-type, which selects the nth child of the same element type, but that's all you can do.
#mytable tr:nth-child(odd) {
background-color: #000;
}
And there you have it.
If you are using JQuery to change the visibility of rows you can apply the following function to the table to add an .odd class where appropriate. Call it each time the rows visible is different.
function updateStriping(jquerySelector){
$(jquerySelector).each(function(index, row){
$(row).removeClass('odd');
if (index%2==1){ //odd row
$(row).addClass('odd');
}
});
}
And for the css simply do
table#tableid tr.visible.odd{
background-color: #EFF3FE;
}
While you can't Zebra stripe a table with hidden rows using CSS3 you can do it with JavaScript. Here is how:
var table = document.getElementById("mytable");
var k = 0;
for (var j = 0, row; row = table.rows[j]; j++) {
if (!(row.style.display === "none")) {
if (k % 2) {
row.style.backgroundColor = "rgba(242,252,244,0.4)";
} else {
row.style.backgroundColor = "rgba(0,0,0,0.0)";
}
k++;
}
}
For a jquery way, you could use this function which iterates through the rows in your table, checking the visbility of the row and (re)setting a class for visible odd rows.
function updateStriping(jquerySelector) {
var count = 0;
$(jquerySelector).each(function (index, row) {
$(row).removeClass('odd');
if ($(row).is(":visible")) {
if (count % 2 == 1) { //odd row
$(row).addClass('odd');
}
count++;
}
});
}
Use css to set a background for odd rows.
#mytable tr.odd { background: rgba(0,0,0,.1); }
Then you can call this zebra-striper whenever by using:
updateStriping("#mytable tr");
I came up with a sort of solution but it's reliant on the fact that the table can only ever have a maximum number of hidden rows and comes with the downside of requiring 2 additional CSS rules for each possible hidden row. The principle is that, after each hidden row, you switch the background-color of the odd and even rows around.
Here's a quick example with just 3 hidden rows and the necessary CSS for up to 4 of them. You can already see how unwieldy the CSS can become but, still, someone may find some use for it:
table{
background:#fff;
border:1px solid #000;
border-spacing:1px;
width:100%;
}
td{
padding:20px;
}
tr:nth-child(odd)>td{
background:#999;
}
tr:nth-child(even)>td{
background:#000;
}
tr[data-hidden=true]{
display:none;
}
tr[data-hidden=true]~tr:nth-child(odd)>td{
background:#000;
}
tr[data-hidden=true]~tr:nth-child(even)>td{
background:#999;
}
tr[data-hidden=true]~tr[data-hidden=true]~tr:nth-child(odd)>td{
background:#999;
}
tr[data-hidden=true]~tr[data-hidden=true]~tr:nth-child(even)>td{
background:#000;
}
tr[data-hidden=true]~tr[data-hidden=true]~tr[data-hidden=true]~tr:nth-child(odd)>td{
background:#000;
}
tr[data-hidden=true]~tr[data-hidden=true]~tr[data-hidden=true]~tr:nth-child(even)>td{
background:#999;
}
tr[data-hidden=true]~tr[data-hidden=true]~tr[data-hidden=true]~tr[data-hidden=true]~tr:nth-child(odd)>td{
background:#999;
}
tr[data-hidden=true]~tr[data-hidden=true]~tr[data-hidden=true]~tr[data-hidden=true]~tr:nth-child(even)>td{
background:#000;
}
<table>
<tbody>
<tr><td></td><td></td></tr>
<tr><td></td><td></td></tr>
<tr data-hidden="true"><td></td><td></td></tr>
<tr><td></td><td></td></tr>
<tr><td></td><td></td></tr>
<tr><td></td><td></td></tr>
<tr><td></td><td></td></tr>
<tr data-hidden="true"><td></td><td></td></tr>
<tr data-hidden="true"><td></td><td></td></tr>
<tr><td></td><td></td></tr>
<tr><td></td><td></td></tr>
<tr><td></td><td></td></tr>
<tr><td></td><td></td></tr>
<tr><td></td><td></td></tr>
<tr><td></td><td></td></tr>
<tr><td></td><td></td></tr>
</tbody>
</table>
in jquery ..
var odd = true;
$('table tr:visible').each(function() {
$(this).removeClass('odd even').addClass(odd?'odd':'even');
odd=!odd
});
You can easily fake the zebra stripes if you apply a vertically repeating gradient on the parent table, positioned exactly to match the rows' height (the rows would have to be transparent). That way the table won't care if anything's hidden, it will repeat no matter what.
If anyone tries to do something like me, where I have alternating hidden and visible rows, you can do this:
.table-striped tbody tr:nth-child(4n + 1) {
background-color: rgba(0,0,0,.05);
}
This will get every 4th element starting with the 1st one, and allows you to maintain striping with hidden rows between each visible row.
Here is a 2022 version of a javascript version
let cnt = 0;
document.querySelectorAll("#mytable tbody tr").forEach(tr => {
cnt += tr.hidden ? 0 : 1;
tr.classList.toggle("odd",cnt%2===0);
});
.odd { background-color: grey; }
<table id="mytable">
<thead><tr><th>Num</th></tr></thead>
<tbody>
<tr><td>1</td></tr>
<tr><td>2</td></tr>
<tr><td>3</td></tr>
<tr hidden><td></td></tr>
<tr><td>5</td></tr>
<tr><td>6</td></tr>
</tbody>
</table>
I add in css:
tr[style="display: table-row;"]:nth-child(even) {
background-color: #f3f6fa;
}
and on create tr add in tag
style="display: table-row;"
Jquery codes for zebra color in html table
$("#mytabletr:odd").addClass('oddRow');
$("#mytabletr:even").addClass('evenEven');
And CSS you can do
.oddRow{background:#E3E5E6;color:black}
.evenRow{background:#FFFFFF;color:black}
I'm having an issue where I can't seem to find an answer to, but I can't imagine it's not possible.
I have a table with two columns: the left column contains a label, the right side contains a value. However, the value can be empty. The label is fixed text.
What I want is to hide the entire row if the right cell of the row (the value) is empty.
For example:
<table>
<tr>
<td class="label">number of users:</td>
<td class="value">8</td>
</tr>
<tr>
<td class="label">total number of people:</td>
<td class="value"></td>
</tr>
</table>
Since the last row does not contain a value, I want the entire row to be hidden.
I can hide the cell using td:empty, but that's not enough. I tried to work around this by setting the height of the row to 0px and make it expand when the 'value'-cell is shown, but I can't get that to work either since the label cell already expands the row.
Anyone knows how I can tackle this problem using just HTML/CSS?
There's no parent selector in css, so you can't do this with css.
You may use jQuery:
$('td').each(function(){
if($(this).is(:empty)){
$(this).closest('tr').hide();
}
});
Or in shorter form,
$('tr:has("td:empty")').hide();
See the docs: :empty, :has,closest and each
While JavaScript is necessary to solve this problem, jQuery is, by no means, a requirement. Using the DOM, one can achieve this with the following:
function hideParentsOf(cssSelector) {
var elems = document.querySelectorAll(cssSelector);
if (elems.length) {
Array.prototype.forEach.call(elems, function (el) {
el.parentNode.style.display = 'none';
});
}
}
hideParentsOf('td:empty');
function hideParentsOf(cssSelector) {
// cssSelector: String,
// a string representing a CSS selector,
// such as 'td:empty' in this case.
// retrieving a NodeList of elements matching the supplied selector:
var elems = document.querySelectorAll(cssSelector);
// if any elements were found:
if (elems.length) {
// iterating over the array-like NodeList with Array.forEach():
Array.prototype.forEach.call(elems, function(el) {
// el is the current array-element (or NodeList-element in
// this instance).
// here we find the parentNode, and set its 'display' to 'none':
el.parentNode.style.display = 'none';
});
}
}
hideParentsOf('td:empty');
<table>
<tr>
<td class="label">number of users:</td>
<td class="value">8</td>
</tr>
<tr>
<td class="label">total number of people:</td>
<td class="value"></td>
</tr>
</table>
References:
CSS:
:empty pseudo-class.
JavaScript:
Array.prototype.forEach().
document.querySelectorAll().
Function.prototype.call().
Node.parentNode.
HTMLElement.style.
An HTML/CSS solution exists if you don't mind throwing out <table> <tr> and <td>. You can get the same end result with CSS - including still rendering like a table:
CSS:
/* hide if empty */
.hideIfEmpty:empty { display: none; }
/* label style */
.hideIfEmpty::before { font-weight:bold; }
/* labels */
.l_numberofusers::before { content:"Number of users: "; }
.l_numberofpeople::before { content: "Number of people:"; }
.l_numberofdogs::before { content: "Number of dogs:" }
/* table like rows/cells */
.table { display: table; }
.row { display: table-row; }
.cell { display: table-cell; }
HTML
<!-- if the div.hideIfEmpty is empty, it'll be hidden;
labels come from CSS -->
<div class="table">
<div class="row hideIfEmpty l_numberofusers"><span class="cell">8</span></div>
<div class="row hideIfEmpty l_numberofpeople"><span class="cell">12</span></div>
<div class="row hideIfEmpty l_numberofdogs"></div>
</div>
The caveat is that your <div> has to be empty to hide the row, and values in the <div> must have a class .cell applied to them.
Result:
Number of users: 8
Number of people: 12
This will make your CSS very long if you have many labels/rows since you have to have one rule for every row to populate the label.
I have a table with a class applied and I want to add a hover effect to all rows with a specific class name. But this doesn't seem to work. Using chrome. Must work in IE8 as well. Can anyone help me get this working please?
html ->
<table class="myTable">
<tr class="myRow">
<td>1</td>
</tr>
<tr>
<td>2</td>
</tr>
css ->
.myTable.myRow tr:hover td{
background-color:red;
}
Here's a Fiddle
You can just use this:
.myRow:hover {
background:red;
}
fiddle
You have applied the class slightly wrong change it to:
.myTable tr.myRow:hover td{
background-color:red;
}
Reasoning being in your css you are saying find the class myTable that also has class myRow but its your tr element with the myRow class.
I'm learning CSS and HTML.
In my code I have:
<style>
table, td, th
{
padding: 5px;
}
</style>
This rule works on all tables on the page.
Now I want to make a table without padding:
Here is the source:
<table>
<tr>
<td>Login</td>
<td><input type="text" name="login" class="input"></td>
</tr>
<tr>
<td>Password</td>
<td><input type="password" name="password" class="input"></tr>
</tr>
</table>
How to do this?
If you want to add specific styles to this table that override the default styles you've defined, then you'll need some way to reference it in CSS.
Typically, you would give it a class or an ID -- eg <table class='myspecialtable'>....</table>
Then you can have a stylesheet which overrides your default 5px styles, just for this table.
.myspecialtable, .myspecialtable td, .myspecialtable th {
padding: 0px;
}
If you can't add an ID or class to this table, then you could add it on a parent element, and the effect would be the same (as long as that parent doesn't contain any other tables, of course). In this case, your CSS would look something like this:
.myspecialtablecontainer table, .myspecialtablecontainer td, .myspecialtablecontainer th {
padding: 0px;
}
You should change your CSS to define a style instead.
.padded { ... }
Then you can set the class to that style for any tables you want to use that style.
<table class="padded">
</table>
When you set a style, as you have done, for all elements of a particular type, then the only way to remove them is to set the style to something else, or not include a reference to that CSS file from the page that you don't want to use them.
One way would be to give your table a class like so:
<table class="nopadding">
[... table rows and columns...]
</table>
And then put this in your css:
.nopadding, .nopadding td, .nopadding th
{
padding: 0;
}
Which says "any element with the class should have a padding of 0". The .nopadding th and .nopadding td has to be there and is a way of saying "all th and td who is inside an element of class nopadding shouldn't have any padding either", since you previously told all th and td to have a padding of 5px.
I remeber when I first started learning HTML.
What you're after is an id or a class attribute. You'd have two tables like so:
<table class="table1">
<tr>
<td>Login</td>
<td><input type="text" name="login" class="input"></td>
</tr>
<tr>
<td>Password</td>
<td><input type="password" name="password" class="input"></tr>
</tr>
</table>
<table class="table2">
<tr>
<td>Login</td>
<td><input type="text" name="login" class="input"></td>
</tr>
<tr>
<td>Password</td>
<td><input type="password" name="password" class="input"></tr>
</tr>
</table>
To make is so that table1 had padding, but table2 didn't, you would use the appropriate CSS rules to identify and style the tables:
.table1, .table1 td, .table1 th
{
padding: 5px;
}
.table2, .table2 td, .table2 th
{
padding: 0px;
}
There's many ways I could have done this with CSS. For example, You could also use ids in this case, but it's easier to use classes as an id can only be used once per document.
A slightly better approach in this case would be to take advantage of cascading rules. I could have kept your original CSS and just added the second set of rules:
.table, .table td, .table th
{
padding: 5px;
}
.table2, .table2 td, .table2 th
{
padding: 0px;
}
In this case, only tables with the class table2 would have the 0px padding - all other tables would have 5px padding.
It would be a good idea to read the W3CSchools introduction to CSS - http://www.w3schools.com/css/css_intro.asp. This will introduce you to the basics and get you on your way.
Simple use
<style>
table, td, th
{
padding: 0px;
}
</style>
Also try border-collapse: collapse;.
<table cellpadding='0'> If this don't work, you can create a css class that removes the padding and use that in your table: <table class='no_padding'>