Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hide scrolled content in table containing sticky columns with border spacing

Tags:

html

css

I have a table that uses border-collapse: separate and border-spacing to add spacing between rows and columns. I also use position: sticky for the first two columns, so when the user scrolls horizontally, those columns remain frozen.

As you can see in the snippet below, when you scroll horizontally, the sticky columns remain in place. But as you scroll, you can see the other parts of the table in the gaps between the sticky columns. I want any content that moves behind these sticky columns to be hidden. Any help would be appreciated.

.table-wrapper {
  width: 250px;
  overflow: scroll;
}

table {
  border-collapse: separate;
  border-spacing: 10px;
}

th {
  background-color: #00aeef;
  border-radius: 5px;
}

table tr td:first-child {
  position: sticky;
  z-index: 2;
  left: 0;
  background-color: white;
}

table tr th:first-child {
  position: sticky;
  z-index: 2;
  left: 0;
  background-color: #00aeef;
}

table tr td:nth-child(2) {
  position: sticky;
  z-index: 2;
  left: 45px;
  background-color: white;
}

table tr th:nth-child(2) {
  position: sticky;
  z-index: 2;
  left: 45px;
  background-color: #00aeef;
}
<div class="table-wrapper">
  <table>
    <thead>
      <tr>
        <th>Col1</th>
        <th>Col2</th>
        <th>Col3</th>
        <th>Col4</th>
        <th>Col5</th>
        <th>Col6</th>
        <th>Col7</th>
        <th>Col8</th>
        <th>Col9</th>
      </tr>
    </thead>
    <tbody>
      <td>Col1</td>
      <td>Col2</td>
      <td>Col3</td>
      <td>Col4</td>
      <td>Col5</td>
      <td>Col6</td>
      <td>Col7</td>
      <td>Col8</td>
      <td>Col9</td>
    </tbody>
  </table>
</div>

Update I'm able to somewhat achieve this effect by using a box-shadow, but it's not perfect. You can still see the overlap with the first column.

.table-wrapper {
  width: 250px;
  overflow: scroll;
}

table {
  border-collapse: separate;
  border-spacing: 10px;
}

th {
  background-color: #00aeef;
  border-radius: 5px;
}

table tr td:first-child {
  position: sticky;
  z-index: 2;
  left: 0;
  background-color: white;
  box-shadow: 10px 0 white;
}

table tr th:first-child {
  position: sticky;
  z-index: 2;
  left: 0;
  background-color: #00aeef;
  box-shadow: 10px 0 white;
}

table tr td:nth-child(2) {
  position: sticky;
  z-index: 2;
  left: 45px;
  background-color: white;
  box-shadow: -10px 0 white;
}

table tr th:nth-child(2) {
  position: sticky;
  z-index: 2;
  left: 45px;
  background-color: #00aeef;
  box-shadow: -10px 0 white;
}
<div class="table-wrapper">
  <table>
    <thead>
      <tr>
        <th>Col1</th>
        <th>Col2</th>
        <th>Col3</th>
        <th>Col4</th>
        <th>Col5</th>
        <th>Col6</th>
        <th>Col7</th>
        <th>Col8</th>
        <th>Col9</th>
      </tr>
    </thead>
    <tbody>
      <td>Col1</td>
      <td>Col2</td>
      <td>Col3</td>
      <td>Col4</td>
      <td>Col5</td>
      <td>Col6</td>
      <td>Col7</td>
      <td>Col8</td>
      <td>Col9</td>
    </tbody>
  </table>
</div>
like image 844
JoshG Avatar asked Dec 17 '25 21:12

JoshG


1 Answers

You can achieve this using JavaScript.

var th = document.querySelectorAll("th");
var td = document.querySelectorAll("td");

var wrapper = document.querySelector(".table-wrapper");

var w1 = th[1].getClientRects()[0].width;

wrapper.addEventListener("scroll", function () {
  for (var i = 0; i < th.length; i++) {
    e = th[i + 1]; //Selecting the next element 
    if (
      e != undefined &&
      i > 0 &&
      th[1].getClientRects()[0].x >= e.getClientRects()[0].x - w1   // Main condition to check if they overlap
    ) {
      e.style.visibility = "hidden";
    } else if (e != undefined) {
      e.style.visibility = "visible";
    }
  }
  for (var i = 0; i < td.length; i++) {
    e = td[i + 1];
    if (
      e != undefined &&
      i > 0 &&
      td[1].getClientRects()[0].x >= e.getClientRects()[0].x - w1
    ) {
      e.style.visibility = "hidden";
    } else if (e != undefined) {
      e.style.visibility = "visible";
    }
  }
});
.table-wrapper {
    width: 250px;
    overflow: scroll;
}

table {
    border-collapse: separate;
    border-spacing: 10px;
}

th {
    background-color: #00aeef;
    border-radius: 5px;
}

table tr td:first-child {
    position: sticky;
    z-index: 2;
    left: 0;
    background-color: white;
}

table tr th:first-child {
    position: sticky;
    z-index: 2;
    left: 0;
    background-color: #00aeef;
}

table tr td:nth-child(2) {
    position: sticky;
    z-index: 2;
    left: 45px;
    background-color: white;
}

table tr th:nth-child(2) {
    position: sticky;
    z-index: 2;
    left: 45px;
    background-color: #00aeef;
}
<link rel="stylesheet" href="style.css">

<body>

    <div class="table-wrapper">
        <table>
            <thead>
                <tr>
                    <th>Col1</th>
                    <th>Col2</th>
                    <th>Col3</th>
                    <th>Col4</th>
                    <th>Col5</th>
                    <th>Col6</th>
                    <th>Col7</th>
                    <th>Col8</th>
                    <th>Col9</th>
                </tr>
            </thead>
            <tbody>
                <td>Col1</td>
                <td>Col2</td>
                <td>Col3</td>
                <td>Col4</td>
                <td>Col5</td>
                <td>Col6</td>
                <td>Col7</td>
                <td>Col8</td>
                <td>Col9</td>
            </tbody>
        </table>
    </div>
    <script src="./script.js"></script>
</body>
like image 52
TechySharnav Avatar answered Dec 20 '25 13:12

TechySharnav



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!