繁体   English   中英

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

[英]Scrollable table with fixed columns and header, with modern CSS

如何使用现代 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'); });
 .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; }
 <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>

但是我可以在没有 JavaScript 的情况下做到这一点吗?


关于可能的重复建议:

我的问题中提到了可能的重复项,但它没有我正在寻找的内容。 这个问题要求“只冻结一个左列” - 这个问题的范围更广泛,它与固定标题、固定列和可滚动正文有关。
另一个问题和接受的答案来自 2009 年! 我认为这个话题,以及我的具体范围和例子值得重新审视。 另外:我的“JS 解决方案”只是 JS 如何破坏的一个例子,我正在寻找现代 CSS 技术来做到这一点。

也许您可以尝试使用最近的position:sticky来实现它。 或者,至少,以较少的 javascript 开始该方法。

 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;}
 <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>

只需查看带有固定标题的代码并修复第一列即可。

    <style type="text/css">
    .table {
          font-family: arial, sans-serif;
  border-collapse: collapse;
}

.th {
  width: 126px;
  height: 56px;
  padding: 0px 16px;
  text-align: left;
  background-color: #fafafa;
}

.td {
  width: 118px;
  min-width: 118px;
  max-width: 118px;
  height: 56px;
  max-height: 56px;
  overflow: hidden;
  text-align: center;
  border-bottom: 2px solid #dddddd;
}
.pink_color {
  background-color: pink;
}

.table_wrapper {
  position: relative;
}
.table_scroll {
  height: 73vh;
  overflow: auto;
}
.table_wrapper table {
  width: 100%;
}

.table_wrapper table thead th .text {
  position: absolute;
  z-index: 2;
}
.tableFixHead
{ 
  overflow: auto; height: 63vh; 
}
.tableFixHead thead th 
{ 
  position: sticky; top: 0; z-index: 1; 
}


@media only screen and (min-width: 1440px) {
  .table_scroll {
    height: 77vh;
    overflow: auto;
  }
}
</style>

<div style="padding-top: 16px;">
    <div class="table_wrapper">
        <div class="tableFixHead">
            <table class="table">
                <thead>
                  <th style="position: sticky; left: 0; z-index: 3;" class="text th"></th>
                  <th class="text th">1</th>
                  <th class="text th">1</th>
                  <th class="text th">1</th>
                  <th class="text th">1</th>
                  <th class="text th">1</th>
                  <th class="text th">1</th>
                  <th class="text th">1</th>
                  <th class="text th">1</th>
                  <th class="text th">1</th>
                  <th class="text th">1</th>
                  <th class="text th">1</th>
                  <th class="text th">1</th>
                  <th class="text th">1</th>
                </thead>
                <tr>
                  <td style="position: sticky; left: 0; z-index: 2; background: #fafafa;" class="td">test</td>
                    <td class="td">test1</td>
                    <td class="td">test1</td>
                    <td class="td">test1</td>
                    <td class="td">test1</td>
                    <td class="td">test1</td>
                    <td class="td">test1</td>
                    <td class="td">test1</td>
                    <td class="td">test1</td>
                    <td class="td">test1</td>
                    <td class="td">test1</td>
                    <td class="td">test1</td>
                    <td class="td">test1</td>
                    <td class="td">test1</td>
                </tr>
                <tr>
                  <td style="position: sticky; left: 0; z-index: 2; background: #fafafa;" class="td">test</td>
                  <td class="td">test1</td>
                    <td class="td">test1</td>
                    <td class="td">test1</td>
                    <td class="td">test1</td>
                    <td class="td">test1</td>
                    <td class="td">test1</td>
                    <td class="td">test1</td>
                    <td class="td">test1</td>
                    <td class="td">test1</td>
                    <td class="td">test1</td>
                </tr>
                <tr>
                  <td style="position: sticky; left: 0; z-index: 2; background: #fafafa;" class="td">test</td>
                  <td class="td">test1</td>
                    <td class="td">test1</td>
                    <td class="td">test1</td>
                    <td class="td">test1</td>
                    <td class="td">test1</td>
                    <td class="td">test1</td>
                    <td class="td">test1</td>
                    <td class="td">test1</td>
                    <td class="td">test1</td>
                    <td class="td">test1</td>
                </tr><tr>
                  <td style="position: sticky; left: 0; z-index: 2; background: #fafafa;" class="td">test</td>
                  <td class="td">test1</td>
                    <td class="td">test1</td>
                    <td class="td">test1</td>
                    <td class="td">test1</td>
                    <td class="td">test1</td>
                    <td class="td">test1</td>
                    <td class="td">test1</td>
                    <td class="td">test1</td>
                    <td class="td">test1</td>
                    <td class="td">test1</td>
                </tr><tr>
                  <td style="position: sticky; left: 0; z-index: 2; background: #fafafa;" class="td">test</td>
                  <td class="td">test1</td>
                    <td class="td">test1</td>
                    <td class="td">test1</td>
                    <td class="td">test1</td>
                    <td class="td">test1</td>
                    <td class="td">test1</td>
                    <td class="td">test1</td>
                    <td class="td">test1</td>
                    <td class="td">test1</td>
                    <td class="td">test1</td>
                </tr><tr>
                  <td style="position: sticky; left: 0; z-index: 2; background: #fafafa;" class="td">test</td>
                  <td class="td">test1</td>
                    <td class="td">test1</td>
                    <td class="td">test1</td>
                    <td class="td">test1</td>
                    <td class="td">test1</td>
                    <td class="td">test1</td>
                    <td class="td">test1</td>
                    <td class="td">test1</td>
                    <td class="td">test1</td>
                    <td class="td">test1</td>
                </tr><tr>
                  <td style="position: sticky; left: 0; z-index: 2; background: #fafafa;" class="td">test</td>
                  <td class="td">test1</td>
                    <td class="td">test1</td>
                    <td class="td">test1</td>
                    <td class="td">test1</td>
                    <td class="td">test1</td>
                    <td class="td">test1</td>
                    <td class="td">test1</td>
                    <td class="td">test1</td>
                    <td class="td">test1</td>
                    <td class="td">test1</td>
                </tr>
            </table>
        </div>
    </div>
</div>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM