代码之家  ›  专栏  ›  技术社区  ›  agsamek

如何创建具有固定/冻结左列和可滚动正文的HTML表?

  •  221
  • agsamek  · 技术社区  · 15 年前

    如何创建具有固定/冻结左列和可滚动正文的HTML表?

    我需要一个简单的解决方案。我知道这和其他一些问题类似,比如:

    但我只需要一个左列就可以冻结,我更喜欢一个简单的、无脚本的解决方案。

    20 回复  |  直到 6 年前
        1
  •  323
  •   arc    7 年前

    如果您想要一个只有列水平滚动的表,您可以 position: absolute 第一列(并显式指定其宽度),然后将整个表包装在 overflow-x: scroll 块。不过,别费心在IE7中尝试这个…

    相关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

        2
  •  25
  •   Rigel1121    10 年前

    This 是一个有趣的jquery插件,它创建了fixed 报头 和/或 . 在演示页面上,将Fixed列切换为true以查看其实际运行情况。

        3
  •  18
  •   Community CDub    7 年前

    如果左栏宽度固定,最佳解决方案是 Eamon Nerbonne .

    对于可变宽度的左列,我找到的最佳解决方案是创建两个相同的表,并将一个表推到另一个表之上。演示: http://jsfiddle.net/xG5QH/6/ .

    <!DOCTYPE html>
    <html>
    <head>
    <style type="text/css">
    /* important styles */
    
    .container {
       /* Attach fixed-th-table to this container,
          in order to layout fixed-th-table
          in the same way as scolled-td-table" */
       position: relative;
    
       /* Truncate fixed-th-table */
       overflow: hidden;
    }
    
    .fixed-th-table-wrapper td,
    .fixed-th-table-wrapper th,
    .scrolled-td-table-wrapper td,
    .scrolled-td-table-wrapper th {
       /* Set background to non-transparent color
          because two tables are one above another.
        */
       background: white;
    }
    .fixed-th-table-wrapper {
       /* Make table out of flow */
       position: absolute;
    }
    .fixed-th-table-wrapper th {
        /* Place fixed-th-table th-cells above 
           scrolled-td-table td-cells.
         */
        position: relative;
        z-index: 1;
    }
    .scrolled-td-table-wrapper td {
        /* Place scrolled-td-table td-cells
           above fixed-th-table.
         */
        position: relative;
    }
    .scrolled-td-table-wrapper {
       /* Make horizonal scrollbar if needed */
       overflow-x: auto;
    }
    
    
    /* Simulating border-collapse: collapse,
       because fixed-th-table borders
       are below ".scrolling-td-wrapper table" borders
    */
    
    table {
        border-spacing: 0;
    }
    td, th {
       border-style: solid;
       border-color: black;
       border-width: 1px 1px 0 0;
    }
    th:first-child {
       border-left-width: 1px;
    }
    tr:last-child td,
    tr:last-child th {
       border-bottom-width: 1px;
    }
    
    /* Unimportant styles */
    
    .container {
        width: 250px;
    }
    td, th {
       padding: 5px;
    }
    </style>
    </head>
    
    <body>
    <div class="container">
    
    <div class="fixed-th-table-wrapper">
    <!-- fixed-th-table -->
    <table>
        <tr>
             <th>aaaaaaa</th>
             <td>ccccccccccc asdsad asd as</td>
             <td>ccccccccccc asdsad asd as</td>
        </tr>
        <tr>
             <th>cccccccc</th>
             <td>xxxxxxxxxxxxxxxxxxxx yyyyyyyyyyyyyy zzzzzzzzzzzzz</td>
             <td>xxxxxxxxxxxxxxxxxxxx yyyyyyyyyyyyyy zzzzzzzzzzzzz</td>
        </tr>
    </table>
    </div>
    
    <div class="scrolled-td-table-wrapper">
    <!-- scrolled-td-table
         - same as fixed-th-table -->
    <table>
        <tr>
             <th>aaaaaaa</th>
             <td>ccccccccccc asdsad asd as</td>
             <td>ccccccccccc asdsad asd as</td>
        </tr>
        <tr>
             <th>cccccccc</th>
             <td>xxxxxxxxxxxxxxxxxxxx yyyyyyyyyyyyyy zzzzzzzzzzzzz</td>
             <td>xxxxxxxxxxxxxxxxxxxx yyyyyyyyyyyyyy zzzzzzzzzzzzz</td>
        </tr>
    </table>
    </div>
    
    </div>
    </body>
    </html>
    
        4
  •  14
  •   Adam Grant    10 年前

    fwiw,这里是一个头部和侧面固定的可滚动表格。

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

        5
  •  10
  •   Sergey Sergey    6 年前

    有点晚了,但我在为自己尝试解决方案时遇到了这个问题。假设您现在使用的是现代浏览器,我就提出了一个使用css calc()来帮助确保满足宽度要求的解决方案。

    .table-fixed-left table,
    .table-fixed-right table {
      border-collapse: collapse;
    }
    .table-fixed-right td,
    .table-fixed-right th,
    .table-fixed-left td,
    .table-fixed-left th {
      border: 1px solid #ddd;
      padding: 5px 5px;
    }
    .table-fixed-left {
      width: 120px;
      float: left;
      position: fixed;
      overflow-x: scroll;
      white-space: nowrap;
      text-align: left;
      border: 1px solid #ddd;
      z-index: 2;
    }
    .table-fixed-right {
      width: calc(100% - 145px);
      right: 15px;
      position: fixed;
      overflow-x: scroll;
      border: 1px solid #ddd;
      white-space: nowrap;
    }
    .table-fixed-right td,
    .table-fixed-right th {
      padding: 5px 10px;
    }
    <div class="table-fixed-left">
      <table>
        <tr>
          <th>Normal Header</th>
        </tr>
        <tr>
          <th>Header with extra line
            <br/>&nbsp;</th>
        </tr>
        <tr>
          <th>Normal Header</th>
        </tr>
        <tr>
          <th>Normal with extra line
            <br/>&nbsp;</th>
        </tr>
        <tr>
          <th>Normal Header</th>
        </tr>
        <tr>
          <th>Normal Header</th>
        </tr>
      </table>
    </div>
    <div class="table-fixed-right">
      <table>
        <tr>
          <th>Header</th>
          <th>Another header</th>
          <th>Header</th>
          <th>Header really really really really long</th>
        </tr>
        <tr>
          <td>Info Long</td>
          <td>Info
            <br/>with second line</td>
          <td>Info
            <br/>with second line</td>
          <td>Info Long</td>
        </tr>
        <tr>
          <td>Info Long</td>
          <td>Info Long</td>
          <td>Info Long</td>
          <td>Info Long</td>
        </tr>
        <tr>
          <td>Info
            <br/>with second line</td>
          <td>Info
            <br/>with second line</td>
          <td>Info
            <br/>with second line</td>
          <td>Info</td>
        </tr>
        <tr>
          <td>Info</td>
          <td>Info</td>
          <td>Info</td>
          <td>Info</td>
        </tr>
        <tr>
          <td>Info</td>
          <td>Info</td>
          <td>Info</td>
          <td>Info</td>
        </tr>
      </table>
    </div>

    希望这能帮助别人!

        6
  •  9
  •   chaos    15 年前

    左栏样式 position: fixed . (你大概想用 top left 样式以控制它的确切位置。)

        7
  •  7
  •   Jonathan.    11 年前

    我把厄尔蒙·内波恩的答案编辑下来,和满桌的桌子一起使用。

    http://jsfiddle.net/DYgD6/6/

    <!DOCTYPE html>
    <html><head><title>testdoc</title>
    <style type="text/css">
                body {
            font:16px Calibri;
        }
        table {
            border-collapse:separate;
            border-top: 3px solid grey;
        }
        td {
            margin:0;
            border:3px solid grey;
            border-top-width:0px;
            white-space:nowrap;
        }
        #outerdiv {
            position: absolute;
            top: 0;
            left: 0;
            right: 5em;
        }
        #innerdiv {
            width: 100%;
            overflow-x:scroll;
            margin-left: 5em;
            overflow-y:visible;
            padding-bottom:1px;
        }
        .headcol {
            position:absolute;
            width:5em;
            left:0;
            top:auto;
            border-right: 0px none black;
            border-top-width:3px;
            /*only relevant for first row*/
            margin-top:-3px;
            /*compensate for top border*/
        }
        .headcol:before {
            content:'Row ';
        }
        .long {
            background:yellow;
            letter-spacing:1em;
        }
    </style></head><body>
      <div id="outerdiv">
       <div id="innerdiv">
        <table>
            <tr>
                <td class="headcol">1</td>
                <td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
                <td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
            </tr>
            <tr>
                <td class="headcol">2</td>
                <td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
                <td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
            </tr>
            <tr>
                <td class="headcol">3</td>
                <td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
                <td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
            </tr>
            <tr>
                <td class="headcol">4</td>
                <td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
                <td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
            </tr>
            <tr>
                <td class="headcol">5</td>
                <td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
                <td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
            </tr>
            <tr>
                <td class="headcol">6</td>
                <td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
                <td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
            </tr>
            <tr>
                <td class="headcol">7</td>
                <td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
                <td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
            </tr>
            <tr>
                <td class="headcol">8</td>
                <td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
                <td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
            </tr>
            <tr>
                <td class="headcol">9</td>
                <td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
                <td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
            </tr>
        </table>
    </div></div>
    </body></html>
    

    不过,固定列的宽度仍然需要是一个设置值。

        8
  •  4
  •   kashesandr    8 年前

    如果您正在开发更复杂的东西,并且希望将多个列固定/固定在左侧,那么您可能需要这样的东西。

    .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>
        9
  •  3
  •   Barnee Emily    12 年前

    如果您身处Webdeveloper地狱,需要为IE6工作,下面是我使用的示例代码:

    <html>
    <head>
    <style type="text/css">
    .fixme {
        position: relative;
        left: expression( ( 20 + ( ignoreMe2 = document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft ) ) + 'px' );
        background-color: #FFFFFF;
    }
    </style>
    </head>
    <body>
    <table width="1500px" border="2">
        <tr>
            <td class="fixme" style="width: 200px;">loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet</td>
            <td>loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet </td>
            <td>loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet </td>
            <td>loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet </td>
        </tr>
        <tr>
            <td class="fixme" style="width: 200px;">loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet </td>
            <td>loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet </td>
            <td>loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet </td>
            <td>loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet </td>
        </tr>
        <tr>
            <td class="fixme" style="width: 200px;">loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet </td>
            <td>loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet </td>
            <td>loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet </td>
            <td>loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet </td>
        </tr>
        <tr>
            <td class="fixme" style="width: 200px;">loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet </td>
            <td>loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet </td>
            <td>loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet </td>
            <td>loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet </td>
        </tr>
    </table>
    </body>
    </html>
    

    这可能只适用于IE6,所以对CSS使用条件注释。

        10
  •  2
  •   Lane    10 年前

    不需要添加任何插件,CSS可以完成这项工作!!!

    其思想是使每列中所有第一个单元格的位置都是绝对的,并使宽度固定。前任:

    max-width: 125px;
    min-width: 125px;
    position: absolute;
    

    这将隐藏第一列下某些列的某些部分,因此添加一个与第一列宽度相同的空第二列(添加第二个空td)。

    我在Chrome和Firefox中测试过,这是可行的。

        11
  •  2
  •   Wu Yang Michael    10 年前

    eamon-nerbonne,我在代码中更改了一些CSS,现在更好了(滚动条从第一行开始)

    http://jsfiddle.net/At8L8/

    我只增加了两行:

    .div : padding-left:5em;
    .headcol : background-color : #fff;
    
        12
  •  1
  •   user2378892    11 年前

    当我在Mac上测试之前的所有答案时,Opera都是笨重的。 如果在表中滚动,则在通过第一个未固定列后,固定列将消失。我继续写下面的代码。它适用于我在本地安装的所有浏览器。我不知道怎么处理。

    请记住,如果您打算跳过一个表中的行而不是另一个表中的行,或者更改行的高度,则可能需要调整此代码。

    <table class = "fixedColumns">
        <tr><td> row 1 </td></tr>
        <tr><td> row 2 </td></tr>
    </table>
    <table class = "scrollableTable">
        <tr><td> col 1 </td> <td> col 2 </td><td> col 3 </td><td> col 4 </td></tr>
        <tr><td> col 1 </td> <td> col 2 </td><td> col 3 </td><td> col 4 </td></tr>
    </table>
    
    <style type = "text/css" >
        .fixedColumns
        {
            vertical-align:top;
            display: inline-block;
        }
        .scrollableTable
        {
            display: inline-block;
            width:50px;
            white-space: nowrap;
            overflow-x: scroll;
        }
    </style>
    
        13
  •  1
  •   Daniel    7 年前

    下面是对最流行答案的另一个修改,但是在第一列标签中处理可变长度的文本: http://jsfiddle.net/ozx56n41/

    基本上,我使用第二列来创建行高,就像前面提到的那样。但我的小提琴实际上工作,不像上面提到的那样。

    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;
    }
    
        14
  •  0
  •   Eamon Nerbonne    15 年前

    或者,用预先确定的尺寸(通过 height:20em ,例如)和使用 overflow-y:scroll;

    然后,您可以有一个巨大的tbody,它将独立于页面的其余部分滚动。

        15
  •  0
  •   Pradep    10 年前
    //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>;
    }
    
        16
  •  0
  •   alexander.polomodov Alex Hawking    6 年前

    $(document).ready(function() {
        var table = $('#example').DataTable( {
            scrollY:        "400px",
            scrollX:        true,
            scrollCollapse: true,
            paging:         true,
            fixedColumns:   {
                leftColumns: 3
            }
        } );
    } );
    <head>
    	<title>table</title>
    	
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <link rel="stylesheet" href="https://cdn.datatables.net/1.10.16/css/jquery.dataTables.min.css">
    <link rel="stylesheet" href="https://cdn.datatables.net/fixedcolumns/3.2.4/css/fixedColumns.dataTables.min.css">
    <script type="text/javascript" src="http://cdn.datatables.net/1.10.2/js/jquery.dataTables.min.js"></script>
    <script type="text/javascript" src="https://code.jquery.com/jquery-1.12.4.js"></script>
    <script type="text/javascript" src="https://cdn.datatables.net/1.10.16/js/jquery.dataTables.min.js"></script>
    <script type="text/javascript" src="https://cdn.datatables.net/fixedcolumns/3.2.4/js/dataTables.fixedColumns.min.js"></script>
    
    
    <style>
           th, td { white-space: nowrap; }
        div.dataTables_wrapper {
            width: 900px;
            margin: 0 auto;
        }
    </style>
    
    </head>
    <table id="example" class="stripe row-border order-column" style="width:100%">
            <thead>
                <tr>
                    <th>First name</th>
                    <th>Last name</th>
                    <th>Position</th>
                    <th>Office</th>
                    <th>Age</th>
                    <th>Start date</th>
                    <th>Salary</th>
                    <th>Extn.</th>
                    <th>E-mail</th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td>Tiger</td>
                    <td>Nixon</td>
                    <td>System Architect</td>
                    <td>Edinburgh</td>
                    <td>61</td>
                    <td>2011/04/25</td>
                    <td>$320,800</td>
                    <td>5421</td>
                    <td>t.nixon@datatables.net</td>
                </tr>
                <tr>
                    <td>Garrett</td>
                    <td>Winters</td>
                    <td>Accountant</td>
                    <td>Tokyo</td>
                    <td>63</td>
                    <td>2011/07/25</td>
                    <td>$170,750</td>
                    <td>8422</td>
                    <td>g.winters@datatables.net</td>
                </tr>
                <tr>
                    <td>Ashton</td>
                    <td>Cox</td>
                    <td>Junior Technical Author</td>
                    <td>San Francisco</td>
                    <td>66</td>
                    <td>2009/01/12</td>
                    <td>$86,000</td>
                    <td>1562</td>
                    <td>a.cox@datatables.net</td>
                </tr>
                <tr>
                    <td>Cedric</td>
                    <td>Kelly</td>
                    <td>Senior Javascript Developer</td>
                    <td>Edinburgh</td>
                    <td>22</td>
                    <td>2012/03/29</td>
                    <td>$433,060</td>
                    <td>6224</td>
                    <td>c.kelly@datatables.net</td>
                </tr>
                <tr>
                    <td>Airi</td>
                    <td>Satou</td>
                    <td>Accountant</td>
                    <td>Tokyo</td>
                    <td>33</td>
                    <td>2008/11/28</td>
                    <td>$162,700</td>
                    <td>5407</td>
                    <td>a.satou@datatables.net</td>
                </tr>
                <tr>
                    <td>Brielle</td>
                    <td>Williamson</td>
                    <td>Integration Specialist</td>
                    <td>New York</td>
                    <td>61</td>
                    <td>2012/12/02</td>
                    <td>$372,000</td>
                    <td>4804</td>
                    <td>b.williamson@datatables.net</td>
                </tr>
                <tr>
                    <td>Herrod</td>
                    <td>Chandler</td>
                    <td>Sales Assistant</td>
                    <td>San Francisco</td>
                    <td>59</td>
                    <td>2012/08/06</td>
                    <td>$137,500</td>
                    <td>9608</td>
                    <td>h.chandler@datatables.net</td>
                </tr>
                <tr>
                    <td>Rhona</td>
                    <td>Davidson</td>
                    <td>Integration Specialist</td>
                    <td>Tokyo</td>
                    <td>55</td>
                    <td>2010/10/14</td>
                    <td>$327,900</td>
                    <td>6200</td>
                    <td>r.davidson@datatables.net</td>
                </tr>
                <tr>
                    <td>Colleen</td>
                    <td>Hurst</td>
                    <td>Javascript Developer</td>
                    <td>San Francisco</td>
                    <td>39</td>
                    <td>2009/09/15</td>
                    <td>$205,500</td>
                    <td>2360</td>
                    <td>c.hurst@datatables.net</td>
                </tr>
                <tr>
                    <td>Sonya</td>
                    <td>Frost</td>
                    <td>Software Engineer</td>
                    <td>Edinburgh</td>
                    <td>23</td>
                    <td>2008/12/13</td>
                    <td>$103,600</td>
                    <td>1667</td>
                    <td>s.frost@datatables.net</td>
                </tr>
                <tr>
                    <td>Jena</td>
                    <td>Gaines</td>
                    <td>Office Manager</td>
                    <td>London</td>
                    <td>30</td>
                    <td>2008/12/19</td>
                    <td>$90,560</td>
                    <td>3814</td>
                    <td>j.gaines@datatables.net</td>
                </tr>
                 <tr>
                    <td>Sakura</td>
                    <td>Yamamoto</td>
                    <td>Support Engineer</td>
                    <td>Tokyo</td>
                    <td>37</td>
                    <td>2009/08/19</td>
                    <td>$139,575</td>
                    <td>9383</td>
                    <td>s.yamamoto@datatables.net</td>
                </tr>
                <tr>
                    <td>Thor</td>
                    <td>Walton</td>
                    <td>Developer</td>
                    <td>New York</td>
                    <td>61</td>
                    <td>2013/08/11</td>
                    <td>$98,540</td>
                    <td>8327</td>
                    <td>t.walton@datatables.net</td>
                </tr>
                <tr>
                    <td>Finn</td>
                    <td>Camacho</td>
                    <td>Support Engineer</td>
                    <td>San Francisco</td>
                    <td>47</td>
                    <td>2009/07/07</td>
                    <td>$87,500</td>
                    <td>2927</td>
                    <td>f.camacho@datatables.net</td>
                </tr>
                <tr>
                    <td>Serge</td>
                    <td>Baldwin</td>
                    <td>Data Coordinator</td>
                    <td>Singapore</td>
                    <td>64</td>
                    <td>2012/04/09</td>
                    <td>$138,575</td>
                    <td>8352</td>
                    <td>s.baldwin@datatables.net</td>
                </tr>
                <tr>
                    <td>Zenaida</td>
                    <td>Frank</td>
                    <td>Software Engineer</td>
                    <td>New York</td>
                    <td>63</td>
                    <td>2010/01/04</td>
                    <td>$125,250</td>
                    <td>7439</td>
                    <td>z.frank@datatables.net</td>
                </tr>
                <tr>
                    <td>Zorita</td>
                    <td>Serrano</td>
                    <td>Software Engineer</td>
                    <td>San Francisco</td>
                    <td>56</td>
                    <td>2012/06/01</td>
                    <td>$115,000</td>
                    <td>4389</td>
                    <td>z.serrano@datatables.net</td>
                </tr>
                <tr>
                    <td>Jennifer</td>
                    <td>Acosta</td>
                    <td>Junior Javascript Developer</td>
                    <td>Edinburgh</td>
                    <td>43</td>
                    <td>2013/02/01</td>
                    <td>$75,650</td>
                    <td>3431</td>
                    <td>j.acosta@datatables.net</td>
                </tr>
                <tr>
                    <td>Cara</td>
                    <td>Stevens</td>
                    <td>Sales Assistant</td>
                    <td>New York</td>
                    <td>46</td>
                    <td>2011/12/06</td>
                    <td>$145,600</td>
                    <td>3990</td>
                    <td>c.stevens@datatables.net</td>
                </tr>
                <tr>
                    <td>Hermione</td>
                    <td>Butler</td>
                    <td>Regional Director</td>
                    <td>London</td>
                    <td>47</td>
                    <td>2011/03/21</td>
                    <td>$356,250</td>
                    <td>1016</td>
                    <td>h.butler@datatables.net</td>
                </tr>
                <tr>
                    <td>Lael</td>
                    <td>Greer</td>
                    <td>Systems Administrator</td>
                    <td>London</td>
                    <td>21</td>
                    <td>2009/02/27</td>
                    <td>$103,500</td>
                    <td>6733</td>
                    <td>l.greer@datatables.net</td>
                </tr>
                <tr>
                    <td>Jonas</td>
                    <td>Alexander</td>
                    <td>Developer</td>
                    <td>San Francisco</td>
                    <td>30</td>
                    <td>2010/07/14</td>
                    <td>$86,500</td>
                    <td>8196</td>
                    <td>j.alexander@datatables.net</td>
                </tr>
                <tr>
                    <td>Shad</td>
                    <td>Decker</td>
                    <td>Regional Director</td>
                    <td>Edinburgh</td>
                    <td>51</td>
                    <td>2008/11/13</td>
                    <td>$183,000</td>
                    <td>6373</td>
                    <td>s.decker@datatables.net</td>
                </tr>
                <tr>
                    <td>Michael</td>
                    <td>Bruce</td>
                    <td>Javascript Developer</td>
                    <td>Singapore</td>
                    <td>29</td>
                    <td>2011/06/27</td>
                    <td>$183,000</td>
                    <td>5384</td>
                    <td>m.bruce@datatables.net</td>
                </tr>
                <tr>
                    <td>Donna</td>
                    <td>Snider</td>
                    <td>Customer Support</td>
                    <td>New York</td>
                    <td>27</td>
                    <td>2011/01/25</td>
                    <td>$112,000</td>
                    <td>4226</td>
                    <td>d.snider@datatables.net</td>
                </tr>
            </tbody>
        </table>

    通过数据表的帮助可以很容易地做到这一点。对数据表不熟悉的人,请参阅 https://datatables.net/ 它是一个插件,提供了很多功能。在给定的代码中,头是固定的,前3列是固定的,还有其他几个功能。

        17
  •  0
  •   Circuit Breaker    6 年前

    你可以使用 sticky 位置。 这是一个示例代码。这是HTML/CSS解决方案。不需要JS。

    HTML:

    <div class="view">
      <div class="wrapper"> 
        <table class="table">
          <thead>
            <tr>
              <th class="sticky-col first-col">Number</th>
              <th class="sticky-col second-col">First Name</th>
              <th>Last Name</th>
              <th>Employer</th>
           </tr>
          </thead>
           <tbody>
           <tr>
             <td class="sticky-col first-col">1</td>
             <td class="sticky-col second-col">Mark</td>
             <td>Ham</td>
             <td>Micro</td>
           </tr>
           <tr>
             <td class="sticky-col first-col">2</td>
             <td class="sticky-col second-col">Jacob</td>
             <td>Smith</td>
             <td>Adob Adob Adob AdobAdob Adob Adob Adob Adob</td>
           </tr>
           <tr>
             <td class="sticky-col first-col">3</td>
             <td class="sticky-col second-col">Larry</td>
             <td>Wen</td>
             <td>Goog Goog Goog GoogGoog Goog Goog Goog Goog Goog</td>
           </tr>
          </tbody>
        </table>
      </div>
    </div>  
    

    CSS:

    .view {
      margin: auto;
      width: 600px;
    }
    
    .wrapper {
      position: relative;
      overflow: auto;
      border: 1px solid black;
      white-space: nowrap;
    }
    
    .sticky-col {
      position: sticky;
      position: -webkit-sticky;    
      background-color: white;
    }
    
    .first-col {
      width: 100px;
      min-width: 100px;
      max-width: 100px;
      left: 0px;    
    }
    
    .second-col {
      width: 150px;
      min-width: 150px;
      max-width: 150px;
      left: 100px;    
    }
    

    引导码: https://www.bootply.com/g8pfBXOcY9

        18
  •  0
  •   Kushagr Arora    6 年前

    我没有检查这个问题的每一个答案,但是在分析了大多数答案之后,我发现在单元格或头部中有多行数据的情况下,设计失败了。我用JavaScript来解决这个问题。我希望有人能帮上忙。

    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>

    注意:“container”DIV只是为了证明代码与mobile view兼容。

        19
  •  -1
  •   Hajime    7 年前

    在HTML5中,可以使用CSS style.transform .
    但是,如果你在Mac上实现,我建议你“在页面之间滑动”关闭。

    look at sample codePen

    let l  = 0;
    let t  = 0;
    
    const MouseWheelHandler = (e) => {
      // vertical scroll
      if (e.deltaX == -0) {
        // t = t - e.deltaY
    
      // horizonal scroll
      } else if (e.deltaY == -0) {
        l = l - e.deltaX
        if (l >= 0) {
          l = 0;
          document.getElementById("gantt_task").style.transform = "translateX(1px)"
          document.getElementById("gantt_task_header").style.transform = "translateX(1px)"
          return false
        } 
        document.getElementById("gantt_task").style.transform = "translateX(" + l.toString() + "px)"
        document.getElementById("gantt_task_header").style.transform = "translateX(" + l.toString() + "px)"
      }
      return false;
    }
    
    window.addEventListener("wheel", MouseWheelHandler, false);
    .row {
      border-bottom: 1px solid #979A9A
    }
    #gantt_grid_header {
      height:   30px;
      width:    100px;
      position: fixed;
      z-index:  3;
      top:      0px;
      left:     0px;
      border:   1px solid #cecece;
      background-color: #F08080;
    }     
    
    #gantt_task_header {
      height:   30px;
      width:    400px;
      position: fixed;
      z-index:  2;
      top:      0px;
      left:     100px;
      border:   1px solid #cecece;
      background-color: #FFC300;
    }
    
    #gantt_grid {
      width:    100px; 
      height:   400px;
      position: absolute;
      left:     0px;
      top:      0px;
      z-index:  1;
      border:   1px solid #cecece;
      background-color: #DAF7A6;
    }
    
    #gantt_task {
      width:    400px; 
      height:   400px;
      position: absolute;
      left:     100px;
      top:      0px;
      border:   1px solid #cecece;
      background-color: #FF5733;
    }
    <html>
        <div id="gantt_grid_header">
          HEADER
        </div>
        <div id="gantt_grid">
          <div class="row">V Scroll OK</div>
          <div class="row">V Scroll OK</div>
          <div class="row">V Scroll OK</div>
          <div class="row">V Scroll OK</div>
          <div class="row">V Scroll OK</div>
          <div class="row">V Scroll OK</div>
          <div class="row">V Scroll OK</div>
          <div class="row">V Scroll OK</div>
          <div class="row">V Scroll OK</div>
        </div>
        <div id="gantt_task_header">
          DATA HEADER
        </div>
        <div id="gantt_task">
          <div class="row">Vertical,Horizenal Scroll OK</div>
          <div class="row">Vertical,Horizenal Scroll OK</div>
          <div class="row">Vertical,Horizenal Scroll OK</div>
          <div class="row">Vertical,Horizenal Scroll OK</div>
          <div class="row">Vertical,Horizenal Scroll OK</div>
          <div class="row">Vertical,Horizenal Scroll OK</div>
          <div class="row">Vertical,Horizenal Scroll OK</div>
          <div class="row">Vertical,Horizenal Scroll OK</div>
          <div class="row">Vertical,Horizenal Scroll OK</div>
        </div>
    </html>
        20
  •  -1
  •   Donald Duck user7392049    7 年前

    在头部添加:

    <link rel="stylesheet" type="text/css" href="/path/to/easyscrolltable.css">
    <script src="/path/to/easyscrolltable.js"></script>
    

    Javascript:

    $('table.ytable').EasyScrollableTable({
        'top'  : 1,  
        'left' : 1,  
        'class': '',
        'width': '100%',
        'height': 'auto',
        'footer': false,
        'hover': true
    });