CSS performance- descendant selector vs. class selector - css

I appending table dynamically using javascript in html with say 50000 cells.
<table id="dataTable">
<tbody>
<tr>
<td>data1</td>
<td>data2</td>
.....
<td>data1</td>
</tr>
..........
<tr>
<td>data1</td>
<td>data2</td>
.....
<td>data1</td>
</tr>
</tbody>
</table>
I'm styling the td with descendant selector as,
#dataTable td{
text-align:right;
border:1px solid #adadad;
padding-right:10px;
}
Another option is to give class to each td using class selector.
<table id="dataTable">
<tbody>
<tr>
<td class="format">data1</td>
<td class="format">data2</td>
.....
<td class="format">data1</td>
</tr>
..........
<tr>
<td class="format">data1</td>
<td class="format">data2</td>
.....
<td class="format">data1</td>
</tr>
</tbody>
</table>
Here we have used format class for styling.
.format{
text-align:right;
border:1px solid #adadad;
padding-right:10px;
}
I'm facing performance issue while rendering the table in browser. Is this because I've used DESCENDANT SELECTOR INSTEAD OF CLASS SELECTOR.
Or Browser is not able handle large data.

About the table performance
Tables can be slow to render mostly due to the dynamic column sizes that need to be calculated and set on every change.
You can solve this by specifying a fixed size for each column, like so:
#dataTable td {
width: 100px; /* Set sizes appropriately */
}
This should make your table more performant
About CSS performance
CSS selects by the last token first, so for example, to execute the following selector:
#dataTable td
CSS will first select ALL td elements and then check if each of them is a descendant of #dataTable. Technically, specifying a class for each cell is faster.
However, this is probably not significant enough to pay for by complicating your overall design.
I recommend reading Efficiently Rendering CSS by CSS-Tricks to get a better idea about CSS and performance.

Related

How to hide this specific text from a <TR> in a TABLE HTML CODE

I am trying to hide this:
<thead>
<tr>
<th class="col-image all" data-name="image" data-orderable="false" data-searchable="false" data-width="200px" data-priority="4">Image</th>
</tr>
</thead>
And this is my attempt:
thead.col-image all {
display: none;
}
^ this didn't work - any idea?
Thanks!
You are calling the wrong element and ALSO 'all' is not a selector;
thead.col-image all {} // is calling e.g. <thead class="col-image">
It should be
thead tr th.col-image.all { display: none; }
thead.col-image all means <all> tags in <thead class='col-image'>
correct css for your code should be
thead .col-image.all {
display: none;
}
https://jsfiddle.net/pb5k4v63/26/
with <th> tag only heading will disappear.
Attach a class for <th>or <td> or <tr> depending on your requirement.
and for that class apply the property
{visibility:hidden} which will not affect alignment of your table.
where as {display:none} can affect the alignment (though it works.)
you can use class for td th or add a span to text you want to hide and add class to it
.hide{
visibility:hidden;
}
<table>
<tr>
<td>hello</td>
<td class="hide">hide me</td>
<td>and also <span class="hide">hide me</span></td>
</tr>
</table>
TL;DR Wrap your <thead>, <th>, etc. within the <table> element. Also make sure you are calling the proper elements in your CSS.
An HTML table is defined with the <table> tag.
So in essence you have the <th>, <thead>, etc. elements operating outside of a <table>, so you are breaking your code because the <th>, <thead>, etc. require the parent <table> element to function properly.
Why you may ask? As stated above a table is defined with the <table> tag, so you do not really have a table on your page.
In conclusion "wrap your tables rows, heads, etc within the <table> element for now on.
Here is the code:
HTML
<table>
<thead>
<tr>
<th class="col-image all" data-name="image" data-orderable="false" data-searchable="false" data-width="200px" data-priority="4">Image</th>
</tr>
</thead>
</table>
CSS
th.col-image.all{
display: none;
}
You can view the code live here: https://jsfiddle.net/W3Develops/nbf17pus/6/
I also added another table in there so you can see how to properly make a table.
Here is a link to Mozilla Developer Network and W3Schools so you can learn more about making tables. Good luck:
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/table
https://www.w3schools.com/html/html_tables.asp
Also you were calling classes for thead when you should have been calling classes for th.
Cheers.

CSS - Hide td in body if th has class

