Home > Net >  CSS: applying class to tbody cells (in the same column) based on header class
CSS: applying class to tbody cells (in the same column) based on header class

Time:10-20

couldn't find anything so here's my Markup:

<style>
table {
  width:300px;
  border-collapse:collapse;
}

th.price
{
  text-align:right;
  background:yellow;
}

th, td
{
  border:1px solid #aaa;
}
</style>

<table>
  <thead><tr><th>Item</th><th class="price">Price</th></tr></thead>
  <tbody>
    <tr><td>Item1</td><td>12.30</td></tr>
    <tr><td>Item2</td><td>23.40</td></tr>
    <tr><td>Item2</td><td>45.60</td></tr>
  </tbody>
</table>

enter image description here

So I don't want to apply .price to each table cell or use :nth-child or jQuery .. would it be possible with css only?

CodePudding user response:

I don’t think you can apply a class to td elements based on the class applied to a th element, in css.

You don’t want to use jQuery, but you can use vanilla javascript:

const cssClass = "price";
const th = document.getElementsByClassName(cssClass)[0];
const thead = th.parentElement;
const idx = Array.prototype.indexOf.call(thead.children, th);
const tbody = th.parentElement.getElementsByTagName("tbody")[0];
Array.prototype.forEach(tbody.getElementsByTagName("tr"), tr => {
  tr.children[idx].classList.add(cssClass)
})

CodePudding user response:

I don't think what you want to do is possible in CSS today. Although it was often requested, you can't travel (at least now) over parents with CSS selectors because CSS cannot pass information upwards in the DOM hierarchy. But this specific feature would be the minimum requirement to determine the index of the children in the following rows that need to be styled.

For more on that see the answer of "Is there a CSS parent selector?", which is stating "There is currently no way to select the parent of an element in CSS. (...) That said, the Selectors Level 4 Working Draft includes a :has() pseudo-class that will provide this capability."

With the currently drafted :has() you could at least build a repetitive CSS solution with a finite column count like this:

/* For a column of three columns maximum: */
/* if price is first column */
table:has(thead > th.price:first-child) tbody > td:first-child,
/* if price is second column */
table:has(thead > :first-child th.price) tbody > :first-child td,
/* if price is third column */
table:has(thead > :first-child * th.price) tbody > :first-child * td {
 ...
}

Crappy, I know... but currently the only native CSS solution in a possible foreseeable future.

But for now depending on what you need, you could also "cheat": If the background and/or border of the column should be changed you can use styling of the th header cell only (e.g. by abusing :before and :after). But text content specific changes would be quite impossible without JavaScript.

  • Related