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

后端 未结 25 1532
有刺的猬
有刺的猬 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:12

    Here is another modification of the most popular answer, but with handling of variable length of text in the first column labels: http://jsfiddle.net/ozx56n41/

    Basically, I'm using the second column for creating row height, like was mentioned. But my fiddle actually works unlike most mentioned above.

    HTML:

    <div id="outerdiv">
        <div id="innerdiv">
            <table>
                <tr>
                    <td class="headcol"><div>This is a long label</div></td>
                    <td class="hiddenheadcol"><div>This is a long label</div></td>
                    <td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
                    <td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
                </tr>
                <tr>
                    <td class="headcol"><div>Short label</div></td>
                    <td class="hiddenheadcol"><div>Short label</div></td>
                    <td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
                    <td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
                </tr>
            </table>
        </div>
    </div>
    

    CSS:

    body {
        font: 16px Calibri;
    }
    #outerdiv {
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        width: 100%;
        border-top: 1px solid grey;
    }
    #innerdiv {
        overflow-x: scroll;
        margin-left: 100px;
        overflow-y: visible;
        padding-bottom: 1px;
    }
    table {
        border-collapse:separate;
    }
    td {
        margin: 0;
        border: 1px solid grey;
        border-top-width: 0;
        border-left-width: 0px;
        padding: 10px;
    }
    td.headcol {
        /* Frozen 1st column */
        position: absolute;
        left: 0;
        top: auto;
        border-bottom-width: 1px;
        padding: 0;
        border-left-width: 1px;
    }
    td.hiddenheadcol {
        /* Hidden 2nd column to create height */
        max-width: 0;
        visibility: hidden;
        padding: 0;
    }
    td.headcol div {
        /* Text container in the 1st column */
        width: 100px;
        max-width: 100px;
        background: lightblue;
        padding: 10px;
        box-sizing: border-box;
    }
    td.hiddenheadcol div {
        /* Text container in the 2nd column */
        width: 100px;
        max-width: 100px;
        background: red;
        padding: 10px;
    }
    td.long {
        background:yellow;
        letter-spacing:1em;
    }
    
    0 讨论(0)
  • 2020-11-21 23:12

    I just made the right-most sticky column of a table sticky.

    th:last-of-type {
     position: sticky;
     right: 0;
     width: 120px;
     background: #f7f7f7;
    }
    
    
    td:last-of-type {
     position: sticky;
     right: 0;
     background: #f7f7f7;
     width: 120px;
    }
    

    I believe if you'll do {position: sticky; left: 0;}, you'll get the desired result.

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

    If you don't want to touch your current table too much you can make a fake pinned column in front of the table.

    The example shows one way of doing it without JS

    table {
      border-collapse: collapse;
      border-spacing: 0;
      border: 1px solid #ffffd;
      min-width: 600px;
    }
    
    .labels {
      display:flex;
      flex-direction: column
    }
    
    .overflow {
      overflow-x: scroll;
      min width: 400px;
      flex: 1;
    }
    
    .label {
      display: flex;
      align-items: center;
      white-space:nowrap;
      padding: 10px;
      flex: 1;
      border-bottom: 1px solid #ffffd;
      border-right: 2px solid #ffffd;
    }
    
    .label:last-of-type {
      overflow-x: scroll;
      border-bottom: 0;
    }
    
    td {
      border: 1px solid #ffffd;
      padding: 10px;
    }
    
    .flex {
      display:flex;
      max-width: 600px;
      padding: 0;
      border: 5px solid #ffffd;
    }
    <div class="flex">
      <div class="labels">
        <span class="label">Label 1</span>
        <span class="label">Lorem ipsum dolor sit amet.</span>
        <span class="label">Lorem ipsum dolor.</span>
      </div>
      <div class="overflow">
        <table>
          <tr>
            <td class="long">Lorem ipsum dolor sit amet consectetur adipisicing</td>
            <td class="long">Lorem ipsum dolor sit amet consectetur adipisicing</td>
          </tr>
          <tr>
            <td class="long">Lorem ipsum dolor sit amet consectetur adipisicing</td>
            <td class="long">Lorem ipsum dolor sit amet consectetur adipisicing</td>
          </tr>
          <tr>
            <td class="long">Lorem ipsum dolor sit amet consectetur adipisicing</td>
            <td class="long">Lorem ipsum dolor sit amet consectetur adipisicing</td>
          </tr>
      </table>
      </div>
    </div>

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

    Eamon Nerbonne, I changed some css in your code and it's better now(the scroll bar starts from the first row)

    http://jsfiddle.net/At8L8/

    I just add two line :

    .div : padding-left:5em;
    .headcol : background-color : #fff;
    
    0 讨论(0)
  • 2020-11-21 23:20

    If you want a table where only the columns scroll horizontally, you can position: absolute the first column (and specify its width explicitly), and then wrap the entire table in an overflow-x: scroll block. Don't bother trying this in IE7, however...

    Relevant HTML & CSS:

    table {
      border-collapse: separate;
      border-spacing: 0;
      border-top: 1px solid grey;
    }
    
    td, th {
      margin: 0;
      border: 1px solid grey;
      white-space: nowrap;
      border-top-width: 0px;
    }
    
    div {
      width: 500px;
      overflow-x: scroll;
      margin-left: 5em;
      overflow-y: visible;
      padding: 0;
    }
    
    .headcol {
      position: absolute;
      width: 5em;
      left: 0;
      top: auto;
      border-top-width: 1px;
      /*only relevant for first row*/
      margin-top: -1px;
      /*compensate for top border*/
    }
    
    .headcol:before {
      content: 'Row ';
    }
    
    .long {
      background: yellow;
      letter-spacing: 1em;
    }
    <div>
    <table>
            <tr><th class="headcol">1</th><td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td><td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td></tr>
            <tr><th class="headcol">2</th><td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td><td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td></tr>
            <tr><th class="headcol">3</th><td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td><td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td></tr>
            <tr><th class="headcol">4</th><td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td><td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td></tr>
            <tr><th class="headcol">5</th><td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td><td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td></tr>
            <tr><th class="headcol">6</th><td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td><td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td></tr>
    </table>
    </div>

    Fiddle

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

    Style the left column with position: fixed. (You'll presumably want to use top and left styles to control where exactly it occurs.)

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