I need to hide td in the body if the th in the head has the class .isSystem
Is this possible in straight CSS?
More info: the table is built dynamically. The head/columns is an array... and the tbody/rows is another array. I'm using Angular/typescript...
I tried this: th.isSystem ~ td { text-decoration: line-through; color: red; }
If the table is built dynamically, then the obvious way is to use col rather than th to drive this behaviour. <col> elements have special powers which enable them to affect the cells they belong to.
table {border:1px outset;}
th, td {border:1px inset;}
col.isSystem {visibility:collapse;}
<table>
<col/><col class="isSystem"/><col/><col/>
<thead>
<tr><th>One</th> <th>Two</th> <th>Three</th> <th>Four</th></tr>
</thead>
<tbody>
<tr><td>This</td> <td>This</td> <td>This</td> <td>This</td></tr>
<tr><td>is</td> <td>is</td> <td>is</td> <td>is</td></tr>
<tr><td>the</td> <td>the</td> <td>the</td> <td>the</td></tr>
<tr><td>first</td> <td>second</td><td>third</td> <td>fourth</td></tr>
<tr><td>column</td><td>column</td><td>column</td><td>column</td></tr>
</tbody>
</table>
Disclaimer: this works as advertised in Firefox, IE11 and Edge. Chrome however... sorry.
Bottom Line:
No, because <td> and <th> can not be siblings since they are not proper children of a <table> and even if your source markup has them that way - the browser will adjust the markup and overrule your styles.
Long explanation:
Looking at a more JS related SO question on the subject, the browser automatically will inject <thead> and <tbody> around your <th> and <tr> (subsequently <td>) elements. <thead> and <tbody> are valid child elements of <table> - <th> and <tr> are not.
As a result, finding the siblings of <th> will only return other th tags, since they technically live in a <thead> - the <td> are in a <tr> in <tbody>
Take a look at these examples:
Example 1
Codepen with straight <th> and <tr> elements
.isSystem + .row { background:red }
<table>
<th class="isSystem">Table Heading</th>
<tr class="row">
<td>Table Item</td>
</tr>
</table>
<div class="isSystem">Div Heading</div>
<div class="row">Div Item</div>
In this example, you would expect the table row to be red... The div elements in the example do this but the <tr> doesn't
Example 2
Codepen with proper <thead> and <tbody> elements
In example 2, wrapping the table with the correct thead and tbody elements, you can acheive this:
.isSystem + .rows tr { background:red; }
<table>
<thead class="isSystem"><th>Heading</th></thead>
<tbody class="rows">
<tr class="row"><td>Item</td></tr>
</tbody>
</table>
Unfortunately if your items are dynamically generated and you can not apply your classes in this way, then your only option will be using JS to target your elements as others have already mentioned. However, I would do what's possible to create proper semantic markup first.

Change <td> width without table-fixed

I want to change the width of one of my cell but without to fixed all table cells. Is there any way to change specific <td> without the rule table-fixed
Give the td a class name. Like <TD CLASS="class">cel</TD>
Then in css call it like .class {color:red}
https://jsfiddle.net/tnquk2xt/
You can add a class to the table cell and style it appropriately like so:
CSS
.large {width:150px;}
.small {width: 50px;}
HTML
<table>
<tr>
<td class="small">First</td>
<td class="large">Second</td>
<td class="small">Third</td>
</tr>
</table>
Here is a fiddle: https://jsfiddle.net/mmvbmktn/
http://www.w3schools.com/tags/tryit.asp?filename=tryhtml_td_width
<td width="70%">
It was not really hard to find, they set width of the 2 TDs but it works also with only one TD width.
Use Google !! :3

Skip first-child selector's style for specific element

Lets say we have generic css class for table to use on all places in our application. Lets consider also this style has first-child selector.
tr td:first-child { ... }
I would like to use this class for an specific table but skip all first-child styles.
Since this is generic style class for tables i cant remove from it and also dont want to handle this with inline styling.
Thanks
You could be more specific for that particular table, assuming it has a class or an id you can use:
tr td:first-child {
color: red;
}
.test tr td:first-child {
color: green;
}
<table>
<tr>
<td>First td</td>
<td>Second td</td>
</tr>
</table>
<table class="test">
<tr>
<td>First td</td>
<td>Second td</td>
</tr>
</table>
Excuse the limited markup, but you get the point. Because the .test tr td:first-child {} class is more specific than the generic style, it overrides it, but only for the table with the class test.
More info on specifity: https://www.smashingmagazine.com/2007/07/css-specificity-things-you-should-know/

Style every thing except first child

I know of the selector :not() but it doesn't work, like tr:not(tr:first-child):hover. I want to style the other trs but not the first one, because it holds the headings. How can I do this without using an id or class?
You can only use simple selectors in :not(), try
tr:not(:first-child)
http://jsfiddle.net/mowglisanu/Sn7Uw/
Another option would be to use the th element which is specifically represents the header cell in a table.
Example
<table>
<thead>
<tr>
<th>Number</th>
<th>element</th>
</tr>
</thead>
<tbody>
<tr>
<td>4.1.1</td>
<td>html</td>
</tr>
<tr>
<td>4.2.1</td>
<td>head</td>
</tr>
</tbody>
</table>
Use the adjacent sibling combinator. As a bonus, it's a bit more widely supported than :not()
TR + TR { background-color: silver; }
TR + TR:hover { background-color: green; }
http://jsfiddle.net/ETYQN/2/
Put your headers in a <thead> and your stylable rows in the <tbody> then use:
tbody tr:hover { background: red }
and it won't matter what the contents is.
http://jsfiddle.net/stevemarvell/we4a6/

Resources