固定位置表头延伸到屏幕外

Posted

技术标签:

【中文标题】固定位置表头延伸到屏幕外【英文标题】:Fixed position table header extends off the screen 【发布时间】:2018-08-12 07:56:57 【问题描述】:

我有一个带有固定顶部标题、固定左侧边栏和可滚动右侧内容区域的布局。内容包括一个长表,我想在粘性标题下方滚动。

我创建了一个单独的表格,只是为了标题,在我添加任何固定位置的样式之前,一切都很好。当我放置位置固定时,标题会粘住但它会延伸到屏幕外(可能是由于侧边栏的偏移?)有没有办法让它像表格本身一样延伸到屏幕的整个宽度?这是小提琴,我对导致 CSS 出现问题的行有一个评论:

https://jsfiddle.net/7wgnosr1/14/

body,
html 
  height: 100%;
  min-height: 100%;
  margin: 0;


.container 
  height: 100%;
  min-height: 100%;
  display: flex;
  flex-direction: column;


header 
  z-index: 0;
  flex: 0 64px;
  display: flex;
  background: #f4991a;


main 
  flex: 1;
  display: flex;
  background: #f9f5f0;
  overflow: auto;


aside 
  background: #f2ead3;
  flex: 0 0 300px;
  overflow: auto;
  order: 0;
  border-right: 1px solid #d9d9d9;
  display: flex;
  flex-direction: column;


section 
  background: #f3f3f5;
  flex: 1 1 100px;
  order: 1;
  overflow: auto;


table.fixed 
  position: fixed;
  /* If I comment this out, it aligns correctly but does not stick */


table 
  text-align: left;
  width: 100%;
  padding: 10px;
  background-color: white;
<div class="container">
  <header>
    Fixed Header
  </header>
  <main>
    <aside>
      Fixed Sidebar
    </aside>
    <section>
      <table class="fixed">
        <thead>
          <tr>
            <th>Fixed TH 1</th>
            <th>Fixed TH 2</th>
            <th>Fixed TH 3</th>
          </tr>
        </thead>
      </table>
      <table>
        <tbody>
          <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>
          <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>
          <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>
          <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>
          <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>
          <tr>
            <td>1</td>
            <td>2</td>
            <td>3</td>
          </tr>
          <tr>
            <td>1</td>
            <td>2</td>
            <td>3</td>
          </tr>
        </tbody>
      </table>
    </section>
  </main>
</div>
<table class="fixed"> // with position fixed, it sticks but extends off the screen
  <thead>
    <tr>
      <th>Fixed TH 1</th>
      <th>Fixed TH 2</th>
      <th>Fixed TH 3</th>
    </tr>
  </thead>
</table>
<table>
  <tbody>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
    ... lots more rows
  </tbody>
</table>

【问题讨论】:

请注意the varying support for position:sticky, especially on table elements。 注意,在您当前的示例中,第二个表中的第一行是不可见的。 我查看了 position:sticky 但不幸的是它不适用于我的 Chrome (63) 版本。可悲的是,我不能指望 chrome 无法处理的东西 看看我关于position: sticky的更新答案 你确定你测试了正确的小提琴吗? jsfiddle.net/7wgnosr1/34 并且还注意到顶部坐标和位置:相对添加到父级? 【参考方案1】:

我建议使用嵌套的flexbox布局,不需要固定位置。

在第二个表周围添加了一个 div 容器。即使内容长度不同,也要为等宽单元格设置table-layout: fixed;

<section>
  <table>
    ...
  </table>
  <div class="scroll-area">
    <table>
      ...
    </table>
  </div>
</section>

section 
  display: flex;
  flex-direction: column;


table 
  table-layout: fixed;
  width: 100%;


.scroll-area 
  flex: 1;
  overflow: auto;


body,
html 
  height: 100%;
  min-height: 100%;
  margin: 0;


.container 
  height: 100%;
  min-height: 100%;
  display: flex;
  flex-direction: column;


header 
  z-index: 0;
  flex: 0 64px;
  display: flex;
  background: #f4991a;


main 
  flex: 1;
  display: flex;
  background: #f9f5f0;
  overflow: auto;


aside 
  background: #f2ead3;
  flex: 0 0 300px;
  overflow: auto;
  order: 0;
  border-right: 1px solid #d9d9d9;
  display: flex;
  flex-direction: column;


section 
  background: #f3f3f5;
  flex: 1 1 100px;


section 
  display: flex;
  flex-direction: column;


table 
  text-align: left;
  table-layout: fixed;
  width: 100%;
  padding: 10px;
  background-color: white;


