html+css grid中显示滚动条后,表格内容与表头有18px的偏移

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了html+css grid中显示滚动条后,表格内容与表头有18px的偏移相关的知识,希望对你有一定的参考价值。

flexigrid表格出现滚动条时列和下面的数据错位的问题这算是bug吧,一个iframe里嵌套的这个表格,表格有一个自带的滚动条,浏览器小的时候滚动条会出现,然后数据和上面的表头就有一点点的错位,虽然不大,但是影响用户体验,所以想问下,如何去掉这个错位问题呢(ps:不让该样式,QAQ,我删除了一个样式就好了,但是滚动条不见了,而那个滚动条是必须有的)谁来帮下忙,提供一个思路也好。非常感谢

参考技术A flexigrid没有过,但按你说没滚动条就正常,再看你截图,很显然错位是因为表格内容部分的宽度计算时没有考虑滚动条宽度的缘故。在有滚动条时,最右列的表头的应比相应内容列宽一个滚动条的宽度。 参考技术B 那个表格和iframe可能是自适应屏幕的(也就是宽度为百分比的),当屏幕变窄后,自动出滚动条的!同时表格宽度也会变,最好的方法只能手动改下iframe样式的宽度,或都改下table的宽度从百分比变成px单为写死宽度。。。

如何在html表格上显示滚动条

【中文标题】如何在html表格上显示滚动条【英文标题】:How to display scroll bar onto a html table 【发布时间】:2012-01-04 04:27:24 【问题描述】:

我正在编写一个页面,我需要一个 html 表格来保持设定的大小。我需要表格顶部的标题始终保持在那里,但无论向表格中添加多少行,我还需要表格的主体滚动。

我希望它看起来像这个网址中的方法 2:http://www.cssplay.co.uk/menu/tablescroll.html

我试过这样做,但没有出现滚动条:

tbody 
  height: 80em;
  overflow: scroll;
<table border=1 id="qandatbl" align="center">
  <tr>
    <th class="col1">Question No</th>
    <th class="col2">Option Type</th>
    <th class="col1">Duration</th>
  </tr>

  <tbody>
    <tr>
      <td class='qid'></td>
      <td class="options"></td>
      <td class="duration"></td>
    </tr>
  </tbody>
</table>

【问题讨论】:

为什么不使用示例方法中的代码?很遗憾,你不能使用&lt;tbody&gt; 【参考方案1】:

这样的?

http://jsfiddle.net/TweNm/

我们的想法是将&lt;table&gt; 包装在一个非静态定位的&lt;div&gt; 中,该&lt;div&gt; 具有overflow:auto CSS 属性。然后绝对定位&lt;thead&gt;中的元素。

#table-wrapper 
  position:relative;

#table-scroll 
  height:150px;
  overflow:auto;  
  margin-top:20px;

#table-wrapper table 
  width:100%;


#table-wrapper table * 
  background:yellow;
  color:black;

#table-wrapper table thead th .text 
  position:absolute;   
  top:-20px;
  z-index:2;
  height:20px;
  width:35%;
  border:1px solid red;
<div id="table-wrapper">
  <div id="table-scroll">
    <table>
        <thead>
            <tr>
                <th><span class="text">A</span></th>
                <th><span class="text">B</span></th>
                <th><span class="text">C</span></th>
            </tr>
        </thead>
        <tbody>
          <tr> <td>1, 0</td> <td>2, 0</td> <td>3, 0</td> </tr>
          <tr> <td>1, 1</td> <td>2, 1</td> <td>3, 1</td> </tr>
          <tr> <td>1, 2</td> <td>2, 2</td> <td>3, 2</td> </tr>
          <tr> <td>1, 3</td> <td>2, 3</td> <td>3, 3</td> </tr>
          <tr> <td>1, 4</td> <td>2, 4</td> <td>3, 4</td> </tr>
          <tr> <td>1, 5</td> <td>2, 5</td> <td>3, 5</td> </tr>
          <tr> <td>1, 6</td> <td>2, 6</td> <td>3, 6</td> </tr>
          <tr> <td>1, 7</td> <td>2, 7</td> <td>3, 7</td> </tr>
          <tr> <td>1, 8</td> <td>2, 8</td> <td>3, 8</td> </tr>
          <tr> <td>1, 9</td> <td>2, 9</td> <td>3, 9</td> </tr>
          <tr> <td>1, 10</td> <td>2, 10</td> <td>3, 10</td> </tr>
          <!-- etc... -->
          <tr> <td>1, 99</td> <td>2, 99</td> <td>3, 99</td> </tr>
        </tbody>
    </table>
  </div>
