5

I have a <td> element with a little bit of padding, and I'd like to shade in the entire table cell when it's immediate child is a <mark> element.

I'm using markdown to generate the table itself, so simply adding a class like <td class="highlight"> isn't really an option.

Basic Table Setup

Here's a basic table setup

<table>
  <thead>
    <tr>
      <th>Name</th>
      <th>Type</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Ranger</td>
      <td>Dog</td>
    </tr>
    <tr>
      <td><mark>Frida <br/> Kahtlo</mark></td>
      <td><mark>Cat</mark></td>
    </tr>
  </tbody>
</table>

With some basic CSS

table {
    border-collapse: collapse;
}
table td, table th {
    border: 1px solid #ddd;
    padding: 8px;
    position: relative;
}

Attempt #1

One idea was to absolutely position the <mark> element and pin it to all four sides:

td > mark {
    position: absolute;
    top: 0;
    right: 0;
    left: 0;
    bottom: 0;
    padding: 8px;
}

However, it doesn't seem possible to set the parent parent height from an absolutely positioned child, so the contents overflows the <td>

example one

table {
    border-collapse: collapse;
}
table td, table th {
    border: 1px solid #ddd;
    padding: 8px;
    position: relative;
}

td > mark {
    position: absolute;
    top: 0;
    right: 0;
    left: 0;
    bottom: 0;
    padding: 8px;
}
<table>
  <thead>
    <tr>
      <th>Name</th>
      <th>Type</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Ranger</td>
      <td>Dog</td>
    </tr>
    <tr>
      <td><mark>Frida <br/> Kahtlo</mark></td>
      <td><mark>Cat</mark></td>
    </tr>
  </tbody>
</table>

Attempt #2

Another idea was to reverse the padding with a negative margin like this:

td > mark {
    display: block;
    margin: -8px;
    padding: 8px;
}

However, if there is a line wrap in another cell, I can't get the child element to occupy the full height available

example two

table {
    border-collapse: collapse;
}
table td, table th {
    border: 1px solid #ddd;
    padding: 8px;
    position: relative;
}

td > mark {
    display: block;
    margin: -8px;
    padding: 8px;
}
<table>
  <thead>
    <tr>
      <th>Name</th>
      <th>Type</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Ranger</td>
      <td>Dog</td>
    </tr>
    <tr>
      <td><mark>Frida <br/> Kahtlo</mark></td>
      <td><mark>Cat</mark></td>
    </tr>
  </tbody>
</table>

Q: Any other ways that this might be possible?

KyleMit
  • 30,350
  • 66
  • 462
  • 664
  • Do you want to add a background in the specific "Frida Kahtlo" row? – Sadik Multani Oct 07 '19 at 17:08
  • @MultaniSadik, yes, in this case. But in the general case applying the style at the cell level. If only one `` has a direct child of ``, that would be the only one that needed highlighting – KyleMit Oct 07 '19 at 17:17

2 Answers2

3

Use a big box-shadow and hide the overflow

table {
    border-collapse: collapse;
}
table td, table th {
    border: 1px solid #ddd;
    padding: 8px;
}
td {
 overflow:hidden;
}
td > mark {
  display:inline-block;
  box-shadow: 0 0 0 50px yellow; 
}
<table>
  <thead>
    <tr>
      <th>Name</th>
      <th>Type</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Ranger</td>
      <td>Dog</td>
    </tr>
    <tr>
      <td><mark>Frida <br/> Kahtlo</mark></td>
      <td><mark>Cat</mark></td>
    </tr>
  </tbody>
</table>
Temani Afif
  • 245,468
  • 26
  • 309
  • 415
2

I suggest to loop all marks and add bg color yellow to their parent :

document.querySelectorAll('mark').forEach(function(item){
  item.parentElement.style.backgroundColor ="ff0";
});

codepen: https://codepen.io/HBA/pen/BaayQOL

Hammed
  • 232
  • 2
  • 7