Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

706
Visualizações
Table headers position:sticky and border issue

I have a table that I'm trying to get sticky headers, following this article. Except my table style has the headers with a border at the top and bottom.

The part I do not understand is that the top/bottom borders applied to the th scroll away with the rest of the table instead of staying with the "stuck" header cells. Is there anything that can be done about this?

Working sample can be found here: https://codepen.io/smlombardi/pen/MNKqQY?editors=1100#0

let string = ''
console.log("oj")
for(let i=0; i<100; i++) {
  string += `
        <tr>
          <td>Malcolm Reynolds</td>
          <td>Captain</td>
          <td>9035749867</td>
          <td>mreynolds</td>
        </tr>
  `
}
document.getElementsByTagName('tbody')[0].innerHTML += string
.table-sticky-container {
  height: 200px;
  overflow-y: scroll;
  border-top: 1px solid green;
  border-bottom: 1px solid green;
}

.table-sticky {

  th {
    position: sticky;
    top: 0;
    z-index: 2;
    border-top: 1px solid red !important;
    border-bottom: 2px solid red !important;
  }
}
<div class="table-sticky-container">
  <table class="table table-sticky">
    <thead class="thead-light">
      <tr>
        <th scope="col">Name</th>
        <th scope="col">Title</th>
        <th scope="col">ID</th>
        <th scope="col">Username</th>
      </tr>
    </thead>
    <tbody>
      <tr>
          <td>Malcolm Reynolds</td>
          <td>Captain</td>
          <td>9035749867</td>
          <td>mreynolds</td>
        </tr>
    </tbody>
  </table>
</div>

over 4 years ago · Santiago Trujillo
5 Respostas
Responde à pergunta

0

You can add

.table {
  border-collapse: separate;
}

But unfortunately it looks bad, a better solution will be adding a workaround using a pseudo-element.

th:after,
th:before {
  content: '';
  position: absolute;
  left: 0;
  width: 100%;
}

th:before {
  top: -1px;
  border-top: 1px solid red;
}

th:after {
  bottom: -1px;
  border-bottom: 2px solid red;
}

.table-sticky-container {
  height: 200px;
  overflow-y: scroll;
  border-top: 1px solid green;
  border-bottom: 1px solid green;
}

.table-sticky th {
  position: -webkit-sticky;
  position: sticky;
  top: 0;
  z-index: 2;
}

th:after,
th:before {
  content: '';
  position: absolute;
  left: 0;
  width: 100%;
}

th:before {
  top: -1px;
  border-top: 1px solid red;
}

th:after {
  bottom: -1px;
  border-bottom: 2px solid red;
}
<link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.min.css'>

<div class="table-sticky-container">
    <table class="table table-sticky">
      <thead class="thead-light">
        <tr>
          <th scope="col">Name</th>
          <th scope="col">Title</th>
          <th scope="col">ID</th>
          <th scope="col">Username</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>Malcolm Reynolds</td>
          <td>Captain</td>
          <td>9035749867</td>
          <td>mreynolds</td>
        </tr>
        <tr>
          <td>Zoe Washburne</td>
          <td>First Officer</td>
          <td>8908980980</td>
          <td>zwashburne</td>
        </tr>
        <tr>
          <td>Kaylee Frye</td>
          <td>Engineer</td>
          <td>6678687678</td>
          <td>kfrye</td>
        </tr>
        <tr>
          <td>Malcolm Reynolds</td>
          <td>Captain</td>
          <td>9035749867</td>
          <td>mreynolds</td>
        </tr>
        <tr>
          <td>Zoe Washburne</td>
          <td>First Officer</td>
          <td>8908980980</td>
          <td>zwashburne</td>
        </tr>
        <tr>
          <td>Kaylee Frye</td>
          <td>Engineer</td>
          <td>6678687678</td>
          <td>kfrye</td>
        </tr>
      </tbody>
    </table>
  </div>

The second solution

.table {
  border-collapse: collapse;
}

