"Leak" text behind <th> using Sticky CSS position

Asked

Viewed 215 times

5

I’m using position: sticky; in the <thead> of a table where I assign a background color to <th>.

My intention is that, when scrolling the page, the header remains visible because the table has many lines and this makes it much easier to read the data.

The problem is that the text that is scrolled up appears behind the <th> table.

Take an example:

/*
  Este código não tem nada a ver com o problema
  é só para o HTML não ficar quilométrico.
*/
let tr = document.getElementById('replicar')
let frag = document.createDocumentFragment()
let i = 30

while (i-- > 0) { frag.appendChild(tr.cloneNode(true)) }
tr.parentElement.appendChild(frag)
table {
  width: 100%;
  margin-top: 100px;
}

thead {
  position: sticky;
  top: 15px;
}

th {
  background-color: #babaca;
}
<table>
  <thead>
    <tr>
      <th>Header 1</th>
      <th>Header 2</th>
      <th>Header 3</th>
      <th>Header 4</th>
    </tr>
  </thead>
  <tbody>
    <tr id="replicar">
      <td>Coluna 1</td>
      <td>Coluna 2</td>
      <td>Coluna 3</td>
      <td>Coluna 4</td>
    </tr>
  </tbody>
</table>

Like the Chrome does not support position: sticky in <thead>, follows a picture:

Texto vazado


I "solved" my problem by applying a box-shadow in my <thead> so that there is a "backdrop" that covers the text rolling behind.

Follow an example with the box-shadow in red for easy viewing:

/*
  Este código não tem nada a ver com o problema
  é só para o HTML não ficar quilométrico.
*/
let tr = document.getElementById('replicar')
let frag = document.createDocumentFragment()
let i = 30

while (i-- > 0) { frag.appendChild(tr.cloneNode(true)) }
tr.parentElement.appendChild(frag)
table {
  width: 100%;
  margin-top: 100px;
}

thead {
  position: sticky;
  top: 15px;
  box-shadow: 0 -8px 0 8px red; /* Aqui seria branco */
}

th {
  background-color: #babaca;
}
<table>
  <thead>
    <tr>
      <th>Header 1</th>
      <th>Header 2</th>
      <th>Header 3</th>
      <th>Header 4</th>
    </tr>
  </thead>
  <tbody>
    <tr id="replicar">
      <td>Coluna 1</td>
      <td>Coluna 2</td>
      <td>Coluna 3</td>
      <td>Coluna 4</td>
    </tr>
  </tbody>
</table>

Imagery:

Com box-shadow


My question is, is there a less likely way to do that?

I should use another element to have one background-color overlapping with the text?

  • If you put top 0px and not 15px you will see that solves :)

  • Hello young man, knew I’d find you here :) About the top: 0;, I know that, but the problem is that I don’t want it to stick to the top. It gets bad to read and sticks to my Navbar

  • Dude I’m in a Hackathon hj there will be hard to stop to test etc, but you can try putting a pseudo-element on the table... This if you consider it less gambiarra rss... Another option would be to put the table inside a div. But only testing to see the result

  • 1

    Relax Hugo, I’m not in a hurry for the answers. It’s already working well here, it’s more for someone to teach me something.

  • Look if that’s what you need https://codepen.io/hugocsl/pen/LMYVyK

2 answers

1


The solution I found was to create a box-shadow in my thead with the same color as the bottom of the page, so the text is hidden "underneath" the box-shadow creating the effect I want.

As mentioned in the question, in my opinion this solution is not ideal and will be marked as the correct answer temporarily while a better answer is not proposed, or the bug is solved.


Code

I’m using red as a shadow to make it easier to visualize where the shadow is, but in practice the color will be the same as the background, giving the impression that the text disappears when it goes "underneath" the header.

/*
  Este código não tem nada a ver com o problema
  é só para o HTML não ficar quilométrico.
*/
let tr = document.getElementById('replicar')
let frag = document.createDocumentFragment()
let i = 30

while (i-- > 0) { frag.appendChild(tr.cloneNode(true)) }
tr.parentElement.appendChild(frag)
table {
  width: 100%;
  margin-top: 100px;
}

thead {
  position: sticky;
  top: 15px;
  box-shadow: 0 -8px 0 8px red; /* Aqui seria branco */
}

th {
  background-color: #babaca;
}
<table>
  <thead>
    <tr>
      <th>Header 1</th>
      <th>Header 2</th>
      <th>Header 3</th>
      <th>Header 4</th>
    </tr>
  </thead>
  <tbody>
    <tr id="replicar">
      <td>Coluna 1</td>
      <td>Coluna 2</td>
      <td>Coluna 3</td>
      <td>Coluna 4</td>
    </tr>
  </tbody>
</table>

  • Very interesting drop-shadow technique

-3

Perhaps it would be better to use:

position: fixed;
top: 0;

Browser other questions tagged

You are not signed in. Login or sign up in order to post.