“粘"带有水平滚动的表格上的标题...完全不可能吗? [英] "Sticky" headers on a table with horizontal scroll... completely impossible?

查看:70
本文介绍了“粘"带有水平滚动的表格上的标题...完全不可能吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在研究了最近几个小时之后,我开始认为这是不可能的,即使在最新的浏览器上也是如此:

HTML table元素,具有水平滚动,顶部带有粘滞" thead,作为垂直滚动的周围网页的一部分.

这是我的尝试:

 #a {
  height: 100px;
  background-color: green;
}

body {
  width: 100%;
}

#wrapper {
  overflow-x: scroll;
  width: 100%;
}

th {
  position:sticky;
  top: 0;
  background-color: red;
  z-index: 1;
}

td {
  white-space: nowrap;
}

#b {
  height: 2000px;
  background-color: blue;
} 

 <div id="a">
  some content
</div>

<div id="wrapper">
  <table id="test">
    <thead>
      <tr>
        <th>sticky header</th>
        <th>sticky header</th>
        <th>sticky header</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>long content long content long content long content long content long content</td>
        <td>long content long content long content long content long content long content</td>
        <td>long content long content long content long content long content long content</td>
      </tr>
      <tr>
        <td>1</td>
        <td>2</td>
        <td>3</td>
      </tr>
      <tr>
        <td>1</td>
        <td>2</td>
        <td>3</td>
      </tr>
      <tr>
        <td>1</td>
        <td>2</td>
        <td>3</td>
      </tr>
      <tr>
        <td>1</td>
        <td>2</td>
        <td>3</td>
      </tr>
      <tr>
        <td>1</td>
        <td>2</td>
        <td>3</td>
      </tr>
    </tbody>
  </table>
</div>
<div id="b">
  some more content
</div> 

(还有此小提琴,因此您可以弄乱代码)

当前的方式是,当#wrapperoverflow-x: scroll时,位置:粘性"不起作用.如果删除了overflow-x规则,它会起作用,但是当然,表格会扩展整个页面的宽度(绝对不酷)

我知道使表格成为"scrolling"元素可以解决此问题,但这也不可取(我只希望网页主体可以垂直滚动).

我试图提出其他CSS解决方案,甚至Javascript解决方案,但我想不出一个最终可行的解决方案.这实际上是不可能的吗?

虽然我希望使用css解决方案,但现在我可以使用javascript解决方案.

解决方案

具有小提琴有一个可行的例子.您甚至可以通过预先声明宽度/高度来摆脱一些JavaScript.

在原始示例中添加了一些ID

<div id="a">
  some content
</div>

<div id="wrapper">
  <table id="test">
    <thead id="sticky">
      <tr id="headerRow">
        <th>sticky header</th>
        <th>sticky header</th>
        <th>sticky header</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>long content long content long content long content long content long content</td>
        <td>long content long content long content long content long content long content</td>
        <td>long content long content long content long content long content long content</td>
      </tr>
      <tr>
        <td>1</td>
        <td>2</td>
        <td>3</td>
      </tr>
      <tr>
        <td>1</td>
        <td>2</td>
        <td>3</td>
      </tr>
      <tr>
        <td>1</td>
        <td>2</td>
        <td>3</td>
      </tr>
      <tr>
        <td>1</td>
        <td>2</td>
        <td>3</td>
      </tr>
      <tr>
        <td>1</td>
        <td>2</td>
        <td>3</td>
      </tr>
    </tbody>
  </table>
</div>
<div id="b">
  some more content
</div>

下面是JavaScript

// When the user scrolls the page, execute addSticky 
window.onscroll = function() {addSticky()};
document.getElementById("wrapper").onscroll = function(){addSticky()};

// Get the header
var header = document.getElementById("sticky");

// Get the offset position
var sticky = header.offsetTop;

// Get bottom offset
var bottomOffset = document.getElementById("test").offsetHeight+100;


// Set the width of the row and columns by placing them in an array and looping said array
var headerRow = document.getElementById("headerRow");
header.style.width = headerRow.offsetWidth+"px";
var headerKids = headerRow.children;
for (var i=0; i<headerKids.length; i++){
  headerKids[i].style.width=headerKids[i].offsetWidth+"px";
}

// Add the sticky class to the header when you reach its scroll position. Remove "sticky" when you leave the scroll position
function addSticky() {
  if (this.scrollY > 100 && this.scrollY < bottomOffset ) {
    xScroll = document.getElementById("wrapper").scrollLeft;
    header.classList.add("sticky");
    header.style.left = "-"+xScroll+"px";
  } else {
    header.classList.remove("sticky");
  }
}

