例1: 表頭固定
- html
<div class="wrap">
<table>
<thead>
<tr>
<th>序號</th>
<th>姓名</th>
<th>年齡</th>
<th>性別</th>
<th>身高 (cm)</th>
<th>體重 (kg)</th>
</tr>
</thead>
<tbody>
<tr>
<td>01</td>
<td>德萊厄斯</td>
<td>31</td>
<td>男</td>
<td>180</td>
<td>80</td>
</tr>
<tr>
<td>02</td>
<td>安妮</td>
<td>14</td>
<td>女</td>
<td>150</td>
<td>35</td>
</tr>
<tr>
<td>03</td>
<td>阿貍</td>
<td>22</td>
<td>女</td>
<td>165</td>
<td>40</td>
</tr>
<tr>
<td>04</td>
<td>盧錫安</td>
<td>28</td>
<td>男</td>
<td>172</td>
<td>55</td>
</tr>
<tr>
<td>05</td>
<td>艾克</td>
<td>25</td>
<td>男</td>
<td>168</td>
<td>60</td>
</tr>
</tbody>
</table>
</div>
- css
table {
border-collapse: collapse;
text-align: center;
tr {
height: 0.44rem;
td,th {
width: 1rem;
border-right: 0.01rem solid rgba(81, 159, 241, 0.2);
}
th {
border-right: 0.01rem solid rgba(160, 216, 226, 0.5);
}
}
thead {
tr {
background: #519FF1;
font-size: 0.15rem;
color: #FFFFFF;
th {
font-weight: normal;
}
}
}
tbody {
height: 1.32rem;
overflow: auto;
tr:nth-child(odd) {
background: #FFFFFF;
}
tr:nth-child(even) {
background: #DCECFC;
}
}
}
例2: 首行首列固定
如圖所示
上下滾動, 1 2固定; 左右滾動, 1 3固定
方法1 ★★☆☆☆
思路: 1 始終固定; 2 3 利用
position: sticky;
粘性布局
優點: 簡單, HTML+CSS 即可實現
缺點: 內容折行會出現問題, 且兼容性不太友好 兼容性查看
- html
<div class="wrap">
<table>
<thead class="t1">
<!-- <tr> -->
<th>序號</th>
<!-- </tr> -->
</thead>
<thead class="t2">
<!-- <tr> -->
<th>姓名</th>
<th>年齡</th>
<th>性別</th>
<th>身高 (cm)</th>
<th>體重 (kg)</th>
<!-- </tr> -->
</thead>
<tbody class="t3">
<tr>
<td>01</td>
</tr>
<tr>
<td>02</td>
</tr>
<tr>
<td>03</td>
</tr>
<tr>
<td>04</td>
</tr>
<tr>
<td>05</td>
</tr>
<tr>
<td>06</td>
</tr>
<tr>
<td>07</td>
</tr>
</tbody>
<tbody class="t4">
<tr>
<td>德萊厄斯</td>
<td>31</td>
<td>男</td>
<td>180</td>
<td>80</td>
</tr>
<tr>
<td>安妮</td>
<td>14</td>
<td>女</td>
<td>150</td>
<td>35</td>
</tr>
<tr>
<td>阿貍</td>
<td>22</td>
<td>女</td>
<td>165</td>
<td>40</td>
</tr>
<tr>
<td>盧錫安</td>
<td>28</td>
<td>男</td>
<td>172</td>
<td>55</td>
</tr>
<tr>
<td>艾克</td>
<td>25</td>
<td>男</td>
<td>168</td>
<td>60</td>
</tr>
<tr>
<td>努努</td>
<td>8</td>
<td>男</td>
<td>30</td>
<td>20</td>
</tr>
<tr>
<td>提莫</td>
<td>11</td>
<td>女</td>
<td>40</td>
<td>20</td>
</tr>
</tbody>
</table>
</div>
- css
注: 如果是全屏滾動的話, 得先設置最最外層的 div 高度為 100%; 建議整體用 fixed布局, 否則可能出現問題
.wrap {
width: 100%;
height: 2.2rem;
overflow: scroll;
table {
position: relative;
border-collapse: collapse;
text-align: center;
td, th {
height: 0.44rem;
width: 1rem;
}
thead {
display: block;
width: 100%;
th {
font-weight: normal;
background: #519FF1;
font-size: 0.15rem;
color: #FFFFFF;
}
}
tbody {
width: 100%;
tr:nth-child(odd) {
background: #FFFFFF;
}
tr:nth-child(even) {
background: #DCECFC;
}
}
.t1 {
position: sticky;
width: 1rem;
z-index: 9;
float: left;
left: 0;
top: 0;
}
.t2 {
position: sticky;
width: 5rem;
top: 0;
margin-left: 1rem;
z-index: 8;
}
.t3 {
position: sticky;
width: 1rem;
left: 0;
float: left;
z-index: 8;
}
.t4 {
position: absolute;
width: 5rem;
left: 1rem;
z-index: 7;
}
}
}
方法2 ★★★☆☆
思路: 讓 3 隨著 4 上下移動; 2 隨著 4 左右移動
優點: 兼容性好
缺點: 內容折行會出現問題
- vue
<template>
<div>
<div class="wrap">
<table>
<div class="table-left">
<thead class="t1">
<tr>
<th>序號</th>
</tr>
</thead>
<tbody class="t3">
<tr>
<td>01</td>
</tr>
<tr>
<td>02</td>
</tr>
<tr>
<td>03</td>
</tr>
<tr>
<td>04</td>
</tr>
<tr>
<td>05</td>
</tr>
<tr>
<td>06</td>
</tr>
<tr>
<td>07</td>
</tr>
</tbody>
</div>
<div class="table-right">
<thead class="t2">
<tr>
<th>姓名</th>
<th>年齡</th>
<th>性別</th>
<th>身高 (cm)</th>
<th>體重 (kg)</th>
</tr>
</thead>
<tbody class="t4">
<tr>
<td>德萊厄斯</td>
<td>31</td>
<td>男</td>
<td>180</td>
<td>80</td>
</tr>
<tr>
<td>安妮</td>
<td>14</td>
<td>女</td>
<td>150</td>
<td>35</td>
</tr>
<tr>
<td>阿貍</td>
<td>22</td>
<td>女</td>
<td>165</td>
<td>40</td>
</tr>
<tr>
<td>盧錫安</td>
<td>28</td>
<td>男</td>
<td>172</td>
<td>55</td>
</tr>
<tr>
<td>艾克</td>
<td>25</td>
<td>男</td>
<td>168</td>
<td>60</td>
</tr>
<tr>
<td>努努</td>
<td>8</td>
<td>男</td>
<td>30</td>
<td>20</td>
</tr>
<tr>
<td>提莫</td>
<td>11</td>
<td>女</td>
<td>40</td>
<td>20</td>
</tr>
</tbody>
</div>
</table>
</div>
</div>
</template>
<script>
export default {
methods: {
// 監聽滾動事件
tableScroll() {
let _t4 = document.getElementsByClassName("t4")[0];
let _t4_top = this.scrollTop;
// let _t4_teft = this.scrollLeft;
document.getElementsByClassName("t3")[0].scrollTop = _t4_top;
// document.getElementsByClassName("t2")[0].scrollLeft = _t4_teft;
}
},
mounted() {
window.addEventListener('scroll', this.tableScroll, true);
},
destroyed() {
window.removeEventListener('scroll', this.tableScroll);
}
}
</script>
<style scoped lang="less">
.wrap {
table {
width: 100%;
height: 2.2rem;
display: block;
overflow: hidden;
text-align: center;
border-collapse: collapse;
th, td {
width: 1rem;
height: 0.44rem;
}
thead {
th {
font-weight: normal;
background: #519FF1;
font-size: 0.15rem;
color: #FFFFFF;
}
}
tbody {
tr:nth-child(odd) {
background: #FFFFFF;
}
tr:nth-child(even) {
background: #DCECFC;
}
}
.table-left {
width: 25%;
float: left;
}
.table-right {
width: 75%;
float: left;
overflow: auto;
}
}
.t1 {
display: block;
width: 1rem;
}
.t2 {
display: block;
width: 5rem;
}
.t3 {
display: block;
width: 1rem;
height: 1.76rem;
overflow: hidden;
}
.t4 {
width: 5rem;
height: 1.76rem;
display: block;
overflow: auto;
}
}
</style>
方法3 ★★★★★
Element UI 受到的啟發
思路: 兩層 div 嵌套
優點: 兼容性好, 并且數據折行后高度靈活改變
缺點: 暫無
<template>
<div class="table">
<div class="table-header">
<table>
<thead>
<tr>
<th>
<div class="cell">日期</div>
</th>
<th>
<div class="cell">姓名</div>
</th>
<th>
<div class="cell">省份</div>
</th>
<th>
<div class="cell">市區</div>
</th>
<th>
<div class="cell">地址</div>
</th>
<th>
<div class="cell">郵編</div>
</th>
</tr>
</thead>
</table>
</div>
<div class="table-body">
<table>
<tbody>
<tr>
<td>
<div class="cell">1111</div>
</td>
<td>
<div class="cell">2222</div>
</td>
<td>
<div class="cell">3333</div>
</td>
<td>
<div class="cell">4444</div>
</td>
<td>
<div class="cell">5555</div>
</td>
<td>
<div class="cell">6666</div>
</td>
</tr>
<tr>
<td>
<div class="cell">1111</div>
</td>
<td>
<div class="cell">2222</div>
</td>
<td>
<div class="cell">3333</div>
</td>
<td>
<div class="cell">4444</div>
</td>
<td>
<div class="cell">5555</div>
</td>
<td>
<div class="cell">6666</div>
</td>
</tr>
<tr>
<td>
<div class="cell">1111</div>
</td>
<td>
<div class="cell">2222</div>
</td>
<td>
<div class="cell">3333</div>
</td>
<td>
<div class="cell">4444</div>
</td>
<td>
<div class="cell">5555</div>
</td>
<td>
<div class="cell">6666</div>
</td>
</tr>
<tr>
<td>
<div class="cell">1111</div>
</td>
<td>
<div class="cell">2222</div>
</td>
<td>
<div class="cell">3333</div>
</td>
<td>
<div class="cell">4444</div>
</td>
<td>
<div class="cell">5555</div>
</td>
<td>
<div class="cell">6666</div>
</td>
</tr>
<tr>
<td>
<div class="cell">1111</div>
</td>
<td>
<div class="cell">2222</div>
</td>
<td>
<div class="cell">3333</div>
</td>
<td>
<div class="cell">4444</div>
</td>
<td>
<div class="cell">5555</div>
</td>
<td>
<div class="cell">6666</div>
</td>
</tr>
<tr>
<td>
<div class="cell">1111</div>
</td>
<td>
<div class="cell">2222</div>
</td>
<td>
<div class="cell">3333</div>
</td>
<td>
<div class="cell">4444</div>
</td>
<td>
<div class="cell">5555</div>
</td>
<td>
<div class="cell">6666</div>
</td>
</tr>
<tr>
<td>
<div class="cell">1111</div>
</td>
<td>
<div class="cell">2222</div>
</td>
<td>
<div class="cell">3333</div>
</td>
<td>
<div class="cell">4444</div>
</td>
<td>
<div class="cell">5555</div>
</td>
<td>
<div class="cell">6666</div>
</td>
</tr>
</tbody>
</table>
</div>
<div class="table-fixed">
<div class="table-fixed-header">
<table>
<thead>
<tr>
<th>
<div class="cell">日期</div>
</th>
<th>
<div class="cell">姓名</div>
</th>
<th>
<div class="cell">省份</div>
</th>
<th>
<div class="cell">市區</div>
</th>
<th>
<div class="cell">地址</div>
</th>
<th>
<div class="cell">郵編</div>
</th>
</tr>
</thead>
</table>
</div>
<div class="table-fixed-body">
<table>
<tbody>
<tr>
<td>
<div class="cell">1111</div>
</td>
<td>
<div class="cell">2222</div>
</td>
<td>
<div class="cell">3333</div>
</td>
<td>
<div class="cell">4444</div>
</td>
<td>
<div class="cell">5555</div>
</td>
<td>
<div class="cell">6666</div>
</td>
</tr>
<tr>
<td>
<div class="cell">1111</div>
</td>
<td>
<div class="cell">2222</div>
</td>
<td>
<div class="cell">3333</div>
</td>
<td>
<div class="cell">4444</div>
</td>
<td>
<div class="cell">5555</div>
</td>
<td>
<div class="cell">6666</div>
</td>
</tr>
<tr>
<td>
<div class="cell">1111</div>
</td>
<td>
<div class="cell">2222</div>
</td>
<td>
<div class="cell">3333</div>
</td>
<td>
<div class="cell">4444</div>
</td>
<td>
<div class="cell">5555</div>
</td>
<td>
<div class="cell">6666</div>
</td>
</tr>
<tr>
<td>
<div class="cell">1111</div>
</td>
<td>
<div class="cell">2222</div>
</td>
<td>
<div class="cell">3333</div>
</td>
<td>
<div class="cell">4444</div>
</td>
<td>
<div class="cell">5555</div>
</td>
<td>
<div class="cell">6666</div>
</td>
</tr>
<tr>
<td>
<div class="cell">1111</div>
</td>
<td>
<div class="cell">2222</div>
</td>
<td>
<div class="cell">3333</div>
</td>
<td>
<div class="cell">4444</div>
</td>
<td>
<div class="cell">5555</div>
</td>
<td>
<div class="cell">6666</div>
</td>
</tr>
<tr>
<td>
<div class="cell">1111</div>
</td>
<td>
<div class="cell">2222</div>
</td>
<td>
<div class="cell">3333</div>
</td>
<td>
<div class="cell">4444</div>
</td>
<td>
<div class="cell">5555</div>
</td>
<td>
<div class="cell">6666</div>
</td>
</tr>
<tr>
<td>
<div class="cell">1111</div>
</td>
<td>
<div class="cell">2222</div>
</td>
<td>
<div class="cell">3333</div>
</td>
<td>
<div class="cell">4444</div>
</td>
<td>
<div class="cell">5555</div>
</td>
<td>
<div class="cell">6666</div>
</td>
</tr>
<tr>
<td>
<div class="cell">1111</div>
</td>
<td>
<div class="cell">2222</div>
</td>
<td>
<div class="cell">3333</div>
</td>
<td>
<div class="cell">4444</div>
</td>
<td>
<div class="cell">5555</div>
</td>
<td>
<div class="cell">6666</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</template>
<script>
export default {
mounted() {
window.addEventListener('scroll', this.tableScroll, true);
},
beforeDestroy() {
window.removeEventListener('scroll', this.tableScroll);
},
methods: {
tableScroll() {
let _t2 = document.getElementsByClassName('table-header')[0];
let _t3 = document.getElementsByClassName('table-fixed-body')[0];
let _t4 = document.getElementsByClassName('table-body')[0];
_t2.scrollLeft = _t4.scrollLeft;
_t3.scrollTop = _t4.scrollTop;
}
}
}
</script>
<style scoped lang="less">
table {
width: 6rem;
text-align: center;
table-layout: fixed; /* 為表設置表格布局算法 */
border-collapse: collapse; /* 合并邊框 */
flex: 1; /* 讓所有彈性盒模型對象的子元素都有相同的長度,且忽略它們內部的內容 */
user-select: none; /* 文本不可選 */
font-size: 0.15rem;
tr {
&:nth-child(odd) {
background: #FFFFFF;
}
&:nth-child(even) {
background: #DCECFC;
}
th, td {
// padding: 0.15rem 0;
height: 0.44rem;
overflow: hidden;
white-space: nowrap; /* 文本不換行 */
}
th {
background: #519FF1;
color: #FFFFFF;
border-right: 0.01rem solid rgba(81, 159, 241, 0.2);
.cell {
position: relative;
word-wrap: normal; /* 只在允許的斷字點換行 */
text-overflow: ellipsis; /* 超出部分省略號 */
vertical-align: middle;
width: 100%;
box-sizing: border-box;
display: inline-block;
}
}
td {
border-right: 0.01rem solid rgba(81, 159, 241, 0.2);
.cell {
box-sizing: border-box;
white-space: normal; /* 文本不換行 */
word-break: break-all;
}
}
}
}
.table {
position: relative;
width: 100%;
height: 2.2rem;
overflow: hidden;
box-sizing: border-box;
max-width: 100%;
color: #606266;
.table-header {
width: 100%;
overflow: hidden;
}
.table-body {
position: relative;
width: 100%;
height: 1.76rem;
overflow: auto;
}
.table-fixed {
position: absolute;
top: 0;
left: 0;
overflow: hidden;
width: 1.01rem;
height: 2.2rem;
.table-fixed-header {
position: absolute;
left: 0;
top: 0;
z-index: 3;
}
.table-fixed-body {
position: absolute;
left: 0;
top: 0.44rem;
width: 100%;
height: 1.76rem;
overflow: hidden;
}
}
}
</style>
小技巧:
- 表格自動折行處理
td {
white-space: nowrap;
}
/* <td nowrap="nowrap"></td> */