Html 带有固定标题的仅 CSS 可滚动表

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11891065/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 02:10:49  来源:igfitidea点击:

CSS-Only Scrollable Table with fixed headers

htmlinternet-explorercss

提问by Troy Alford

I have a solution by which I can create scrollable tables w/fixed header/footer using minor jQuery and CSS - but I am looking for a way to make this a CSS-only solution that is cross-browser compliant.

我有一个解决方案,通过它我可以使用次要的 jQuery 和 CSS 创建带有固定页眉/页脚的可滚动表格 - 但我正在寻找一种方法来使其成为跨浏览器兼容的仅 CSS 解决方案。

To be clear, what I am seeking to do is use onlya tabletag (and it's valid sub-tags, colgroup, col, thead, tbody, tfoot, tr, th, td), but adopt a set of CSS rules which will meet the following conditions:

需要明确的是,我想要做的是使用一个table标签(并且它是有效的子标签,colgroup, col, thead, tbody, tfoot, tr, th, td),但采用一组符合以下条件的 CSS 规则:

  1. Must maintain column alignment between header / footer / content rows
  2. Must allow the header/footer to remain fixed while the content scrolls vertically
  3. Must not require any jQuery or other JavaScript in order to provide the functionality
  4. Must only use the tags provided above
  1. 必须保持页眉/页脚/内容行之间的列对齐
  2. 必须允许页眉/页脚在内容垂直滚动时保持固定
  3. 不得需要任何 jQuery 或其他 JavaScript 才能提供功能
  4. 只能使用上面提供的标签

This code example: http://jsfiddle.net/TroyAlford/SNKfd/shows my current approach. Most of the JS is just to populate the table with random values, but the last portion is what drives the left/right scrollability.

此代码示例:http: //jsfiddle.net/TroyAlford/SNKfd/显示了我当前的方法。大多数 JS 只是用随机值填充表格,但最后一部分是驱动左/右滚动性的部分。

$tbody.bind('scroll', function(ev) {
    var $css = { 'left': -ev.target.scrollLeft };
    $thead.css($css);
    $tfoot.css($css);
});

NOTE: The example provided does not render properly in IE, and requires jQuery to provide the horizontal scrolling. I don't care about horizontal scrolling anyway, so it's fine if a solution doesn't do that.

注意:提供的示例在 IE 中无法正确呈现,并且需要 jQuery 来提供水平滚动。反正我不关心水平滚动,所以如果解决方案不这样做也没关系。

采纳答案by nkmol

This answer will be used as a placeholder for the not fully supported position: stickyand will be updated over time. It is currently advised to not use the native implementation of this in a production environment.

此答案将用作不完全支持的占位符position: sticky,并将随着时间的推移进行更新。目前建议不要在生产环境中使用本机实现。

See this for the current support: https://caniuse.com/#feat=css-sticky

查看当前支持:https: //caniuse.com/#feat=css-sticky



Use of position: sticky

用于 position: sticky

An alternative answer would be using position: sticky. As described by W3C:

另一种答案是使用position: sticky. 正如 W3C 所描述的

A stickily positioned box is positioned similarly to a relatively positioned box, but the offset is computed with reference to the nearest ancestor with a scrolling box, or the viewport if no ancestor has a scrolling box.

粘性定位框的定位与相对定位框类似,但偏移量是参考最近的具有滚动框的祖先计算的,或者如果没有祖先具有滚动框,则参考视口。

This described exactly the behavior of a relative static header. It would be easy to assign this to the <thead>or the first <tr>HTML-tag, as this should be supported according to W3C. However, both Chrome, IE and Edgehave problems assigning a sticky position property to these tags. There also seems to be no priority in solving this at the moment.

这准确地描述了相对静态标头的行为。将它分配给第一个<thead>或第一个<tr>HTML 标签会很容易,因为根据 W3C应该支持它。但是,ChromeIE 和 Edge在为这些标签分配粘性位置属性时都存在问题。目前似乎也没有优先解决这个问题。

What does seem to work for a table element is assigning the sticky property to a table-cell. In this case the <th>cells.

似乎对表格元素有效的是将粘性属性分配给表格单元格。在这种情况下,<th>细胞。

Because a table is not a block-element that respects the static size you assign to it, it is best to use a wrapper elementto define the scroll-overflow.

因为表格不是尊重您分配给它的静态大小的块元素,所以最好使用包装元素来定义滚动溢出。

The code

编码

div {
  display: inline-block;
  height: 150px;
  overflow: auto
}

table th {
  position: -webkit-sticky;
  position: sticky;
  top: 0;
}


/* == Just general styling, not relevant :) == */

table {
  border-collapse: collapse;
}

th {
  background-color: #1976D2;
  color: #fff;
}

th,
td {
  padding: 1em .5em;
}

table tr {
  color: #212121;
}

table tr:nth-child(odd) {
  background-color: #BBDEFB;
}
<div>
  <table border="0">
    <thead>
      <tr>
        <th>head1</th>
        <th>head2</th>
        <th>head3</th>
        <th>head4</th>
      </tr>
    </thead>
    <tr>
      <td>row 1, cell 1</td>
      <td>row 1, cell 2</td>
      <td>row 1, cell 2</td>
      <td>row 1, cell 2</td>
    </tr>
    <tr>
      <td>row 2, cell 1</td>
      <td>row 2, cell 2</td>
      <td>row 1, cell 2</td>
      <td>row 1, cell 2</td>
    </tr>
    <tr>
      <td>row 2, cell 1</td>
      <td>row 2, cell 2</td>
      <td>row 1, cell 2</td>
      <td>row 1, cell 2</td>
    </tr>
    <tr>
      <td>row 2, cell 1</td>
      <td>row 2, cell 2</td>
      <td>row 1, cell 2</td>
      <td>row 1, cell 2</td>
    </tr>
    <tr>
      <td>row 2, cell 1</td>
      <td>row 2, cell 2</td>
      <td>row 1, cell 2</td>
      <td>row 1, cell 2</td>
    </tr>
  </table>
</div>

In this example I use a simple <div>wrapper to define the scroll-overflow done with a static height of 150px. This can of course be any size. Now that the scrolling box has been defined, the sticky <th>elements will corespondent "to the nearest ancestor with a scrolling box", which is the div-wrapper.

在这个例子中,我使用一个简单的<div>包装器来定义静态高度为150px. 这当然可以是任何大小。现在已经定义了滚动框,粘性<th>元素将对应“到最近的带有滚动框的祖先”,即 div-wrapper。



Use of a position: stickypolyfill

使用position: stickypolyfill

Non-supported devices can make use of a polyfill, which implements the behavior through code. An example is stickybits, which resembles the same behavior as the browser's implemented position: sticky.

不受支持的设备可以使用 polyfill,它通过代码实现行为。一个例子是stickybits,它类似于浏览器实现的相同行为position: sticky

Example with polyfill:http://jsfiddle.net/7UZA4/6957/

polyfill 示例:http : //jsfiddle.net/7UZA4/6957/

回答by Purag

Surprised a solution using flexbox hasn't been posted yet.

令人惊讶的是,尚未发布使用 flexbox 的解决方案。

Here's my solution using display: flexand a basic use of :after(thanks to Luggage) to maintain the alignment even with the scrollbar padding the tbodya bit. This has been verified in Chrome 45, Firefox 39, and MS Edge. It can be modified with prefixed properties to work in IE11, and further in IE10 with a CSS hackand the 2012 flexbox syntax.

这是我的解决方案使用display: flex和基本使用:after(感谢Luggage)即使滚动条填充tbody了一点也能保持对齐。这已在Chrome 45、Firefox 39 和 MS Edge 中得到验证。可以使用前缀属性修改它以在 IE11 中工作,并在 IE10 中使用CSS hack2012 flexbox 语法进一步修改

Note the table width can be modified; this even works at 100%width.

注意表格宽度可以修改;这甚至适用于100%宽度。

The only caveat is that all table cells must have the same width. Below is a clearly contrived example, but this works fine when cell contents vary (table cells all have the same width and word wrapping on, forcing flexbox to keep them the same width regardless of content). Hereis an example where cell contents are different.

唯一的警告是所有表格单元格必须具有相同的宽度。下面是一个明显人为设计的示例,但是当单元格内容不同时它可以正常工作(表格单元格都具有相同的宽度和自动换行,强制 flexbox 无论内容如何都保持相同的宽度)。是一个单元格内容不同的示例。

Just apply the .scrollclass to a table you want scrollable, and make sure it has a thead:

只需将该.scroll类应用于您想要滚动的表,并确保它具有thead

.scroll {
  border: 0;
  border-collapse: collapse;
}

.scroll tr {
  display: flex;
}

.scroll td {
  padding: 3px;
  flex: 1 auto;
  border: 1px solid #aaa;
  width: 1px;
  word-wrap: break-word;
}

.scroll thead tr:after {
  content: '';
  overflow-y: scroll;
  visibility: hidden;
  height: 0;
}

.scroll thead th {
  flex: 1 auto;
  display: block;
  border: 1px solid #000;
}

.scroll tbody {
  display: block;
  width: 100%;
  overflow-y: auto;
  height: 200px;
}
<table class="scroll" width="400px">
  <thead>
    <tr>
      <th>Header</th>
      <th>Header</th>
      <th>Header</th>
      <th>Header</th>
      <th>Header</th>
      <th>Header</th>
    </tr>
  </thead>
  <tr>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
  </tr>
  <tr>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
  </tr>
  <tr>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
  </tr>
  <tr>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
  </tr>
  <tr>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
  </tr>
  <tr>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
  </tr>
  <tr>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
  </tr>
  <tr>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
  </tr>
  <tr>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
  </tr>
  <tr>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
  </tr>
  <tr>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
  </tr>
  <tr>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
  </tr>
  <tr>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
  </tr>
  <tr>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
  </tr>
  <tr>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
  </tr>
  <tr>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
  </tr>
  <tr>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
  </tr>
  <tr>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
    <td>Data</td>
  </tr>
</table>

回答by Jan Turoň

Inspired by @Purag's answer, here's another flexbox solution:

受到@Purag 回答的启发,这是另一个 flexbox 解决方案:

/* basic settings */
table { display: flex; flex-direction: column; width: 200px; }
tr { display: flex; }
th:nth-child(1), td:nth-child(1) { flex-basis: 35%; }
th:nth-child(2), td:nth-child(2) { flex-basis: 65%; }
thead, tbody { overflow-y: scroll; }
tbody { height: 100px; }

/* color settings*/
table, th, td { border: 1px solid black; }
tr:nth-child(odd) { background: #EEE; }
tr:nth-child(even) { background: #AAA; }
thead tr:first-child { background: #333; }
th:first-child, td:first-child { background: rgba(200,200,0,0.7); }
th:last-child, td:last-child { background: rgba(255,200,0,0.7); }
<table>
    <thead>
      <tr>
        <th>a
        <th>bbbb
    <tbody>
      <tr>
        <td>fooo vsync dynamic
        <td>bar
      <tr>
        <td>a
        <td>b
      <tr>
        <td>a
        <td>b
      <tr>
        <td>a
        <td>b
      <tr>
        <td>a
        <td>b
      <tr>
        <td>a
        <td>b
      <tr>
        <td>a
        <td>b
  </table>

回答by Victoria

As far as I know, there is no standard way to achieve this with only CSS, although I think there should be. Mozilla browsers used to support fixed headers with a scrolling body, but they've removed it in the last few years.

据我所知,没有标准的方法可以只用 CSS 来实现这一点,尽管我认为应该有。Mozilla 浏览器过去支持带有滚动体的固定标题,但在过去几年中已将其删除。

After researching this a bit, including finding this posting, a friend just developed this solutionfor me; it uses Javascript but no canned libraries, and the only requirement for the HTML markup is that the table have an id name. Then, at window.onload, to call one Javascript function for each table giving the id, height, and width. If Javascript is disabled at the browser, the whole table is displayed according to its original markup. If Javascript is enabled, the table is fit into the specified height and width, and tbody scrolls, and if thead and tfoot exist, they are fixed at top and bottom.

经过一番研究,包括找到这个帖子,一个朋友刚刚为我开发了这个解决方案;它使用 Javascript 但没有罐头库,对 HTML 标记的唯一要求是表有一个 id 名称。然后,在 window.onload 中,为每个表调用一个 Javascript 函数,给出 id、高度和宽度。如果浏览器禁用了 Javascript,则整个表格将根据其原始标记显示。如果启用Javascript,表格适合指定的高度和宽度,tbody滚动,如果thead和tfoot存在,它们固定在顶部和底部。

回答by Max Alexander Hanna

Ive achieved this easily using this code :

我使用此代码轻松实现了这一点:

So you have a structure like this :

所以你有一个这样的结构:

<table>
<thead><tr></tr></thead>
<tbody><tr></tr></tbody>
</table>

just style the thead with :

只需使用以下样式设置头饰:

<style>
thead{ 
    position: -webkit-sticky;
    position: -moz-sticky;
    position: -ms-sticky;
    position: -o-sticky;
    position: sticky;
    top: 0px;
}
</style>

Three things to consider :

需要考虑的三件事:

First, this property is new. It's not supported at all, apart from the beta builds of Webkit-based browsers. So caveat formator. Again, if you really want for your users to benefit from sticky headers, go with a javascript implementation.

首先,这个属性是新的。除了基于 Webkit 的浏览器的 beta 版本之外,它根本不受支持。所以请注意格式化程序。同样,如果您真的希望您的用户从粘性标题中受益,请使用 javascript 实现。

Second, if you do use it, you'll need to incorporate vendor prefixes. Perhaps position: sticky will work one day. For now, though, you need to use position:-webkit-sticky (and the others; check the block of css further up in this post).

其次,如果您确实使用它,则需要合并供应商前缀。也许位置:粘性有一天会起作用。不过现在,您需要使用 position:-webkit-sticky(以及其他;在这篇文章中进一步检查 css 块)。

Third, there aren't any positioning defaults at the moment, so you need to at least include top: 0; in the same css declaration as the position:-webkit-sticky. Otherwise, it'll just scroll off-screen.

第三,目前没有任何定位默认值,所以你至少需要包含 top: 0; 在与 position:-webkit-sticky 相同的 css 声明中。否则,它只会在屏幕外滚动。

回答by Greg Rozmarynowycz

If you have the option of giving a fixed width to the table cells (and a fixed height to the header), you can used the position: fixedoption:

如果您可以选择为表格单元格提供固定宽度(并为标题提供固定高度),则可以使用以下position: fixed选项:

http://jsfiddle.net/thundercracker/ZxPeh/23/

http://jsfiddle.net/thundercracker/ZxPeh/23/

You would just have to stick it in an iframe. You could also have horizontal scrolling by giving the iframea scrollbar (I think).

你只需要把它放在一个iframe. 您还可以通过提供iframe滚动条来进行水平滚动(我认为)。



Edit 2015

编辑 2015

If you can live with a pre-defining the width of your table cells (by percentage), then here's a bit more elegant (CSS-only) solution:

如果您可以预先定义表格单元格的宽度(按百分比),那么这里有一个更优雅的(仅 CSS)解决方案:

http://jsfiddle.net/7UBMD/77/

http://jsfiddle.net/7UBMD/77/

回答by BENARD Patrick

Only with CSS :

仅使用 CSS :

CSS:

CSS:

tr {
  width: 100%;
  display: inline-table;
  table-layout: fixed;
}

table{
 height:300px;              // <-- Select the height of the table
 display: -moz-groupbox;    // Firefox Bad Effect
}
tbody{
  overflow-y: scroll;      
  height: 200px;            //  <-- Select the height of the body
  width: 100%;
  position: absolute;
}

Bootply: http://www.bootply.com/AgI8LpDugl

引导http: //www.bootply.com/AgI8LpDugl

回答by Blunderfest

I see this thread has been inactive for a while, but this topic interested me and now with some CSS3 selectors, this just became easier (and pretty doable with only CSS).

我看到这个帖子已经有一段时间没有活动了,但是这个话题让我很感兴趣,现在有了一些 CSS3 选择器,这变得更容易了(而且只用 CSS 就很可行)。

This solution relies on having a max height of the table container. But it is supported as long as you can use the :first-childselector.

此解决方案依赖于表容器的最大高度。但只要您可以使用:first-child选择器,它就受到支持。

Fiddle here.

在这里摆弄。

If anyone can improve on this answer, please do! I plan on using this solution in a commercial app soon!

如果有人可以改进这个答案,请做!我计划很快在商业应用程序中使用此解决方案!

HTML

HTML

<div id="con">
<table>
    <thead>
        <tr>
            <th>Header 1</th>
            <th>Header 2</th>
            <th>Header 3</th>
        </tr>
    </thead>        
    <tbody>             
    </tbody>
</table>
</div>

CSS

CSS

#con{
    max-height:300px;
    overflow-y:auto;
}
thead tr:first-child {
    background-color:#00f;
    color:#fff;
    position:absolute;
}
tbody tr:first-child td{
    padding-top:28px;
}

回答by Ruto Collins

if it gets rock hard where all the mentioned solutions don't work (as it got for me), try a two-tabled solutioned, as I explained in this answer

如果在所有提到的解决方案都不起作用的情况下变得非常困难(正如我所得到的那样),请尝试两桌解决方案,正如我在此答案中所解释的

https://stackoverflow.com/a/47722456/6488361

https://stackoverflow.com/a/47722456/6488361

回答by J Belloch

I had the same problem and after spending 2 days researching I found this solution from Ksesocss that fits for me and maybe is good for you too. It allows fixed header and dynamic width and only uses CSS. The only problem is that the source is in spanish but you can find the html and css code there.

我遇到了同样的问题,经过 2 天的研究,我发现 Ksesocss 的这个解决方案适合我,也许对你也有好处。它允许固定标题和动态宽度,并且只使用 CSS。唯一的问题是源代码是西班牙语,但您可以在那里找到 html 和 css 代码。

This is the link:

这是链接:

http://ksesocss.blogspot.com/2014/10/responsive-table-encabezado-fijo-scroll.html

http://ksesocss.blogspot.com/2014/10/responsive-table-encabezado-fijo-scroll.html

I hope this helps

我希望这有帮助