具有固定列和标题的可滚动表,具有现代CSS

Rik*_*ard 13 html javascript css html-table css3

如何使用现代CSS制作尽可能少的JavaScript表格?

我想要的功能是:

  • 固定柱(定位和宽度)
  • 可在X和Y轴上滚动
  • 在X轴上响应(对于非固定宽度的列).

在此输入图像描述

注意:我确实看到并分析了SO中一些最受欢迎/最常见的问题和答案,例如此处此处.

我知道这可以通过JavaScript事件处理程序进行滚动,以便可以向下/向上移动固定列以跟随主列.我试图构建的功能(但是大量编写脚本)的一个例子可能是这样的.我们还可以将MutationObserver父元素添加到表中以检测大小更改并再次计算表的大小.但这在性能上是昂贵的,而且由于CSS也在不断发展和现代化,我想知道是否有新方法......

是否有2017/2018解决方案,只有CSS或尽可能少的JS开销?

我想避免必须实现像这样容易破解的JavaScript解决方案:

在此输入图像描述

我的想法:

a):position: fixed;在固定列中使用

问题:

  • <td> 元素高度必须由JavaScript定义或计算.
  • 需要一个滚动事件监听器,我们需要以编程方式滚动固定列

b):使用div(s)来"伪造"左列,并在表格中包含可滚动内容

问题:

  • div高度必须与表行高度同步
  • HTML语义丢失,因为固定的"假"列不再是表格语法

c):使用N表只显示每个部分,所以我可以有HTML标记但保留固定的标题/列.

问题:

  • 重复HTML x N.
  • 必须同步大小并使用JavaScript滚动

使用滚动事件监听器和固定的左列,我们可以像这样使用JavaScript:

const firstColumn = [...document.querySelectorAll('table tr > *:first-of-type')];
const tableContainer = document.querySelector('.table-container');
tableContainer.addEventListener('scroll', function() {
    const currentScrollPosition = this.scrollTop * -1;
	firstColumn.forEach(el => el.style.marginTop = currentScrollPosition + 'px');
});
Run Code Online (Sandbox Code Playgroud)
.table-container {
    width: 600px;
    height: 300px;
    overflow-x: scroll;
    overflow-y: scroll;
}

.table-scroller {
    width: 1000px;
}

table {
    width: 100%;
    margin-left: -13px;
    table-layout: fixed;
    border-collapse: collapse;
    border: none;
}

table th,
table td {
    padding: 0.8em;
    border: 1px solid;
    background-color: #eeeeef;
}

table th {
    background-color: #6699FF;
    font-weight: bold;
}

table tr {
    height: 60px;
    vertical-align: middle;
}

