2

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; }

Mark
  • 2,543
  • 6
  • 33
  • 44
  • The most straightforward way, if you have control of the document, would be to add a hide-me type class to the elements in the body that you want hidden, since at creation time you would know if the element in the head has a particular class. – scrappedcola Oct 04 '18 at 19:15
  • 1
    give small example how your html code looks like. – Void Spirit Oct 04 '18 at 19:16
  • Perhaps `th.isSystem ~ td { display: none }` (or `visibility: hidden`)? This selects a `td` that is a general sibling of `th.isSystem`. I haven't tested it, though. – lurker Oct 04 '18 at 19:18
  • @lurker, ha, that's exactly what I tried, but it did not work :( – Mark Oct 04 '18 at 19:20
  • 1
    You should say in your question that you tried that! :) You might have to bite the bullet and do a little Javascript or (better) some jQuery. But really, that's overkill if this is a static table. I assume, though, that although static, maybe you want to be able to go in and mark it `isSystem` as needed and have it respond accordingly. – lurker Oct 04 '18 at 19:22
  • You cannot do this with plain CSS. Javascript is necessary. – Gerard Oct 04 '18 at 19:41
  • I got it - using typescript. cheers all – Mark Oct 04 '18 at 19:46
  • Yep, choose your favorite javascript wrapper. – lurker Oct 04 '18 at 20:54

2 Answers2

0

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.

Mr Lister
  • 45,515
  • 15
  • 108
  • 150
0

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.

Stu Furlong
  • 3,490
  • 5
  • 34
  • 47