Scroll-snap to table header with column span

316 Views Asked by At

Trying to build a table with horizontal scrolling and snapping to the yellow header columns which span over multiple columns. They should snap to the end of the red column, but always snap to the beginning of the table. What am I missing?

div {
  overflow: auto;
  scroll-snap-type: both mandatory;
  width: 200px;
  /* to force scroll */
}

table {}

table thead .group {
  background: yellow;
  padding-right: 12px;
  background-clip: padding-box;
  scroll-snap-align: start;
}

table thead th {
  text-align: left;
}

table tbody th {
  position: sticky;
  left: 0;
  white-space: nowrap;
  background: red;
  scroll-snap-align: start;
}

table tbody td,
table tbody th {
  padding-right: 12px;
}
<div>
  <table>
    <thead>
      <tr>
        <th/>
        <th colspan="4" class="group">
          Group 1
        </th>

        <th colspan="4" class="group">
          Group 2
        </th>

        <th colspan="4" class="group">
          Group 3
        </th>

        <th colspan="4" class="group">
          Group 4
        </th>

      </tr>
      <tr>
        <th/>
        <th>One</th>
        <th>Two</th>
        <th>Three</th>
        <th>Four</th>

        <th>One</th>
        <th>Two</th>
        <th>Three</th>
        <th>Four</th>

        <th>One</th>
        <th>Two</th>
        <th>Three</th>
        <th>Four</th>

        <th>One</th>
        <th>Two</th>
        <th>Three</th>
        <th>Four</th>

      </tr>
    </thead>

    <tbody>
      <tr>
        <th>Sticky</th>
        <td>Value 1</td>
        <td>Value 2</td>
        <td>Value 3</td>
        <td>Value 4</td>

        <td>Value 1</td>
        <td>Value 2</td>
        <td>Value 3</td>
        <td>Value 4</td>

        <td>Value 1</td>
        <td>Value 2</td>
        <td>Value 3</td>
        <td>Value 4</td>

        <td>Value 1</td>
        <td>Value 2</td>
        <td>Value 3</td>
        <td>Value 4</td>
      </tr>
    </tbody>
  </table>
</div>

1

There are 1 best solutions below

3
Brett Donald On

The specs don’t provide the capability you are looking for. They only provide the ability to snap elements to a containing element (scroll container); either:

  1. the start (left) of your chosen element (.group) to the start (left) of its scroll container,
  2. the centre of your chosen element (.group) to the centre of its scroll container, or
  3. the end (right) of your chosen element (.group) to the end (right) of its scroll container.

You are wanting to snap <th> elements relative to their first (sticky) sibling, another <th>. I’m afraid you're out of luck, at least with building something like this using HTML and CSS alone.