65.9K
CodeProject 正在变化。 阅读更多。
Home

HTML 表格 – 使用 CSS 冻结行和列

starIconstarIconstarIconstarIconstarIcon

5.00/5 (6投票s)

2021年12月15日

CPOL

3分钟阅读

viewsIcon

50080

在 HTML 表格上实现冻结窗格效果。

引言

本文展示了一种仅使用 CSS 冻结 HTML 表格的列和行的方法,无需 JavaScript 或 JQuery。

背景

我要感谢 Manish Malviya 分享他在这篇博文中关于冻结表格行和列的知识。

以下工作灵感来自他的文章。

Youtube 教程视频演示

示例

示例 1:如 Youtube 教程视频所示

示例 2:固定宽度和高度

示例 3:响应式宽度和高度(通过使用视口调整)

Using the Code

让我们以一个简单的 HTML 表格为例

<div class="div1">
    <table>
        <tr>
            <th>Column 1</th>
            <th>Column 2</th>
            <th>Column 3</th>
            <th>Column 4</th>
            <th>Column 5</th>
            <th>Column 6</th>
        </tr>
        <tr>
            <td>Row Data 1</td>
            <td>Row Data 2</td>
            <td>Row Data 3</td>
            <td>Row Data 4</td>
            <td>Row Data 5</td>
            <td>Row Data 6</td>
        </tr>
        <tr>
            <td>Row Data 1</td>
            <td>Row Data 2</td>
            <td>Row Data 3</td>
            <td>Row Data 4</td>
            <td>Row Data 5</td>
            <td>Row Data 6</td>
        </tr>

        <tr>
            <td>Row Data 1</td>
            <td>Row Data 2</td>
            <td>Row Data 3</td>
            <td>Row Data 4</td>
            <td>Row Data 5</td>
            <td>Row Data 6</td>
        </tr>
    </table>
</div>

这是实现魔法的 CSS

.div1 {
    width: 600px;
    height: 400px;
    overflow: scroll;
    border: 1px solid #777777;
}

.div1 table {
    border-spacing: 0;
}

.div1 th {
    border-left: none;
    border-right: 1px solid #bbbbbb;
    padding: 5px;
    width: 80px;
    min-width: 80px;
    position: sticky;
    top: 0;
    background: #727272;
    color: #e0e0e0;
    font-weight: normal;
}

.div1 td {
    border-left: none;
    border-right: 1px solid #bbbbbb;
    border-bottom: 1px solid #bbbbbb;
    padding: 5px;
    width: 80px;
    min-width: 80px;
}

.div1 th:nth-child(1),
.div1 td:nth-child(1) {
    position: sticky;
    left: 0;
    width: 150px;
    min-width: 150px;
}

.div1 th:nth-child(2),
.div1 td:nth-child(2) {
    position: sticky;
    /* 1st cell left/right padding + 1st cell width + 1st cell left/right border width */
    /* 0 + 5 + 150 + 5 + 1 */
    left: 161px;
    width: 50px;
    min-width: 50px;
}

.div1 td:nth-child(1),
.div1 td:nth-child(2) {
    background: #ffebb5;
}

.div1 th:nth-child(1),
.div1 th:nth-child(2) {
    z-index: 2;
}

解释

首先,使用 DIV 标签包含 TABLE,提供固定的宽度和高度,将一个非常长和宽的 HTML 表格变成可滚动的表格。

.div1 {
    width: 600px;
    height: 400px;
    overflow: scroll;
    border: 1px solid #777777;
}

overflow: scroll”属性将使表格可滚动。

为了构建一个响应式表格,可以使用 CSS 函数 “CALC” 来自动计算宽度,例如

.div1 {
    height: calc(100vh - 250px);
    width: calc(100vw - 100px);
    overflow: scroll;
    border: 1px solid #777777;
}

请注意,CALC 值之间需要空格。

例如,这是错误的

height: calc(100vh-250px);

这是正确的

height: calc(100vh - 250px);

vh” 或 “vw” 是 “视口” 单位。

  • 100vh = 100% 可见高度,它类似于窗口大小,指的是可见区域。
  • 100vw = 100% 可见宽度。

表格样式

.div1 table {
    border-spacing: 0;
}
  • border-spacing: 0,消除单元格之间的空白距离

请注意,在这种情况下不能使用 "border-collapse: collapse" 属性。 这是因为边框线在使用 "position: sticky" 时会表现不正确,我们将在下面讨论。

TH (标题) 样式

.div1 th {
    border-left: none;
    border-right: 1px solid #bbbbbb;
    padding: 5px;
    width: 80px;
    min-width: 80px;
    position: sticky;
    top: 0;
    background: #727272;
    color: #e0e0e0;
    font-weight: normal;
}
  • position: sticky,这将使 TH 单元格始终保持在顶部位置
  • top: 0,这告诉 TH 单元格始终保持在从顶部测量的 位置 0(零)
  • background,如果没有背景颜色,底部的 TD 单元格将会“撞”到 TH 单元格,导致它们相互重叠
  • width, min-width:这用于固定列宽,如果没有这些属性,单元格列将会变形和压缩

这将冻结“标题”。

冻结第一列

.div1 th:nth-child(1),
.div1 td:nth-child(1) {
    position: sticky;
    left: 0;
    width: 150px;
    min-width: 150px;
}
  • nth-child(1) 表示每个“TR”块中的第一个元素。 指的是第一列。
  • left: 0 告诉单元格从左侧“冻结”在位置零。

冻结第二列

.div1 th:nth-child(2),
.div1 td:nth-child(2) {
    position: sticky;
    /* 1st cell left/right padding + 1st cell width + 1st cell left/right border width */
    /* 0 + 5 + 150 + 5 + 1 */
    left: 161px;
    width: 50px;
    min-width: 50px;
}

下一个单元格位置的计算是:边框宽度 + 内边距 + 单元格宽度

在这种情况下,0 左边框宽度 + 5px 左内边距 + 150px (第一个单元格宽度) + 5px 右内边距) + 1px 右边框宽度 = 161px

因此,left: 161px

接下来,当表格向右滚动时,非粘性单元格将撞到并覆盖第一和第二列冻结的单元格。

为第一和第二列冻结的单元格提供背景颜色以解决重叠问题

.div_maintb td:nth-child(1),
.div_maintb td:nth-child(2) {
    background: #ffebb5;
}

现在,前两个冻结的 "TH" 和 "TD" 都是 "sticky"。 由于 "TD" 是在 "TH" 之后创建的,因此当表格向下滚动时,"TD" 将保持在顶部并覆盖 "TH",使 "TH" 隐藏在 "TD" 下面。

因此,我们可以设置 "TH" 的 CSS 值 "z-index" 以覆盖它的层,使其位于前面/顶部,以便 "TD" 现在位于 "TH" 之下/之后。

默认情况下,所有元素的默认值都是 "z-index=0"。

.div1 th:nth-child(1),
.div1 th:nth-child(2) {
    z-index: 2;
}
© . All rights reserved.