3

Using Bootstrap 5, I wrote an HTML table with a scrollable content and a "sticky" header. I also used Bootstrap CSS classes to stylize the table.

The snippet below shows a minimal example:

html,
body {
  height: 100%;
}

body {
  font-size: 1.5em
}
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" />
<div id="root" class="container d-flex flex-column h-100" style="border:1px solid black;">
  <div class="mb-3 text-center"> Header </div>
  <div class="flex-grow-1 overflow-auto">
    <table class="table table-bordered table-striped table-hover">
      <thead class="table-dark sticky-top">
        <tr>
          <th scope="col">Header 1</th>
          <th scope="col">Header 2</th>
          <th scope="col">Header 3</th>
          <th scope="col">Header 4</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>Content 1</td>
          <td>Content 2</td>
          <td>Content 3</td>
          <td>Content 4</td>
        </tr>
        <tr>
          <td>Content 1</td>
          <td>Content 2</td>
          <td>Content 3</td>
          <td>Content 4</td>
        </tr>
        <tr>
          <td>Content 1</td>
          <td>Content 2</td>
          <td>Content 3</td>
          <td>Content 4</td>
        </tr>
        <tr>
          <td>Content 1</td>
          <td>Content 2</td>
          <td>Content 3</td>
          <td>Content 4</td>
        </tr>
      </tbody>
    </table>
  </div>
  <div class="mt-3 mb-3 text-center"> Footer </div>
</div>

But when the content is scrolled with Chrome:

  • TD cell borders move over the header
  • Back to its beginning, a "padding" appears between the header and the top border, as shown here:

Padding between the header and the top border

Did I miss something, or is this a known behavior?

2
  • 1
    I'm not seeing this problem with a 'vanilla' CSS version (table, borders on the tds and sticky thead) so you'll need to look further into exactly what CSS bootstrap is setting. Commented Sep 4 at 19:44
  • I upvoted your comment, you're right @AHaworth. Commented Sep 4 at 21:48

1 Answer 1

1

position: sticky is applied to <thead>, but Bootstrap adds borders to <td>.

This probably happens because Chrome renders the borders on the elements below and strangely ignores z-index.

Try forcibly removing the borders from <thead>:

thead tr, thead th {
  border: none;
}

And instead, use a box-shadow for the header:

thead th {
  box-shadow: -1px 1px 2px 0px rgb(159 72 134 / 90%) !important;
}

html,
body {
  height: 100%;
}

body {
  font-size: 1.25em
}


thead tr, thead th {
  border: none;
}

thead th {
      box-shadow: -1px 1px 2px 0px rgb(159 72 134 / 90%) !important;
}
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" />



<div id="root" class="container d-flex flex-column h-100" style="border:1px solid black;">
  <div class="mb-3 text-center"> Header </div>
  <div class="flex-grow-1 overflow-auto">
    <table class="table table-bordered table-striped table-hover">
      <thead class="table-dark sticky-top">
        <tr>
          <th scope="col">Header 1</th>
          <th scope="col">Header 2</th>
          <th scope="col">Header 3</th>
          <th scope="col">Header 4</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>Content 1</td>
          <td>Content 2</td>
          <td>Content 3</td>
          <td>Content 4</td>
        </tr>
        <tr>
          <td>Content 1</td>
          <td>Content 2</td>
          <td>Content 3</td>
          <td>Content 4</td>
        </tr>
        <tr>
          <td>Content 1</td>
          <td>Content 2</td>
          <td>Content 3</td>
          <td>Content 4</td>
        </tr>
        <tr>
          <td>Content 1</td>
          <td>Content 2</td>
          <td>Content 3</td>
          <td>Content 4</td>
        </tr>
      </tbody>
    </table>
  </div>
  <div class="mt-3 mb-3 text-center"> Footer </div>
</div>

Sign up to request clarification or add additional context in comments.

2 Comments

Hello ! Thanks, it seems interesting... I'll give a try.
I tested by adding just the rule thead tr, thead th {border: none;} and it seems to be enough to work. Maybe the background thing was to let the TH cells to have borders?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.