.table-sticky thead th {
  position: -webkit-sticky;
  position: sticky;
  top: 0;
  z-index: 2;
  box-shadow: inset 0 1px 0 red, inset 0 -2px 0 red;
 }
over 4 years ago · Santiago Trujillo Relatório

0

Another working solution (tested at latest Chrome and FF) - wrap th/td content with divs and use those divs borders instead of cell's borders.

<div class="wrapper">
  <table>
  <thead>
    <tr>
      <th>
        <div class="cell">head1</div>
      </th>
      <th>
        <div class="cell">head2</div>
      </th>
      <th>
        <div class="cell">head3</div>
      </th>
      <th>
        <div class="cell">head4</div>
      </th>
      <th>
        <div class="cell">head5</div>
      </th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>
        <div class="cell">1</div>
      </td>
      <td>
        <div class="cell">1</div>
      </td>
      <td>
        <div class="cell">1</div>
      </td>
      <td>
        <div class="cell">1</div>
      </td>
      <td>
        <div class="cell">1</div>
      </td>
    </tr>
    <tr>
      <td>
        <div class="cell">1</div>
      </td>
      <td>
        <div class="cell">1</div>
      </td>
      <td>
        <div class="cell">1</div>
      </td>
      <td>
        <div class="cell">1</div>
      </td>
      <td>
        <div class="cell">1</div>
      </td>
    </tr>
    <tr>
      <td>
        <div class="cell">1</div>
      </td>
      <td>
        <div class="cell">1</div>
      </td>
      <td>
        <div class="cell">1</div>
      </td>
      <td>
        <div class="cell">1</div>
      </td>
      <td>
        <div class="cell">1</div>
      </td>
    </tr>
  </tbody>
</table>
</div>

table {
  border-collapse: collapse;
  table-layout: fixed;
  width: 500px;
}

.wrapper {
  height: 150px;
  overflow: auto;
}

td, th {
  width: 150px;
  height: 50px;
  text-align: center;
  font-size: 32px;
  padding: 0;
}

th {
  position: sticky;
  top: 0;
  left: 0;
  background-color: #fff;
}

.cell {
  border: 1px solid black;
  height: 100%;
}

td .cell {
  border-top: none;
  border-left: none;
}

th .cell {
  border-left: none;
}

td:first-child .cell,
th:first-child .cell {
  border-left: 1px solid black;
}
over 4 years ago · Santiago Trujillo Relatório

0

You can add

.table {
  border-collapse: separate;
  border-spacing: 0;
}
over 4 years ago · Santiago Trujillo Relatório

0

Don't use border-collapse and draw the lines as follows :

td, th {
    border-bottom: 1px solid grey;
    border-right: 1px solid grey;
}

table {
    border-spacing: 0px;
    border-left: 1px solid grey
}

th {
    background-color:#c5e8ec;
    position: sticky;
    position: -webkit-sticky;
    border-top: 1px solid grey;
    top:0;
}
over 4 years ago · Santiago Trujillo Relatório

0

Here is CSB for mui material table, tested in Chrome, FF, Edge & Safari

https://codesandbox.io/s/mui-material-table-sticky-header-with-borders-fsmnd?file=/src/App.tsx

In this case key was in unsetting border-collapse on the table:

const TableSticky = (props: TableProps) => {
  const { sx, ...other } = props;
  return (
    <Table
      sx={{
        borderCollapse: "unset",
        borderLeft: border,
        ...sx,
      }}
      size="small"
      {...other}
    />
  );
};

It's also smart to use postion: sticky on header columns instead of the table:

const HeadCell = (props: TableCellProps) => {
  const { sx, ...other } = props;
  const theme = useTheme();

  return (
    <TableCell
      sx={{
        borderBottom: border,
        borderRight: border,
        borderTop: border,
        position: "sticky",
        top: 0,
        backgroundColor: theme.palette.background.default,
        ...sx
      }}
      {...other}
    />
  );
};
over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda