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

固定标题和固定列的HTML表? 我如何锁定表的第一行和第一列时滚动,可能使用JavaScript和CSS?

但我只需要一个单独的左列被冻结,我更喜欢一个简单的和无脚本的解决方案。


当前回答

我改进了断路器的例子,原来的例子代码将动摇固定列,因为表有填充,我使用边界崩溃:崩溃禁用它

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <!--mobile friendly-->
  <meta name="viewport" content="width=device-width, user-scalable=yes">
  <style>
    .view {
      margin: auto;
      width: 600px;
    }

    .wrapper {
      position: relative;
      overflow: auto;
      border: 1px solid black;
      white-space: nowrap;
    }

    .sticky-col {
      position: -webkit-sticky;
      position: sticky;
      background-color: white;
    }

    .first-col {
      padding: 0;
      margin: 0;
      left: 0;
    }

    .second-col {
      left: 200px;
    }

    .col {
      width: 200px;
      min-width: 200px;
      max-width: 200px;
    }
  </style>
</head>
<body>
<div class="view">
  <div class="wrapper">
    <table class="table" style="border-collapse: collapse;">
      <colgroup>
        <col class="col"/>
        <col class="col"/>
        <col class="col"/>
        <col class="col"/>
      </colgroup>
      <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>
</body>
</html>

其他回答

我没有检查这个问题的每个答案,但在分析了大部分答案后,我发现在单元格或头部的多行数据情况下,设计会失败。我使用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兼容。

下面是对最流行答案的另一种修改,但在第一列标签中处理了可变长度的文本: 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;
}

对于2017年之后发布的大多数浏览器:

你可以使用位置:粘性。= css-sticky看到https://caniuse.com/壮举。

不需要固定宽度的列。

运行下面的代码片段,看看它的工作原理。

.tscroll { width: 400px; overflow-x: scroll; margin-bottom: 10px; border: solid black 1px; } .tscroll table td:first-child { position: sticky; left: 0; background-color: #ddd; } .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>

如果你不想过多地触碰你现在的桌子,你可以在桌子前面做一个假的固定列。

这个例子展示了一种不使用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>

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

.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>