.scroll-area 
  flex: 1;
  overflow: auto;
<div class="container">
<header>
  Fixed Header
</header>
<main>
  <aside>
    Fixed Sidebar
  </aside>
  <section>
    <table>
      <thead>
        <tr>
          <th>Fixed TH 1</th>
          <th>Fixed TH 2</th>
          <th>Fixed TH 3</th>
        </tr>
      </thead>
    </table>
    <div class="scroll-area">
      <table>
        <tbody>
          <tr><td>1 first cell</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>
          <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>
          <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>
          <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>
          <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>
          <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>
  </section>
</main>
</div>

【讨论】:

所以这看起来很有希望,因为我不需要关心侧边栏的宽度。是否有关于它是如何工作的解释?我很难理解为什么它会粘住.. 查看jsfiddle.net/zh5rhdfk 的小版本并阅读 cmets。 我最终选择了这个解决方案,因为它不需要计算,我不必担心粘性支持,并且滚动条不会显示在标题旁边。谢谢【参考方案2】:

实际上,一切正常,因为根据文档,固定元素是相对于浏览器窗口定位的,并且表格标题的宽度等于窗口的宽度。如果您的侧边栏将始终具有固定宽度(例如 300 像素),您可以为表格标题设置限制,如下所示:

table.fixed 
  position: fixed;
  max-width: calc(100% - 300px);

更新:正如 cmets 中提到的那样,position: sticky 即将到来。 Google Chrome 56+ 支持 th 元素和其他现代浏览器 already started to go in this direction。您说它在 Chrome 63 上对您不起作用。您是否正确设置了阈值?仅设置position: sticky 是不够的:

body,
html 
  height: 100%;
  min-height: 100%;
  margin: 0;


.container 
  height: 100%;
  min-height: 100%;
  display: flex;
  flex-direction: column;


header 
  z-index: 0;
  flex: 0 64px;
  display: flex;
  background: #f4991a;


main 
  flex: 1;
  display: flex;
  background: #f9f5f0;
  overflow: auto;


aside 
  background: #f2ead3;
  flex: 0 0 300px;
  overflow: auto;
  order: 0;
  border-right: 1px solid #d9d9d9;
  display: flex;
  flex-direction: column;


section 
  background: #f3f3f5;
  flex: 1 1 100px;
  order: 1;
  overflow: auto;


table 
  text-align: left;
  width: 100%;
  background-color: white;
  border-collapse: collapse;


th 
  position: sticky;
  top: 0;
  background-color: #fff;


td, th 
  padding: 5px;
<div class="container">

  <header>
    Fixed Header
  </header>
  <main>
    <aside>
      Fixed Sidebar
    </aside>
    <section>
      <table>
        <thead>
          <tr>
            <th>Fixed TH 1</th>
            <th>Fixed TH 2</th>
            <th>Fixed TH 3</th>
          </tr>
        </thead>
        <tbody>
          <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>
          <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>
          <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>
          <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>
          <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>
          <tr>
            <td>1</td>
            <td>2</td>
            <td>3</td>
          </tr>
          <tr>
            <td>1</td>
            <td>2</td>
            <td>3</td>
          </tr>
        </tbody>
      </table>
    </section>
  </main>

</div>

【讨论】:

sticky 在应用于表格子元素时在 FF 中存在问题(您的示例在 Firefox 中失败),我之前对 jsfiddle.net/7wgnosr1/34 的评论在将粘性应用于表格并且父级设置为相对位置时有效(匹配最高坐标)。 @G-Cyr FF 将很快更新。根据caniuse.comdev。分支有这个固定。我相信用户会在一个月左右的时间内得到更新。无论如何,它仍然是一个非常新的功能,应谨慎使用。当我们使用 html/css 时,它并不总是一个公共网站。可能是一个或几个人的小项目。如果需要,他们可以使用最新的 Chrome 或 FF。 这是一个多年前的已知错误,它确实会修复一次;) 好吧我现在不知道该往哪个方向走哈哈。 calc 有效,但我不喜欢知道侧边栏宽度,sticky 有效,但我不知道是否有支持,另一个答案中的嵌套 flexbox 布局也看起来很有希望。如何选择!

以上是关于固定位置表头延伸到屏幕外的主要内容,如果未能解决你的问题,请参考以下文章

带有固定元素的 jQuery .animate() 和 css 位置

具有固定位置和可滚动表数据元素的 HTML 表头

延伸到屏幕外的 HTML 表格

将元素动画到固定位置的屏幕大小

opencv播放视频屏幕固定位置显示文字

表头如何固定下拉表头不动