我需要一个简单的解决方案。我知道这和其他一些问题类似,比如:
固定标题和固定列的HTML表? 我如何锁定表的第一行和第一列时滚动,可能使用JavaScript和CSS?
但我只需要一个单独的左列被冻结,我更喜欢一个简单的和无脚本的解决方案。
我需要一个简单的解决方案。我知道这和其他一些问题类似,比如:
固定标题和固定列的HTML表? 我如何锁定表的第一行和第一列时滚动,可能使用JavaScript和CSS?
但我只需要一个单独的左列被冻结,我更喜欢一个简单的和无脚本的解决方案。
当前回答
我没有检查这个问题的每个答案,但在分析了大部分答案后,我发现在单元格或头部的多行数据情况下,设计会失败。我使用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兼容。
其他回答
如果你不想过多地触碰你现在的桌子,你可以在桌子前面做一个假的固定列。
这个例子展示了一种不使用JS的方法
table { border-collapse: collapse; border-spacing: 0; border: 1px solid #ddd; 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 #ddd; border-right: 2px solid #ddd; } .label:last-of-type { overflow-x: scroll; border-bottom: 0; } td { border: 1px solid #ddd; padding: 10px; } .flex { display:flex; max-width: 600px; padding: 0; border: 5px solid #ddd; } <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>
如果您想要一个只有列水平滚动的表,您可以定位:绝对第一列(并显式指定其宽度),然后将整个表包装在一个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>
小提琴
不需要添加任何插件,CSS可以做这个工作!!
其思想是使每列中所有第一个单元格的位置是绝对的,宽度是固定的。例:
max-width: 125px;
min-width: 125px;
position: absolute;
这将在第一列下面隐藏一些列的某些部分,因此添加一个空的第二列(添加第二个空td),其宽度与第一列相同。
我进行了测试,在Chrome和Firefox中都可以使用。
.div1 {
width: 600px;
height: 400px;
overflow: scroll;
border: 1px solid #777777;
}
.div1 table {
border-spacing: 0;
}
.div1 th {
border-left: none;
border-right: 1px solid #bbbbbb;
padding: 5px;
width: 80px;
min-width: 80px;
position: sticky;
top: 0;
background: #727272;
color: #e0e0e0;
font-weight: normal;
}
.div1 td {
border-left: none;
border-right: 1px solid #bbbbbb;
border-bottom: 1px solid #bbbbbb;
padding: 5px;
width: 80px;
min-width: 80px;
}
.div1 th:nth-child(1),
.div1 td:nth-child(1) {
position: sticky;
left: 0;
width: 150px;
min-width: 150px;
}
.div1 th:nth-child(2),
.div1 td:nth-child(2) {
position: sticky;
/* 1st cell left/right padding + 1st cell width + 1st cell left/right border width */
/* 0 + 5 + 150 + 5 + 1 */
left: 161px;
width: 50px;
min-width: 50px;
}
.div1 td:nth-child(1),
.div1 td:nth-child(2) {
background: #ffebb5;
}
.div1 th:nth-child(1),
.div1 th:nth-child(2) {
z-index: 2;
}
HTML,
<div class="div1">
<table>
<tr>
<th>Column 1</th>
<th>Column 2</th>
<th>Column 3</th>
<th>Column 4</th>
<th>Column 5</th>
<th>Column 6</th>
</tr>
<tr>
<td>Row Data 1</td>
<td>Row Data 2</td>
<td>Row Data 3</td>
<td>Row Data 4</td>
<td>Row Data 5</td>
<td>Row Data 6</td>
</tr>
<tr>
<td>Row Data 1</td>
<td>Row Data 2</td>
<td>Row Data 3</td>
<td>Row Data 4</td>
<td>Row Data 5</td>
<td>Row Data 6</td>
</tr>
</table>
</div>
Youtube视频演练:https://www.youtube.com/watch?v=_dpSEjaKqSE
例1:固定宽度和高度
https://adriancs.com/demo/freeze_table_column_row.html
示例2:响应宽度和高度(通过使用viewport进行调整)
https://adriancs.com/html-css-js/298/html-table-freeze-row-and-column-with-css/
完整的教程解释:
https://adriancs.com/demo/freeze_table_column_row_responsive_viewport.html
Eamon Nerbonne,我在你的代码中改变了一些css,现在它更好了(滚动条从第一行开始)
http://jsfiddle.net/At8L8/
我只是加了两行:
.div : padding-left:5em;
.headcol : background-color : #fff;