如何创build一个固定/冻结的左列和可滚动的主体的HTML表格?
如何创build一个固定/冻结的左列和可滚动的主体的HTML表格?
我需要一个简单的解决scheme 我知道这是类似的一些其他问题,如:
- 带有固定标题和固定列的HTML表?
- 如何在滚动时locking表格的第一行和第一列,可能使用JavaScript和CSS?
但是我只需要一个左列就可以被冻结,而我更喜欢一个简单的,无脚本的解决scheme。
如果你想要一个只有列水平滚动的表,你可以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>
这是一个有趣的jQuery插件,可以创build固定的标题和/或列 。 在演示页面上切换固定列以使其成为真实。
在固定宽度左栏的情况下, Eamon Nerbonne提供了最佳解决scheme。
如果左栏的宽度可变,我发现的最佳解决scheme是制作两个相同的表格,并将一个表格推向另一个表格。 演示: 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>
FWIW,这里是一个可以滚动头部和侧面的表格。
用position: fixed
左列。 (你大概会想用top
和left
样式来控制它发生的地方。)
有点晚了,但是当我为自己尝试解决scheme的时候,我碰到了这个线程。 假设你现在使用的是现代浏览器,我想出了一个使用CSS calc()的解决scheme来保证宽度的达到。
.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/> </th> </tr> <tr> <th>Normal Header</th> </tr> <tr> <th>Normal with extra line <br/> </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>
我拿着Earmon Nerbonne的答案,编辑它,用来填充整个宽度的表格。
<!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>
虽然固定列的宽度仍然需要设置一个值。
如果你在Webdevelopper地狱,需要使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使用条件注释。
无需添加任何插件,CSS可以做这个工作!
这个想法是使每一列中所有第一个单元格的位置为绝对的,并使宽度固定。 例如:
max-width: 125px; min-width: 125px; position: absolute;
这隐藏了第一列下的一些列的一些部分,所以添加一个空的第二列(添加第二个空的TD)与第一列的宽度相同。
我testing过,并且可以在Chrome和Firefox中使用。
Eamon Nerbonne,我在你的代码中改了一些css,现在好了(滚动条从第一行开始)
我只是添加两行:
.div : padding-left:5em; .headcol : background-color : #fff;
如果你正在开发更复杂的东西,并想要将多列固定/卡在左边,那么你可能需要这样的东西。
.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>
当我在我的Mac上testing它时,Opera对于之前的所有答案都是buggy。 如果在表格中滚动,则在通过第一个不固定列后,固定列将消失。 我继续写下面的代码。 它适用于我本地安装的所有浏览器。 我不知道如何处理它。
只要记住,如果你打算跳过一个表中的行而不是另一个,或者改变行的高度,你可能需要调整这个代码。
<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>
或者,使用预定大小的样式(例如,通过height:20em
),并使用overflow-y:scroll;
然后,你可以有一个巨大的tbody,它将独立于页面的其余部分进行滚动。
//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>; }
这里是最受欢迎的答案的另一种修改,但在第一列标签中处理可变长度的文本: http : //jsfiddle.net/ozx56n41/
基本上,我使用第二列来创build行高,就像之前提到过的那样。 但我的小提琴实际上不像上面提到的大多数。
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; }
在HTML5中,您可以使用CSS style.transform
。
但是,我build议你“在页面之间滑动”closures如果你在Mac上实现。
看代码示例
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>
添加这个在头上:
<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 });