更新为CSS

.sticky {
  position: fixed;
  top: 0;
  height: 20px;
}

After researching this for the last few hours, I'm beginning to think this is impossible, even on the most up-to-date browsers:

HTML table element with a horizontal scroll, with a "sticky" thead on the top, as part of a surrounding web page that scrolls vertically.

Here's my attempt:

#a {
  height: 100px;
  background-color: green;
}

body {
  width: 100%;
}

#wrapper {
  overflow-x: scroll;
  width: 100%;
}

th {
  position:sticky;
  top: 0;
  background-color: red;
  z-index: 1;
}

td {
  white-space: nowrap;
}

#b {
  height: 2000px;
  background-color: blue;
}

<div id="a">
  some content
</div>

<div id="wrapper">
  <table id="test">
    <thead>
      <tr>
        <th>sticky header</th>
        <th>sticky header</th>
        <th>sticky header</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>long content long content long content long content long content long content</td>
        <td>long content long content long content long content long content long content</td>
        <td>long content long content long content long content long content long content</td>
      </tr>
      <tr>
        <td>1</td>
        <td>2</td>
        <td>3</td>
      </tr>
      <tr>
        <td>1</td>
        <td>2</td>
        <td>3</td>
      </tr>
      <tr>
        <td>1</td>
        <td>2</td>
        <td>3</td>
      </tr>
      <tr>
        <td>1</td>
        <td>2</td>
        <td>3</td>
      </tr>
      <tr>
        <td>1</td>
        <td>2</td>
        <td>3</td>
      </tr>
    </tbody>
  </table>
</div>
<div id="b">
  some more content
</div>

(There's also this fiddle, so you can mess with the code)

The way it currently is, the "position: sticky" doesn't work when the #wrapper is overflow-x: scroll. If you remove the overflow-x rule, it works, but then of course the table expands the width of the entire page (which is definitely not cool)

I know making the table the "scrolling" element would fix the issue, but that's not desirable either (I only want the web page body to be scrollable vertically).

I've tried to come up with alternate CSS solutions, and even Javascript solutions, but I can't think of a solution that would ultimately work. Is this actually impossible?

While I'd prefer a css solution, I'm open to a javascript solution at this point.

解决方案

Have a fiddle with a working example. You could even get rid of some of the javascript by declaring width/height beforehand.

Added some ids to your original example

<div id="a">
  some content
</div>

<div id="wrapper">
  <table id="test">
    <thead id="sticky">
      <tr id="headerRow">
        <th>sticky header</th>
        <th>sticky header</th>
        <th>sticky header</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>long content long content long content long content long content long content</td>
        <td>long content long content long content long content long content long content</td>
        <td>long content long content long content long content long content long content</td>
      </tr>
      <tr>
        <td>1</td>
        <td>2</td>
        <td>3</td>
      </tr>
      <tr>
        <td>1</td>
        <td>2</td>
        <td>3</td>
      </tr>
      <tr>
        <td>1</td>
        <td>2</td>
        <td>3</td>
      </tr>
      <tr>
        <td>1</td>
        <td>2</td>
        <td>3</td>
      </tr>
      <tr>
        <td>1</td>
        <td>2</td>
        <td>3</td>
      </tr>
    </tbody>
  </table>
</div>
<div id="b">
  some more content
</div>

Below is the javascript

// When the user scrolls the page, execute addSticky 
window.onscroll = function() {addSticky()};
document.getElementById("wrapper").onscroll = function(){addSticky()};

// Get the header
var header = document.getElementById("sticky");

// Get the offset position
var sticky = header.offsetTop;

// Get bottom offset
var bottomOffset = document.getElementById("test").offsetHeight+100;


// Set the width of the row and columns by placing them in an array and looping said array
var headerRow = document.getElementById("headerRow");
header.style.width = headerRow.offsetWidth+"px";
var headerKids = headerRow.children;
for (var i=0; i<headerKids.length; i++){
  headerKids[i].style.width=headerKids[i].offsetWidth+"px";
}

// Add the sticky class to the header when you reach its scroll position. Remove "sticky" when you leave the scroll position
function addSticky() {
  if (this.scrollY > 100 && this.scrollY < bottomOffset ) {
    xScroll = document.getElementById("wrapper").scrollLeft;
    header.classList.add("sticky");
    header.style.left = "-"+xScroll+"px";
  } else {
    header.classList.remove("sticky");
  }
}

Updates to CSS

.sticky {
  position: fixed;
  top: 0;
  height: 20px;
}

这篇关于“粘"带有水平滚动的表格上的标题...完全不可能吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