</div>

【讨论】:

没有固定宽度的列怎么样? 我尝试了您的答案,但标题列未对齐。我只在 body 标记内的样式标记中使用了你的 CSS,我在其中复制了你的表格 很好的解决方案,但我遇到了问题。当尝试隐藏一行并设置 display:none 时,行之间有一些空格。常规表不是这种情况。有什么想法、提示或建议吗? @Antonio:我遇到了同样的问题(居中*标题列似乎未对齐),但添加 transform: translateX(-50%) 对我有用 [*centered 是 Firefox 中的标准样式,已被此答案的 JSFiddle 中的“规范化 CSS”选项]【参考方案2】:

您必须将&lt;table&gt; 插入到具有固定大小的&lt;div&gt; 中,并且在&lt;div&gt; 样式中您必须设置overflow: scroll

更新

最初的答案是 10 年前写的。现在有很多很好的用于表格视图的 UI 组件并以适当的方式显示。因此,我的建议是选择这些免费或付费组件之一,以确保您已经支持许多已经在这些组件中实现的边缘案例。

【讨论】:

为我的 div 设置了 500px 的高度,它工作得很好。 不知道为什么每个人都把它弄得这么复杂。这应该是公认的答案。 这是迄今为止最简单的解决方案。添加具有溢出和固定高度的 div 可能有一些注意事项,但此解决方案至少会让您朝着正确的方向前进。 精湛的答案队友!为你干杯:)- 这应该是公认的答案。简单,直截了当,我不会用它破坏任何其他东西。【参考方案3】:

接受的答案提供了一个很好的起点,但如果您调整框架大小、更改列宽,甚至更改表格数据,标题将以各种方式弄乱。我见过的所有其他示例都有类似的问题,或者对表格的布局施加了一些严重的限制。

不过,我想我终于解决了所有这些问题。它使用了 很多 CSS,但最终产品与普通表格一样可靠且易于使用。

这是一个示例,它具有复制 OP 引用的表所需的所有功能:jsFiddle

必须更改颜色和边框以使其与参考相同。 CSS cmets 中提供了有关如何进行此类更改的信息。

代码如下:

/*the following html and body rule sets are required only if using a % width or height*/
/*html 
width: 100%;
height: 100%;
*/
body 
  box-sizing: border-box;
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0 20px 0 20px;
  text-align: center;
  background: white;

.scrollingtable 
  box-sizing: border-box;
  display: inline-block;
  vertical-align: middle;
  overflow: hidden;
  width: auto; /*if you want a fixed width, set it here, else set to auto*/
  min-width: 0/*100%*/; /*if you want a % width, set it here, else set to 0*/
  height: 188px/*100%*/; /*set table height here; can be fixed value or %*/
  min-height: 0/*104px*/; /*if using % height, make this large enough to fit scrollbar arrows + caption + thead*/
  font-family: Verdana, Tahoma, sans-serif;
  font-size: 15px;
  line-height: 20px;
  padding: 20px 0 20px 0; /*need enough padding to make room for caption*/
  text-align: left;

.scrollingtable * box-sizing: border-box;
.scrollingtable > div 
  position: relative;
  border-top: 1px solid black;
  height: 100%;
  padding-top: 20px; /*this determines column header height*/

.scrollingtable > div:before 
  top: 0;
  background: cornflowerblue; /*header row background color*/

.scrollingtable > div:before,
.scrollingtable > div > div:after 
  content: "";
  position: absolute;
  z-index: -1;
  width: 100%;
  height: 100%;
  left: 0;

.scrollingtable > div > div 
  min-height: 0/*43px*/; /*if using % height, make this large enough to fit scrollbar arrows*/
  max-height: 100%;
  overflow: scroll/*auto*/; /*set to auto if using fixed or % width; else scroll*/
  overflow-x: hidden;
  border: 1px solid black; /*border around table body*/

.scrollingtable > div > div:after background: white; /*match page background color*/
.scrollingtable > div > div > table 
  width: 100%;
  border-spacing: 0;
  margin-top: -20px; /*inverse of column header height*/
  /*margin-right: 17px;*/ /*uncomment if using % width*/

