I'd like to select all of the child td elements of the second child of a tbody element. Here is the selection I am trying to achieve:
<table>
<thead></thead>
<tbody>
<tr></tr>
<tr>
<td>I want to select this td</td>
<td>And this one</td>
</tr>
</tbody>
</table>
tbody:nth-child(2) > td
{
//insert rules
}
However this is not working. Does CSS3 support selecting children of pseudoclasses? If not, any advice on how to achieve the above selection would be greatly appreciated.
Thanks for you input.
tr:nth-child(2) does what you asked for:
tr:nth-child(2) {
color: red;
<table>
<thead></thead>
<tbody>
<tr>
<td>not me</td>
<td>And not me</td>
</tr>
<tr>
<td>I want to select this td</td>
<td>And this one</td>
</tr>
</tbody>
</table>
tbody:nth-child(2) > td won't work because only <tr> elements can be children of <tbody> elements.
to select all second td try it:
td:nth-child(2)
{
//
}
but if you wan't to select all td in the second child you can try :
tr:nth-child(2)
{
//
}
Yes you can mix pseudo-selectors and the child selector (did you notice your typo on child?):
.a-class:nth-child(2n) > .child-class
Related
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.
In my CSS, I have an entry:
.isenabled {
font-weight:bold;
background-color:lightyellow
}
In the HTML, I have:
<table>
<tr>
<td class="isenabled">This is enabled</td>
<td>This isn't</td>
</tr>
</table>
This works as intended. What I'd like to do is:
<table>
<tr class="isenabled">
<td>This is enabled</td>
<td>So is this</td>
</tr>
<tr>
<td class="isenabled">This is enabled</td>
<td>This isn't</td>
</tr>
</table>
But this doesn't work as it stands (both the cells have the default background). What should I do instead?
[EDIT]
I've made the desired behaviour more explicit.
Use following style
tr.isenabled > td, td.isenabled {
font-weight: bold;
background-color: lightyellow
}
<table>
<tr class="isenabled">
<td>This is enabled</td>
<td>So is this</td>
</tr>
</table>
.isenabled is catching the element with class "isenabled".
that's why when you add class to 'td' it works.
<table>
<tr>
<td class="isenabled">This is enabled</td>
<td>This isn't</td>
</tr>
</table>
if you are adding class to 'tr' element the css properties will be applied to 'tr' but you want it to be applied on 'td'.
'>' is used for immediate child after the the selected element
so if you write "tr > td" as selected it will select all 'td' which are immediate child of any 'tr' in html document.
so you can do like this
tr.isenabled > td {
font-weight: bold;
background-color: lightyellow
}
it will select all 'td' which is immediate child of any element with class "isenabled".
Here is the more information about css selectors https://www.w3schools.com/cssref/css_selectors.asp.
I have a table that I want to select the very first TH only if it contains a caption. I thought it might be something like this:
.myTable caption + tr th:first-child
{
/* stuff */
}
It's instead selecting nothing. Is this a bug in CSS or just my logic?
See my JSFiddle: https://jsfiddle.net/ukb13pdp/1/
.objectTable th:first-child
{
background-color: blue;
color: white;
}
.objectTable caption + tr th:first-child
{
background-color: red;
}
<table class='objectTable'>
<caption>Caption Table</caption>
<tr>
<th>A</th>
<th>B</th>
</tr>
<tr>
<td>1</td>
<td>2</td>
</tr>
</table>
<br/><br/>
<span>No Caption Table</span>
<table class='objectTable'>
<tr>
<th>C</th>
<th>D</th>
</tr>
<tr>
<td>3</td>
<td>4</td>
</tr>
</table>
The cause here is exactly the same as the one described in this related question about the use of child selectors with tr. The problem is that tr elements are made children of an implicit tbody element, so what ends up being the sibling of the caption is that tbody and not the tr:
.myTable caption + tbody th:first-child
As an aside, if your th elements reside in a header row they should ideally be contained in a thead element and the data rows contained in explicit tbody element(s):
<table class=myTable>
<caption>Table with header group</caption>
<thead>
<tr><th>Header<th>Header
<tbody>
<tr><td>Row 1<td>Row 1
<tr><td>Row 2<td>Row 2
</table>
And selected using
.myTable caption + thead th:first-child
You're forgetting about the <tbody> element which wraps the <tr> element. Even though not specified in your (otherwise invalid) HTML, the <tbody> element is automatically implemented by the browser as a way of validating this, so instead of:
<caption>
<tr>
You end up with:
<caption>
<tbody>
<tr>
As seen in this element inspector capture below:
To select the very first <tr> element after a <caption> element, you can instead use:
caption + tbody tr:first-child {
...
}
JSFiddle demo.
Lets say I have the following table:
<table style="width:500px">
<tr>
<td>Col 1</td>
<td>Col 2</td>
</tr>
<tr>
<td colspan="2"></td>
</tr>
</table>
Now if I use the first-child selector to apply a style to the first TD, is there anyway I can have it ignore the td that has the colspan (even though of course this is the first-child)?
table tr td:first-child{
width:100px;
}
I would be happy to give the td with the colspan it's own class name if there was then a way I could modify my selector to say apply to first child except when the class name is x?
use :not([attr="val"])
table tr td:first-child:not([colspan="#NUMBER OF COLSPAN"]){
width:100px;
}
Try this:
table tr td:first-child:not(.ignore) {
width:100px;
}
(Where you give the td that you want to ignore a class of "ignore")
Why not just give the class the opposing property?
table tr td:first-child{
width:100px;
}
.your_class {
width:auto !important;
}
One simple way is to just add a class to the first TD that you actually want to select:
<table style="width:500px">
<tr>
<td class='selectable'>Col 1</td>
<td>Col 2</td>
</tr>
<tr>
<td colspan="2"></td>
</tr>
</table>
Then hit it with:
table tr td.selectable {
width: 100px;
}
Alternatively, you could try jQuery and put a class name of "ignoreMe" on the row you don't want affected with:
$('table tr td:first-child').not('.ignoreMe').css({width:100});
For your example you can use :not([colspan]) which ignores the any td with colspan defined. Something like this:
table tr td:first-child:not([colspan]){
width:100px;
}
suppose I have a nested tables in html like this
<table>
<tr>
<td><table>
<tr>
<td></td>
<td></td>
</tr>
</table></td>
<td></td>
</tr>
<tr>
<td><table>
<tr>
<td></td>
<td></td>
</tr>
</table></td>
<td></td>
</tr>
</table>
Now I want to do style only to the parent table without adding any markup like any class or IDs. so how can I do that only in css.I just want to select the parent table.
You can't specify the parent table in a selector, but you can specify the child tables, so you can style all tables, and then override the style for child tables:
table { background: red; }
table table { background: none; }
You could probably use table:first.
But it's advanced selector which I personally wouldn't trust that much in pure CSS. There is also a reason why there are classes and ids so why not use them?