table tr > *:first-of-type {
    position: fixed;
    width: 50px;
    margin-left: 13px;
    margin-top: 0;
    height: inherit;
}
Run Code Online (Sandbox Code Playgroud)
<div class="table-container">
    <div class="table-scroller">
        <table>
            <tbody>
                <tr>
                    <td>Edrward 0</td>
                    <td>32</td>
                    <td>London Park no. 0</td>
                    <td>London Park no. 0</td>
                    <td>London Park no. 0</td>
                    <td>London Park no. 0</td>
                    <td>London Park no. 0</td>
                    <td>London Park no. 0</td>
                    <td>London Park no. 0</td>
                    <td>London Park no. 0</td>
                    <td><a href="#">action</a></td>
                </tr>
                <tr>
                    <td>Edrward 1</td>
                    <td>32</td>
                    <td>London Park no. 1</td>
                    <td>London Park no. 1</td>
                    <td>London Park no. 1</td>
                    <td>London Park no. 1</td>
                    <td>London Park no. 1</td>
                    <td>London Park no. 1</td>
                    <td>London Park no. 1</td>
                    <td>London Park no. 1</td>
                    <td><a href="#">action</a></td>
                </tr>
                <tr>
                    <td>Edrward 2</td>
                    <td>32</td>
                    <td>London Park no. 2</td>
                    <td>London Park no. 2</td>
                    <td>London Park no. 2</td>
                    <td>London Park no. 2</td>
                    <td>London Park no. 2</td>
                    <td>London Park no. 2</td>
                    <td>London Park no. 2</td>
                    <td>London Park no. 2</td>
                    <td><a href="#">action</a></td>
                </tr>
                <tr>
                    <td>Edrward 3</td>
                    <td>32</td>
                    <td>London Park no. 3</td>
                    <td>London Park no. 3</td>
                    <td>London Park no. 3</td>
                    <td>London Park no. 3</td>
                    <td>London Park no. 3</td>
                    <td>London Park no. 3</td>
                    <td>London Park no. 3</td>
                    <td>London Park no. 3</td>
                    <td><a href="#">action</a></td>
                </tr>
                <tr>
                    <td>Edrward 4</td>
                    <td>32</td>
                    <td>London Park no. 4</td>
                    <td>London Park no. 4</td>
                    <td>London Park no. 4</td>
                    <td>London Park no. 4</td>
                    <td>London Park no. 4</td>
                    <td>London Park no. 4</td>
                    <td>London Park no. 4</td>
                    <td>London Park no. 4</td>
                    <td><a href="#">action</a></td>
                </tr>
                <tr>
                    <td>Edrward 5</td>
                    <td>32</td>
                    <td>London Park no. 5</td>
                    <td>London Park no. 5</td>
                    <td>London Park no. 5</td>
                    <td>London Park no. 5</td>
                    <td>London Park no. 5</td>
                    <td>London Park no. 5</td>
                    <td>London Park no. 5</td>
                    <td>London Park no. 5</td>
                    <td><a href="#">action</a></td>
                </tr>
                <tr>
                    <td>Edrward 6</td>
                    <td>32</td>
                    <td>London Park no. 6</td>
                    <td>London Park no. 6</td>
                    <td>London Park no. 6</td>
                    <td>London Park no. 6</td>
                    <td>London Park no. 6</td>
                    <td>London Park no. 6</td>
                    <td>London Park no. 6</td>
                    <td>London Park no. 6</td>
                    <td><a href="#">action</a></td>
                </tr>
                <tr>
                    <td>Edrward 7</td>
                    <td>32</td>
                    <td>London Park no. 7</td>
                    <td>London Park no. 7</td>
                    <td>London Park no. 7</td>
                    <td>London Park no. 7</td>
                    <td>London Park no. 7</td>
                    <td>London Park no. 7</td>
                    <td>London Park no. 7</td>
                    <td>London Park no. 7</td>
                    <td><a href="#">action</a></td>
                </tr>
                <tr>
                    <td>Edrward 8</td>
                    <td>32</td>
                    <td>London Park no. 8</td>
                    <td>London Park no. 8</td>
                    <td>London Park no. 8</td>
                    <td>London Park no. 8</td>
                    <td>London Park no. 8</td>
                    <td>London Park no. 8</td>
                    <td>London Park no. 8</td>
                    <td>London Park no. 8</td>
                    <td><a href="#">action</a></td>
                </tr>
                <tr>
                    <td>Edrward 9</td>
                    <td>32</td>
                    <td>London Park no. 9</td>
                    <td>London Park no. 9</td>
                    <td>London Park no. 9</td>
                    <td>London Park no. 9</td>
                    <td>London Park no. 9</td>
                    <td>London Park no. 9</td>
                    <td>London Park no. 9</td>
                    <td>London Park no. 9</td>
                    <td><a href="#">action</a></td>
                </tr>
            </tbody>
        </table>
    </div>
</div>
Run Code Online (Sandbox Code Playgroud)

但是我可以不用JavaScript吗?


关于可能的重复建议:

在我的问题中提到了可能的重复,它没有我正在寻找的东西.那个问题要求"只有一个左列被冻结" - 这一个的范围更广泛,它涉及固定标题,固定列和可滚动的主体.
另一个问题和接受的答案是2009年!我认为这个主题,我的具体范围和例子值得重新审视.另外:我的"JS解决方案"只是JS如何破解的一个例子,我正在寻找现代的CSS技术来做到这一点.

Alv*_*dez 16

也许你可以尝试使用最近position:sticky的实现它.或者,至少,用较少的javascript启动aproach.

div{
  overflow:auto;
  width:100%;
  height:200px;
}
td,
th {
  border: 1px solid #000;
  width: 100px;
}
th {background-color:red;}

table {
  table-layout: fixed;
  width:100%;
}
td:first-child, th:first-child {
  position:sticky;
  left:0;
  z-index:1;
  background-color:grey;
}
td:last-child, th:last-child {
  position:sticky;
  right:0;
  z-index:1;
  background-color:blue;
}
thead tr th {
  position:sticky;
  top:0;
}
th:first-child, th:last-child {z-index:2;background-color:red;}
Run Code Online (Sandbox Code Playgroud)
<div>
  <table>
    <thead>
      <tr>
        <th>&nbsp;&nbsp;&nbsp;</th>
        <th>&nbsp;&nbsp;&nbsp;</th>
        <th>&nbsp;&nbsp;&nbsp;</th>
        <th>&nbsp;&nbsp;&nbsp;</th>
        <th>&nbsp;&nbsp;&nbsp;</th>
        <th>&nbsp;&nbsp;&nbsp;</th>
        <th>&nbsp;&nbsp;&nbsp;</th>
        <th>&nbsp;&nbsp;&nbsp;</th>
        <th>&nbsp;&nbsp;&nbsp;</th>
        <th>&nbsp;&nbsp;&nbsp;</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
      </tr>
      <tr>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
      </tr>
      <tr>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
      </tr>
      <tr>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
      </tr>
      <tr>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
      </tr>
      <tr>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
      </tr>
      <tr>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
      </tr>
      <tr>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
      </tr>
      <tr>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;</td>
      </tr>
    </tbody>
  </table>
</div>
Run Code Online (Sandbox Code Playgroud)

  • 添加固定高度以显示示例中的粘性标题,使其尽可能接近gif提供的... (2认同)
  • 杰出的。非常紧凑且可读的代码支持强大的示例。 (2认同)