css 具有粘性标题和水平滚动的表格

q0qdq0h2  于 11个月前  发布在  其他
关注(0)|答案(2)|浏览(95)

我想要一个粘性标题和水平滚动表。
我不想在表内的垂直滚动。它应该与页面滚动。所以没有设置表的高度。这甚至可能吗?
下面是一个不工作的例子:https://codepen.io/fwitkowski/pen/zYEQvvg
当我从table-container中删除overflow:auto时,position sticky工作得很好。

.table-container {
  max-width:350px;
  overflow-x:auto; /* for horizontal scroll */
  position: relative; /* relative to the normal flow */
  border: solid 5px red /* for reference */
}

字符串

ezykj2lf

ezykj2lf1#

根据the MDN documentation
一个粘性元素“粘”到它最近的具有“滚动机制”的祖先(当overflowhiddenscrollauto,或overlay时创建),即使该祖先不是最近的实际滚动祖先。
在W3C repo上有一个活跃的GitHub问题在讨论这个问题,该repo自2017年以来一直在运行。已经提出了各种解决方案,但它们似乎都依赖于向表/表容器添加固定高度,或using Javascript as in this answer
至少在目前,这不是原生支持的东西。

nuypyhwy

nuypyhwy2#

带有position:sticky的头文件想贴在它们的父文件(表格)的顶部,而不是窗口的顶部,因为表格有overflow-x:scroll。我想出了一个简单的解决方法,它不依赖于固定的高度或自定义的滚动条。它只使用JavaScript。
技巧是将表分成两个表。(tableHeaders)和一个body表(tableBody)。tableHeadersoverflow-x:hiddentableBodyoverflow-x:scroll。现在头不再在表内,正文可以滚动。唯一的问题是头不滚动,但我们可以通过将其匹配到tableBody使用onscroll事件滚动。
将两个表都 Package 在一个div中,以获得以表体结尾的粘性效果。
我们需要做的最后一件事是确保tableHeaders中的列宽与tableBody的标题中生成的列宽相匹配。我们可以用一点JavaScript来处理这个问题。在内容加载后在某处调用它。

// The FullHeightTable component is expected to build a Sticky Table containing only an exact copy of the Primary Tables headers.
// The Sticky Table should be placed above the Primary Table.
function FixFullHeightTable() {

    // Select Primary Table body with built in headers.
    var tBody = document.getElementById('tableBody');
    var thead = tBody.querySelector('thead');

    // Select Sticky Table with only headers. This table contains only a copy of the Primary Table headers with no body. 
    // It is placed directly above the Primary Table and is intended to replace the Primary Table built in headers.
    // It's purpose is to stick to the top of the screen outside of the table markup.
    var stickyThead = document.getElementById('tableHeaders').querySelector('thead');
    var stickycolumns = stickyThead.querySelectorAll('th');

    // Copy the column widths from our hidden Primary table header to our Sticky Table header.
    var ths = thead.querySelectorAll('th');
    for (var i = 0; i < ths.length; i++) {
        var th = ths[i];
        // Since the Sticky Table header is expected to be an exact copy of the Primary Table, we know their indicies will be the same.
        stickycolumns[i].style.minWidth = th.offsetWidth + 'px';
        stickycolumns[i].style.maxWidth = th.offsetWidth + 'px';
    }

    // Sometimes setting line-height and opacity won't be enough to collapse the header to 0px.
    // We'll cover those edge cases by moving the table body over the header.
    // Warning: We can't remove Primary table header because they determine some of our column formatting, especially when css is involved.
    tBody.style.marginTop = `-${thead.offsetHeight}px`;
}

字符串

**注意:**我在Blazor环境中,所有这些都被 Package 到一个组件中,其中<thead>作为RenderFragment传递并自动复制。如果是其他情况,我可能会使用JavaScript将头克隆到粘性表中,而不是弄乱标记。
**提示:**如果页面顶部有其他粘性或固定元素,则应该等于它们的高度。我有另一个example,它显示了如何自动处理这个问题。