.scrollingtable > div > div > table > caption 
  position: absolute;
  top: -20px; /*inverse of caption height*/
  margin-top: -1px; /*inverse of border-width*/
  width: 100%;
  font-weight: bold;
  text-align: center;

.scrollingtable > div > div > table > * > tr > * padding: 0;
.scrollingtable > div > div > table > thead 
  vertical-align: bottom;
  white-space: nowrap;
  text-align: center;

.scrollingtable > div > div > table > thead > tr > * > div 
  display: inline-block;
  padding: 0 6px 0 6px; /*header cell padding*/

.scrollingtable > div > div > table > thead > tr > :first-child:before 
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  height: 20px; /*match column header height*/
  border-left: 1px solid black; /*leftmost header border*/

.scrollingtable > div > div > table > thead > tr > * > div[label]:before,
.scrollingtable > div > div > table > thead > tr > * > div > div:first-child,
.scrollingtable > div > div > table > thead > tr > * + :before 
  position: absolute;
  top: 0;
  white-space: pre-wrap;
  color: white; /*header row font color*/

.scrollingtable > div > div > table > thead > tr > * > div[label]:before,
.scrollingtable > div > div > table > thead > tr > * > div[label]:after content: attr(label);
.scrollingtable > div > div > table > thead > tr > * + :before 
  content: "";
  display: block;
  min-height: 20px; /*match column header height*/
  padding-top: 1px;
  border-left: 1px solid black; /*borders between header cells*/

.scrollingtable .scrollbarhead float: right;
.scrollingtable .scrollbarhead:before 
  position: absolute;
  width: 100px;
  top: -1px; /*inverse border-width*/
  background: white; /*match page background color*/

.scrollingtable > div > div > table > tbody > tr:after 
  content: "";
  display: table-cell;
  position: relative;
  padding: 0;
  border-top: 1px solid black;
  top: -1px; /*inverse of border width*/

.scrollingtable > div > div > table > tbody vertical-align: top;
.scrollingtable > div > div > table > tbody > tr background: white;
.scrollingtable > div > div > table > tbody > tr > * 
  border-bottom: 1px solid black;
  padding: 0 6px 0 6px;
  height: 20px; /*match column header height*/

.scrollingtable > div > div > table > tbody:last-of-type > tr:last-child > * border-bottom: none;
.scrollingtable > div > div > table > tbody > tr:nth-child(even) background: gainsboro; /*alternate row color*/
.scrollingtable > div > div > table > tbody > tr > * + * border-left: 1px solid black; /*borders between body cells*/
<div class="scrollingtable">
  <div>
    <div>
      <table>
        <caption>Top Caption</caption>
        <thead>
          <tr>
            <th><div label="Column 1"></div></th>
            <th><div label="Column 2"></div></th>
            <th><div label="Column 3"></div></th>
            <th>
              <!--more versatile way of doing column label; requires 2 identical copies of label-->
              <div><div>Column 4</div><div>Column 4</div></div>
            </th>
            <th class="scrollbarhead"/> <!--ALWAYS ADD THIS EXTRA CELL AT END OF HEADER ROW-->
          </tr>
        </thead>
        <tbody>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
        </tbody>
      </table>
    </div>
    Faux bottom caption
  </div>
</div>

<!--[if lte IE 9]><style>.scrollingtable > div > div > table margin-right: 17px;</style><![endif]-->

【讨论】:

很棒的工作。但是,我有一个包含 15 列的表格,现在我似乎也无法在没有水平滚动条的情况下将表格包含在页面中。我已经尝试调整你的 css,你编码精美的 css,以适应更多动态宽度的列,但除了表格宽度之外,我没有改变任何东西。如果我将表格宽度更改为 100%,那么表格将呈现在表格的宽度中,但由于列宽不会换行,我仍然看不到所有 15 列数据。我几乎有一个看起来很酷的滚动表,所以任何帮助表示赞赏。 哦,等一下,没有水平滚动条,表格就被切断了。 @nanker 如果你需要水平滚动并且愿意使用一点点 JavaScript,你应该检查this answer。这是我知道的做滚动表的最佳方式。当我发布这个答案时,没有很好的方法可以只使用 CSS 进行水平滚动,但我有一段时间没有研究它,所以我不知道现在有什么可能。 很棒的工作。您能否评论如何调整多个标题行?简单地重复 &lt;tr&gt;&lt;th&gt;&lt;/th&gt;..&lt;/tr&gt; 结构显然是行不通的。谢谢。 @DavidI.McIntosh 使用这种技术多行标题会很棘手。添加行很容易,但我不确定如何获得它们之间的水平边界。您可能想尝试我在之前评论中链接的 JavaScript 解决方案,除非由于某种原因您不能使用 JS。【参考方案4】:

不知道为什么没有人提到只对元素使用内置的粘性标题样式。对我来说效果很好。

.tableContainerDiv 
   overflow: auto;
   max-height: 80em;

th 
   position: sticky;
   top: 0;
   background: white;

如果您需要做出响应(或类似),请在@media 中设置最小宽度。

见Table headers position:sticky或Position Sticky and Table Headers

【讨论】:

这是一种更简洁的方法,更接近原始表格,并且使用最少的 css。其他答案已过时。【参考方案5】:

我通过将我的内容分成两个表格解决了这个问题。

一个表是标题行。

秒也是&lt;table&gt;标签,但被&lt;div&gt;包裹,具有静态高度和溢出滚动。

【讨论】:

【参考方案6】:

值得注意的是,根据您的目的(我的目的是搜索栏的自动填充结果),您可能希望高度是可变的,并且滚动条仅在高度超过该高度时才存在。

如果需要,请将height: x; 替换为max-height: x;,将overflow:scroll 替换为overflow:auto

此外,如果需要,您可以使用overflow-xoverflow-y,显然同样的事情与width : x; 水平工作

【讨论】:

【参考方案7】:

非常简单,只需将表格包裹在具有overflow-y:scroll;overflow-x:scroll 属性的div 中,并使div 的宽度和长度小于表格。 它会工作的!!!

【讨论】:

好的,我会在下一个答案中添加。 好的,做到了,我还不知道如何在堆栈溢出时正确缩进代码。【参考方案8】:

如果您遇到所有提到的解决方案都不起作用的地步(就像我遇到的那样),请执行以下操作:

创建两个表。一个用于标题,另一个用于正文 给两个表不同的父容器/div 设置第二个表格的 div 以允许垂直滚动其内容。

像这样,在你的HTML

<div class="table-header-class">
    <table>
       <thead>
          <tr>
            <th>Ava</th>
            <th>Alexis</th>
            <th>Mcclure</th>
          </tr>
       </thead>
    </table>
</div>
<div class="table-content-class">
   <table>
       <tbody>
          <tr>
            <td>I am the boss</td>
            <td>No, da-da is not the boss!</td>
            <td>Alexis, I am the boss, right?</td>
          </tr>
       </tbody>
    </table>
</div>

然后在您的CSS 中设置第二个表的父级以允许垂直滚动

    .table-content-class 
        overflow-y: scroll;    // use auto; or scroll; to allow vertical scrolling; 
        overflow-x: hidden;    // disable horizontal scroll 
    

【讨论】:

这与 Zvi 一年前的回答相同。【参考方案9】:

添加到表格中

style="overflow-x:auto;"

<table border=1 id="qandatbl" align="center" style="overflow-x:auto;">
    <tr>
    <th class="col1">Question No</th>
    <th class="col2">Option Type</th>
    <th class="col1">Duration</th>
    </tr>

   <tbody>
    <tr>
    <td class='qid'></td>
    <td class="options"></td>
    <td class="duration"></td>
    </tr>
    </tbody>
</table>

style="overflow-x:auto;"`

【讨论】:

问题是如何在列标题保持不变的情况下使表格主体垂直滚动。【参考方案10】:

CSS: div overflow-y:scroll; overflow-x:scroll; width:20px; height:30px; table width:50px; height:50px;

你可以把桌子和桌子周围的 DIV 做成你想要的任何大小,只要确保 DIV 比桌子小。 您必须将表格包含在 DIV 中。

【讨论】:

以上是关于html+css grid中显示滚动条后,表格内容与表头有18px的偏移的主要内容,如果未能解决你的问题,请参考以下文章

css中overflow被隐藏的内容如何正常的显示出来

如何在 ag-grid 表的页脚中启用或显示总行

纯css控制-表格表头固定,内容多时滚动内容

【CSS】为啥设置不显示滚动条不好用呢?

表格超出不现实纵向滚动条

wpf 动态添加滚动条