How do I create an HTML table with a fixed/frozen left column and a scrollable body?

后端 未结 25 1550
有刺的猬
有刺的猬 2020-11-21 22:27

I need a simple solution. I know it\'s similar to some other questions, like:

  • HTML table with fixed headers and a fixed column?
  • How can I lock the fir
相关标签:
25条回答
  • 2020-11-21 23:25
    //If the table has tbody and thead, make them the relative container in which we can fix td and th as absolute
    
    table tbody {
        position: relative;
    }
    
    table thead {
        position: relative;
    }
    
    //Make both the first header and first data cells (First column) absolute so that it sticks to the left
    
    table td:first-of-type {
        position: absolute;
    }
    
    table th:first-of-type {
        position: absolute;
    }
    
    //Move Second column according to the width of column 1 
    
    table td:nth-of-type(2) {
        padding-left: <Width of column 1>;
    }
    
    table th:nth-of-type(2) {
        padding-left: <Width of column 1>;
    }
    
    0 讨论(0)
  • 2020-11-21 23:26

    FWIW, here is a table that is scrollable with the head and side fixed.

    http://codepen.io/ajkochanowicz/pen/KHdih

    0 讨论(0)
  • 2020-11-21 23:27

    If you're developing something more complicated and want multiple columns to be fixed/stuck to the left, you'll probably need something like this.

    .wrapper {
        overflow-x: scroll;
    }
    
    td {
        min-width: 50px;
    }
    
    .fixed {
        position: absolute;
        background: #aaa;
    }
    <div class="content" style="width: 400px">
    
      <div class="wrapper" style="margin-left: 100px">
    
          <table>
            <thead>
              <tr>
                <th class="fixed" style="left: 0px">aaa</th>
                <th class="fixed" style="left: 50px">aaa2</th>
                <th>a</th>
                <th>b</th>
                <th>c</th>
                <th>d</th>
                <th>e</th>
                <th>f</th>
                <th>a</th>
                <th>b</th>
                <th>c</th>
                <th>d</th>
                <th>e</th>
                <th>f</th>
                <th>a</th>
                <th>b</th>
                <th>c</th>
                <th>d</th>
                <th>e</th>
                <th>f</th>
                <th>a</th>
                <th>b</th>
                <th>c</th>
                <th>d</th>
                <th>e</th>
                <th>f</th>        
              </tr>
            </thead>
            <tbody>
              <tr>
                <td class="fixed" style="left: 0px">aaa</td>
                <td class="fixed" style="left: 50px">aaa2</td>
                <td>a</td>
                <td>b</td>
                <td>c</td>
                <td>d</td>
                <td>e</td>
                <td>f</td>
                <td>a</td>
                <td>b</td>
                <td>c</td>
                <td>d</td>
                <td>e</td>
                <td>f</td>
                <td>a</td>
                <td>b</td>
                <td>c</td>
                <td>d</td>
                <td>e</td>
                <td>f</td>
                <td>a</td>
                <td>b</td>
                <td>c</td>
                <td>d</td>
                <td>e</td>
                <td>f</td>
              </tr>
              <tr>
                <td class="fixed" style="left: 0">bbb</td>
                <td class="fixed" style="left: 50px">bbb2</td>
                <td>a</td>
                <td>b</td>
                <td>c</td>
                <td>d</td>
                <td>e</td>
                <td>f</td>
                <td>a</td>
                <td>b</td>
                <td>c</td>
                <td>d</td>
                <td>e</td>
                <td>f</td>
                <td>a</td>
                <td>b</td>
                <td>c</td>
                <td>d</td>
                <td>e</td>
                <td>f</td>
                <td>a</td>
                <td>b</td>
                <td>c</td>
                <td>d</td>
                <td>e</td>
                <td>f</td>
              </tr>
            </tbody>
          </table>
    
      </div>
    
    </div>

    0 讨论(0)
  • 2020-11-21 23:28

    Alternatively, style the tbody with a predetermined size (via height:20em, for example) and use overflow-y:scroll;

    Then, you can have a huge tbody, which will scroll independently of the rest of the page.

    0 讨论(0)
  • 2020-11-21 23:29

    For most browsers released after 2017:

    You can use the position: sticky. See https://caniuse.com/#feat=css-sticky.

    There is no need for a fixed width column.

    Run the code snippet below to see how it works.

    .tscroll {
      width: 400px;
      overflow-x: scroll;
      margin-bottom: 10px;
      border: solid black 1px;
    }
    
    .tscroll table td:first-child {
      position: sticky;
      left: 0;
      background-color: #ffffd;
    }
    
    .tscroll td, .tscroll th {
      border-bottom: dashed #888 1px;
    }
    <html>
    <div class="tscroll">
      <table>
        <thead>
          <tr>
            <th></th>
            <th colspan="5">Heading 1</th>
            <th colspan="8">Heading 2</th>
            <th colspan="4">Heading 3</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td>9:00</td>
            <td>AAA</td>
            <td>BBB</td>
            <td>CCC</td>
            <td>DDD</td>
            <td>EEE</td>
            <td>FFF</td>
            <td>GGG</td>
            <td>HHH</td>
            <td>III</td>
            <td>JJJ</td>
            <td>KKK</td>
            <td>LLL</td>
            <td>MMM</td>
            <td>NNN</td>
            <td>OOO</td>
            <td>PPP</td>
            <td>QQQ</td>
          </tr>
          <tr>
            <td>10:00</td>
            <td>AAA</td>
            <td>BBB</td>
            <td>CCC</td>
            <td>DDD</td>
            <td>EEE</td>
            <td>FFF</td>
            <td>GGG</td>
            <td>HHH</td>
            <td>III</td>
            <td>JJJ</td>
            <td>KKK</td>
            <td>LLL</td>
            <td>MMM</td>
            <td>NNN</td>
            <td>OOO</td>
            <td>PPP</td>
            <td>QQQ</td>
          </tr>
          <tr>
            <td>11:00</td>
            <td>AAA</td>
            <td>BBB</td>
            <td>CCC</td>
            <td>DDD</td>
            <td>EEE</td>
            <td>FFF</td>
            <td>GGG</td>
            <td>HHH</td>
            <td>III</td>
            <td>JJJ</td>
            <td>KKK</td>
            <td>LLL</td>
            <td>MMM</td>
            <td>NNN</td>
            <td>OOO</td>
            <td>PPP</td>
            <td>QQQ</td>
          </tr>
          <tr>
            <td>12:00</td>
            <td>AAA</td>
            <td>BBB</td>
            <td>CCC</td>
            <td>DDD</td>
            <td>EEE</td>
            <td>FFF</td>
            <td>GGG</td>
            <td>HHH</td>
            <td>III</td>
            <td>JJJ</td>
            <td>KKK</td>
            <td>LLL</td>
            <td>MMM</td>
            <td>NNN</td>
            <td>OOO</td>
            <td>PPP</td>
            <td>QQQ</td>
          </tr>
          <tr>
            <td>13:00</td>
            <td>AAA</td>
            <td>BBB</td>
            <td>CCC</td>
            <td>DDD</td>
            <td>EEE</td>
            <td>FFF</td>
            <td>GGG</td>
            <td>HHH</td>
            <td>III</td>
            <td>JJJ</td>
            <td>KKK</td>
            <td>LLL</td>
            <td>MMM</td>
            <td>NNN</td>
            <td>OOO</td>
            <td>PPP</td>
            <td>QQQ</td>
          </tr>
          <tr>
            <td>14:00</td>
            <td>AAA</td>
            <td>BBB</td>
            <td>CCC</td>
            <td>DDD</td>
            <td>EEE</td>
            <td>FFF</td>
            <td>GGG</td>
            <td>HHH</td>
            <td>III</td>
            <td>JJJ</td>
            <td>KKK</td>
            <td>LLL</td>
            <td>MMM</td>
            <td>NNN</td>
            <td>OOO</td>
            <td>PPP</td>
            <td>QQQ</td>
          </tr>
          <tr>
            <td>15:00</td>
            <td>AAA</td>
            <td>BBB</td>
            <td>CCC</td>
            <td>DDD</td>
            <td>EEE</td>
            <td>FFF</td>
            <td>GGG</td>
            <td>HHH</td>
            <td>III</td>
            <td>JJJ</td>
            <td>KKK</td>
            <td>LLL</td>
            <td>MMM</td>
            <td>NNN</td>
            <td>OOO</td>
            <td>PPP</td>
            <td>QQQ</td>
          </tr>
          <tr>
            <td>16:00</td>
            <td>AAA</td>
            <td>BBB</td>
            <td>CCC</td>
            <td>DDD</td>
            <td>EEE</td>
            <td>FFF</td>
            <td>GGG</td>
            <td>HHH</td>
            <td>III</td>
            <td>JJJ</td>
            <td>KKK</td>
            <td>LLL</td>
            <td>MMM</td>
            <td>NNN</td>
            <td>OOO</td>
            <td>PPP</td>
            <td>QQQ</td>
          </tr>
          <tr>
            <td>17:00</td>
            <td>AAA</td>
            <td>BBB</td>
            <td>CCC</td>
            <td>DDD</td>
            <td>EEE</td>
            <td>FFF</td>
            <td>GGG</td>
            <td>HHH</td>
            <td>III</td>
            <td>JJJ</td>
            <td>KKK</td>
            <td>LLL</td>
            <td>MMM</td>
            <td>NNN</td>
            <td>OOO</td>
            <td>PPP</td>
            <td>QQQ</td>
          </tr>
        </tbody>
        </table>
    </div>

    0 讨论(0)
  • 2020-11-21 23:29

    I didn't check each and every answer for this question, but after analyzing most of them I found that design fails in case of multiline data in cells or head. I used Javascript to solve this. I hope someone finds this helpful.

    https://codepen.io/kushagrarora/pen/zeYaoY

    var freezeTables = document.getElementsByClassName("freeze-pane");
    
    [].forEach.call(freezeTables, ftable => {
      var wrapper = document.createElement("div");
      wrapper.className = "freeze-pane-wrapper";
      var scroll = document.createElement("div");
      scroll.className = "freeze-pane-scroll";
    
      wrapper.appendChild(scroll);
    
      ftable.parentNode.replaceChild(wrapper, ftable);
    
      scroll.appendChild(ftable);
    
      var heads = ftable.querySelectorAll("th:first-child");
    
      let maxWidth = 0;
    
      [].forEach.call(heads, head => {
        var w = window
          .getComputedStyle(head)
          .getPropertyValue("width")
          .split("px")[0];
        if (Number(w) > Number(maxWidth)) maxWidth = w;
      });
    
      ftable.parentElement.style.marginLeft = maxWidth + "px";
      ftable.parentElement.style.width = "calc(100% - " + maxWidth + "px)";
      [].forEach.call(heads, head => {
        head.style.width = maxWidth + "px";
        var restRowHeight = window
          .getComputedStyle(head.nextElementSibling)
          .getPropertyValue("height");
        var headHeight = window.getComputedStyle(head).getPropertyValue("height");
        if (headHeight > restRowHeight)
          head.nextElementSibling.style.height = headHeight;
        else head.style.height = restRowHeight;
      });
    });
    @import url("https://fonts.googleapis.com/css?family=Open+Sans");
    * {
      font-family: "Open Sans", sans-serif;
    }
    
    .container {
      width: 400px;
      height: 90vh;
      border: 1px solid black;
      overflow: hidden;
    }
    
    table,
    th,
    td {
      border: 1px solid #eee;
    }
    
    .table {
      width: 100%;
      margin-bottom: 1rem;
      table-layout: fixed;
      border-collapse: collapse;
    }
    
    .freeze-pane-wrapper {
      position: relative;
    }
    
    .freeze-pane-scroll {
      overflow-x: scroll;
      overflow-y: visible;
    }
    
    .freeze-pane th:first-child {
      position: absolute;
      background-color: pink;
      left: 0;
      top: auto;
      max-width: 40%;
    }
    <div class="container">
      <table class="freeze-pane">
        <tbody>
          <tr>
            <th>
              <p>Model</p>
            </th>
            <th>
              <p>Mercedes Benz AMG C43 4dr</p>
            </th>
            <th>
              <p>Audi S4 Premium 4dr</p>
            </th>
            <th>
              <p>BMW 440i 4dr sedan</p>
            </th>
          </tr>
          <tr>
            <th>
              <p>Passenger capacity</p>
            </th>
            <td>
              <p>5</p>
            </td>
            <td>
              <p>5</p>
            </td>
            <td>
              <p>5</p>
            </td>
          </tr>
          <tr>
            <th>
              <p>Front (Head/Shoulder/Leg) (In.)</p>
            </th>
            <td>
              <p>37.1/55.3/41.7</p>
            </td>
            <td>
              <p>38.9/55.9/41.3</p>
            </td>
            <td>
              <p>39.9/54.8/42.2</p>
            </td>
          </tr>
          <tr>
            <th>
              <p>Second (Head/Shoulder/Leg) (In.)</p>
            </th>
            <td>
              <p>37.1/55.5/35.2</p>
            </td>
            <td>
              <p>37.4/54.5/35.7</p>
            </td>
            <td>
              <p>36.9/54.3/33.7</p>
            </td>
          </tr>
        </tbody>
      </table>
    </div>

    Note: the "container" div is just to demonstrate that code is compatible with mobile-view.

    0 讨论(0)
提交回复
热议问题