<div>
    <div id="tableHeaders" style="overflow-x:hidden;position:sticky;top:0; background: red;color: white;">
    <table >
        <thead>
            <tr>
                <th style="white-space: nowrap !important">1. A Very Long Header That Never Ends</th>
                <th style="white-space: nowrap !important">2. A Very Long Header That Never Ends</th>
                <th style="white-space: nowrap !important">3. A Very Long Header That Never Ends</th>
                <th style="white-space: nowrap !important">4. A Very Long Header That Never Ends</th>
                <th style="white-space: nowrap !important">5. A Very Long Header That Never Ends</th>
                    <th style="white-space: nowrap !important">6. A Very Long Header That Never Ends</th>
            </tr>
        </thead>
    </table>
    </div>

    <div id="tableBody" style="overflow-x:scroll" onscroll="document.getElementById('tableHeaders').scrollLeft = this.scrollLeft">
    <table>
            <thead style="line-height:0px;opacity:0">
            <tr>
                <th style="white-space: nowrap !important">1. A Very Long Header That Never Ends</th>
                <th style="white-space: nowrap !important">2. A Very Long Header That Never Ends</th>
                <th style="white-space: nowrap !important">3. A Very Long Header That Never Ends</th>
                <th style="white-space: nowrap !important">4. A Very Long Header That Never Ends</th>
                <th style="white-space: nowrap !important">5. A Very Long Header That Never Ends</th>
                <th style="white-space: nowrap !important">6. A Very Long Header That Never Ends</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td style="white-space: nowrap !important" >1. This is some very long content</td>
                <td style="white-space: nowrap !important" >2. This is some very long content</td>
                <td style="white-space: nowrap !important" >3. This is some very long content</td>
                <td style="white-space: nowrap !important" >4. This is some very long content</td>
                <td style="white-space: nowrap !important" >5. This is some very long content</td>
                <td style="white-space: nowrap !important" >6. This is some very long content</td>
            </tr>
            <tr>
                <td style="white-space: nowrap !important" >1. This is some very long content</td>
                <td style="white-space: nowrap !important" >2. This is some very long content</td>
                <td style="white-space: nowrap !important" >3. This is some very long content</td>
                <td style="white-space: nowrap !important" >4. This is some very long content</td>
                <td style="white-space: nowrap !important" >5. This is some very long content</td>
                <td style="white-space: nowrap !important" >6. This is some very long content</td>
            </tr>
            <tr>
                <td style="white-space: nowrap !important" >1. This is some very long content</td>
                <td style="white-space: nowrap !important" >2. This is some very long content</td>
                <td style="white-space: nowrap !important" >3. This is some very long content</td>
                <td style="white-space: nowrap !important" >4. This is some very long content</td>
                <td style="white-space: nowrap !important" >5. This is some very long content</td>
                <td style="white-space: nowrap !important" >6. This is some very long content</td>
            </tr>
            <tr>
                <td style="white-space: nowrap !important" >1. This is some very long content</td>
                <td style="white-space: nowrap !important" >2. This is some very long content</td>
                <td style="white-space: nowrap !important" >3. This is some very long content</td>
                <td style="white-space: nowrap !important" >4. This is some very long content</td>
                <td style="white-space: nowrap !important" >5. This is some very long content</td>
                <td style="white-space: nowrap !important" >6. This is some very long content</td>
            </tr>
            <tr>
                <td style="white-space: nowrap !important" >1. This is some very long content</td>
                <td style="white-space: nowrap !important" >2. This is some very long content</td>
                <td style="white-space: nowrap !important" >3. This is some very long content</td>
                <td style="white-space: nowrap !important" >4. This is some very long content</td>
                <td style="white-space: nowrap !important" >5. This is some very long content</td>
                <td style="white-space: nowrap !important" >6. This is some very long content</td>
            </tr>
            <tr>
                <td style="white-space: nowrap !important" >1. This is some very long content</td>
                <td style="white-space: nowrap !important" >2. This is some very long content</td>
                <td style="white-space: nowrap !important" >3. This is some very long content</td>
                <td style="white-space: nowrap !important" >4. This is some very long content</td>
                <td style="white-space: nowrap !important" >5. This is some very long content</td>
                <td style="white-space: nowrap !important" >6. This is some very long content</td>
            </tr>
        </tbody>
    </table>
    </div>

</div>

<div style="min-height:2000px">
 <p> Just some long body content</p>
</div>

相关问题