【问题标题】:Pure CSS scrolling tbody and static thead table w/ dynamic height & width纯 CSS 滚动 tbody 和带动态高度和宽度的静态头表
【发布时间】:2016-02-02 16:08:32
【问题描述】:

我的任务是创建一个用作布局主要部分的表格。表格的标题应该是静态的,而正文应该在必要时滚动。问题是如果需要滚动条,表格的列会因为 tbody 的宽度发生变化而错位。

我使用了一些 javascript 来补偿,将thead 上的右填充设置为等于滚动条的宽度,并计划在滚动条消失/出现时使用侦听器来删除/添加填充。

虽然这种方法可以保持列对齐,但如果可能的话,我被要求提出一个仅 HTML/CSS 的解决方案。有谁知道在没有任何js的情况下实现这一目标的方法?谢谢。

我目前拥有的一些相关 CSS:

table {
  width: 100%;
  border-collapse: collapse;
}

table tbody {
  position: absolute;
  top: 24px;
  left: 0;
  right: 0;
  bottom: 0;
  overflow-y: auto;
}

table thead {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
}

这是一个查看整个示例的小提琴:http://jsfiddle.net/kirky93/qqv73kjo/5/
向上/向下拖动视口以使滚动条消失/出现以查看问题。

【问题讨论】:

  • 那么,你取得的结果有什么问题?
  • 你应该使用 :overflow:scroll on tbody ;) 类似 stackoverflow.com/questions/23989463/…
  • @Trix 好问题——归结为关于不喜欢使用 javascript 设置样式的意见。

标签: html css


【解决方案1】:

为了消除纯 CSS 的错位,我们可以让滚动条将标题推到一边。我们可以通过将其设为position: fixed 来做到这一点,这样 tbody 上的滚动条就会延伸到视口的顶部。

阅读量太大?跳到底部的示例。

列颜色和宽度

使用七个<col> elements,一个代表每一列。我们可以用宽度和背景颜色将类放在它们上面,这些属性将在整个列中重复,而不必在每个表格单元格上放置一个类。它们看起来像这样:

<table class="fixed">      
  <col class="one">
  <col class="two">
  <col class="three">
  <col class="four">
  <col class="five">
  <col class="six">
  <col class="seven">

为了在列上放置width CSS 属性,我们可以在表格元素上设置table-layout: fixed。现在不需要匹配的最小/最大宽度。

让标题滚动

  • 设置position: fixed
  • 设置 display: table 使其再次表现得像一张桌子
  • 设置table-layout: fixed 使宽度正常
  • 因为现在已经有效地从其表和&lt;col&gt; 元素中删除了thead,所以在每个th 上设置列类

身体

  • 保留其初始position: static
  • 设置与标题高度相同的上边距

完整示例

请注意box-sizing: border-box,它使元素的宽度和高度包括内边距和边框。

html {
  box-sizing: border-box;
}
*,
*:before,
*:after {
  box-sizing: inherit;
}
body {
  margin: 0;
}
table {
  border-collapse: collapse;
  background: #FFF;
  table-layout: fixed;
  width: 100%;
}
table thead {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  background: #FFF;
  display: table;
  table-layout: fixed;
  border: solid 1px #000;
}
table tbody {
  margin-top: 24px;
}
table {
  /*Make sure table has border that matches the cell border so it is included in the width*/
  border: 1px solid black;
}
td,
th {
  height: 20px;
  border: 1px solid black;
}
.one {
  width: 30px;
  background-color: yellow;
}
.two {
  width: 30px;
  background-color: orange;
}
.three {
  width: 30px;
  background-color: red;
}
.four {
  width: 100%;
}
.five {
  width: 100px;
  background-color: green;
}
.six {
  width: 100px;
  background-color: lightblue;
}
.seven {
  width: 100px;
}
<table class="fixed">
  
  <col class="one">
  <col class="two">
  <col class="three">
  <col class="four">
  <col class="five">
  <col class="six">
  <col class="seven">

  <thead>
    <tr>
      <th class="one">1</th>
      <th class="two">2</th>
      <th class="three">3</th>
      <th class="four">4</th>
      <th class="five">5</th>
      <th class="six">6</th>
      <th class="seven">7</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
      <td>4</td>
      <td>5</td>
      <td>6</td>
      <td>7</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
      <td>4</td>
      <td>5</td>
      <td>6</td>
      <td>7</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
      <td>4</td>
      <td>5</td>
      <td>6</td>
      <td>7</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
      <td>4</td>
      <td>5</td>
      <td>6</td>
      <td>7</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
      <td>4</td>
      <td>5</td>
      <td>6</td>
      <td>7</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
      <td>4</td>
      <td>5</td>
      <td>6</td>
      <td>7</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
      <td>4</td>
      <td>5</td>
      <td>6</td>
      <td>7</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
      <td>4</td>
      <td>5</td>
      <td>6</td>
      <td>7</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
      <td>4</td>
      <td>5</td>
      <td>6</td>
      <td>7</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
      <td>4</td>
      <td>5</td>
      <td>6</td>
      <td>7</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
      <td>4</td>
      <td>5</td>
      <td>6</td>
      <td>7</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
      <td>4</td>
      <td>5</td>
      <td>6</td>
      <td>7</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
      <td>4</td>
      <td>5</td>
      <td>6</td>
      <td>7</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
      <td>4</td>
      <td>5</td>
      <td>6</td>
      <td>7</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
      <td>4</td>
      <td>5</td>
      <td>6</td>
      <td>7</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
      <td>4</td>
      <td>5</td>
      <td>6</td>
      <td>7</td>
    </tr>
  </tbody>
</table>

【讨论】:

    【解决方案2】:

    只需将其设置为溢出:在 tbody 上滚动而不是自动

    table tbody {
      position: absolute;
      top: 24px;
      left: 0;
      right: 0;
      bottom: 0;
      overflow-y: scroll;
    }
    

    【讨论】:

    • 这样做的“问题”是,由于滚动条宽度不同,仍然必须通过 js AFAIK 动态设置头部的填充。不过谢谢。
    • 是的,我可能不会做那个 js 的事情。只需设置溢出-y:在标题上滚动,以便它们可以对齐。然后您可以自定义标题上的滚动条,使其不显示为 stackoverflow.com/questions/19603141/transparent-scrollbar ... 虽然这仅适用于 webkit。
    猜你喜欢
    • 1970-01-01
    • 2011-12-21
    • 1970-01-01
    • 2011-08-07
    • 1970-01-01
    • 1970-01-01
    • 2015-09-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多