首页 > 解决方案 > 冻结的表格列在纯 CSS 中无法正常工作

问题描述

我正在处理 HTML 表的冻结左列。我尝试了 STO 上建议的各种方法,但没有一个适合我。然后我使用 2 个相同样式的 HTML 表重新创建了它。虽然,我取得了一些成功,但它还不完美。我无法继续修复它。我想坚持纯 CSS 来实现它。

这是我的代码:

	#tb_wrapper {
		border:1px solid red;
		position:relative;
		max-width:960px;
	}
	
	#fixed_tb_wrapper {
		position:absolute;
		left:0;
		top:0;
		z-index:99999;
	}
	
	#scrollable_tb_wrapper {
		border:1px solid #cccccc;
		z-index:-99999;
	}
	
	.tb_records1 {
		border-collapse:separate;
		border-spacing:0;
		text-align:center;
	}
	
	.tb_records1 th {
		background-color:#5F5F5F;
		color:#FFFFFF;
		font-weight:bold;
	}
	
	.tb_records1 th, .tb_records1 td {
		padding:10px;
		border:1px solid #000000;
		font-size:15px;
	}
	
	.tb_records1 tr:nth-child(even) {
		background-color:#F2F2F2;
	}
	
	.tb_records1 tr:hover {
		background-color:#F5F5F5;
	}

	.tb_responsive {
		overflow-x:auto;
		overflow-y:hidden;
	}

	.tb_records2 {
		border-collapse:separate;
		border-spacing:0;
		text-align:center;
		white-space:nowrap;
		width:100%;
	}
	
	.tb_records2 th {
		background-color:#5F5F5F;
		color:#FFFFFF;
		font-weight:bold;
	}
	
	.tb_records2 th, .tb_records2 td {
		padding:10px;
		border:1px solid #000000;
		font-size:15px;
	}
	
	.tb_records2 tr:nth-child(even) {
		background-color:#F2F2F2;
	}
	
	.tb_records2 tr:hover {
		background-color:#F5F5F5;
	}
	<div id="tb_wrapper">

        <div id="fixed_tb_wrapper" style="border:1px solid red;">
            <table class="tb_records1">
                <tr>
                    <th>Post ID</th>
                </tr>
                <tr>
                    <td>This is a long Post ID</td>
                </tr>
                <tr>
                    <td>2</td>
                </tr>
                <tr>
                    <td>3</td>
                </tr>
                <tr>
                    <td>4</td>
                </tr>
                <tr>
                    <td>5</td>
                </tr>
                <tr>
                    <td>6</td>
                </tr>
                <tr>
                    <td>7</td>
                </tr>
                <tr>
                    <td>8</td>
                </tr>
                <tr>
                    <td>9</td>
                </tr>
                <tr>
                    <td>10</td>
                </tr>
            </table>
        </div>

        <div id="scrollable_tb_wrapper" style="border:1px solid blue;">
            <div class="tb_responsive">
                <table class="tb_records2">
                    <tr>
                        <th>Post Name</th>
                        <th>Post URL</th>
                        <th>Post Title</th>
                        <th>Post Heading</th>
                        <th>Post Content</th>
                        <th>Post Date Published</th>
                        <th>Post Date Modified</th>
                        <th>Post Image</th>
                        <th>Post Views</th>
                    </tr>
                    <tr>
                        <td>My Post</td>
                        <td>my-post</td>
                        <td>My Post</td>
                        <td>My Post</td>
                        <td>Lorem ipsum dolor sit amet.</td>
                        <td>2017-07-21 13:58:16</td>
                        <td>2019-07-30 22:38:36</td>
                        <td>my-post.jpg</td>
                        <td>7</td>
                    </tr>
                    <tr>
                        <td>My Post</td>
                        <td>my-post</td>
                        <td>My Post</td>
                        <td>My Post</td>
                        <td>Lorem ipsum dolor sit amet.</td>
                        <td>2017-07-21 13:58:16</td>
                        <td>2019-07-30 22:38:36</td>
                        <td>my-post.jpg</td>
                        <td>7</td>
                    </tr>
                    <tr>
                        <td>My Post</td>
                        <td>my-post</td>
                        <td>My Post</td>
                        <td>My Post</td>
                        <td>Lorem ipsum dolor sit amet.</td>
                        <td>2017-07-21 13:58:16</td>
                        <td>2019-07-30 22:38:36</td>
                        <td>my-post.jpg</td>
                        <td>7</td>
                    </tr>
                    <tr>
                        <td>My Post</td>
                        <td>my-post</td>
                        <td>My Post</td>
                        <td>My Post</td>
                        <td>Lorem ipsum dolor sit amet.</td>
                        <td>2017-07-21 13:58:16</td>
                        <td>2019-07-30 22:38:36</td>
                        <td>my-post.jpg</td>
                        <td>7</td>
                    </tr>
                    <tr>
                        <td>My Post</td>
                        <td>my-post</td>
                        <td>My Post</td>
                        <td>My Post</td>
                        <td>Lorem ipsum dolor sit amet.</td>
                        <td>2017-07-21 13:58:16</td>
                        <td>2019-07-30 22:38:36</td>
                        <td>my-post.jpg</td>
                        <td>7</td>
                    </tr>
                    <tr>
                        <td>My Post</td>
                        <td>my-post</td>
                        <td>My Post</td>
                        <td>My Post</td>
                        <td>Lorem ipsum dolor sit amet.</td>
                        <td>2017-07-21 13:58:16</td>
                        <td>2019-07-30 22:38:36</td>
                        <td>my-post.jpg</td>
                        <td>7</td>
                    </tr>
                    <tr>
                        <td>My Post</td>
                        <td>my-post</td>
                        <td>My Post</td>
                        <td>My Post</td>
                        <td>Lorem ipsum dolor sit amet.</td>
                        <td>2017-07-21 13:58:16</td>
                        <td>2019-07-30 22:38:36</td>
                        <td>my-post.jpg</td>
                        <td>7</td>
                    </tr>
                    <tr>
                        <td>My Post</td>
                        <td>my-post</td>
                        <td>My Post</td>
                        <td>My Post</td>
                        <td>Lorem ipsum dolor sit amet.</td>
                        <td>2017-07-21 13:58:16</td>
                        <td>2019-07-30 22:38:36</td>
                        <td>my-post.jpg</td>
                        <td>7</td>
                    </tr>
                    <tr>
                        <td>My Post</td>
                        <td>my-post</td>
                        <td>My Post</td>
                        <td>My Post</td>
                        <td>Lorem ipsum dolor sit amet.</td>
                        <td>2017-07-21 13:58:16</td>
                        <td>2019-07-30 22:38:36</td>
                        <td>my-post.jpg</td>
                        <td>7</td>
                    </tr>
                    <tr>
                        <td>My Post</td>
                        <td>my-post</td>
                        <td>My Post</td>
                        <td>My Post</td>
                        <td>Lorem ipsum dolor sit amet.</td>
                        <td>2017-07-21 13:58:16</td>
                        <td>2019-07-30 22:38:36</td>
                        <td>my-post.jpg</td>
                        <td>7</td>
                    </tr>
                </table>
            </div>
        </div>

    </div>
    

您可以看到具有单列 Post ID 的第一个表是固定的,并且右表在其下方滚动。但我有两个问题:

  1. 可滚动表的内容在第一个固定表(列)下可见。我使用了 z-index 但它没有效果。不知道为什么?
  2. 是否有必要给第一个固定表提供固定宽度?然后等于右边可滚动表的左边距?如果是这样,那么它似乎有效,但这会是唯一的最佳解决方案吗?

标签: htmlcss

解决方案


一个纯 CSS 解决方案

解决方案 1

table {
  border-collapse: separate;
  border-spacing: 0;
  border-top: 1px solid grey;
}

td, th {
  margin: 0;
  border: 1px solid grey;
  white-space: nowrap;
  border-top-width: 0px;
}

div {
  width: 500px;
  overflow-x: scroll;
  margin-left: 5em;
  overflow-y: visible;
  padding: 0;
}

.headcol {
  position: absolute;
  width: 5em;
  left: 0;
  top: auto;
  border-top-width: 1px;
  /*only relevant for first row*/
  margin-top: -1px;
  /*compensate for top border*/
}

.headcol:before {
  content: 'Row ';
}

.long {
  background: yellow;
  letter-spacing: 1em;
}
<div>
<table>
        <tr><th class="headcol">1</th><td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td><td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td></tr>
        <tr><th class="headcol">2</th><td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td><td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td></tr>
        <tr><th class="headcol">3</th><td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td><td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td></tr>
        <tr><th class="headcol">4</th><td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td><td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td></tr>
        <tr><th class="headcol">5</th><td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td><td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td></tr>
        <tr><th class="headcol">6</th><td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td><td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td></tr>
</table>
</div>

解决方案 2

.container {
   /* Attach fixed-th-table to this container,
      in order to layout fixed-th-table
      in the same way as scolled-td-table" */
   position: relative;
    
   /* Truncate fixed-th-table */
   overflow: hidden;
}

.fixed-th-table-wrapper td,
.fixed-th-table-wrapper th,
.scrolled-td-table-wrapper td,
.scrolled-td-table-wrapper th {
   /* Set background to non-transparent color
      because two tables are one above another.
    */
   background: white;
}
.fixed-th-table-wrapper {
   /* Make table out of flow */
   position: absolute;
}
.fixed-th-table-wrapper th {
    /* Place fixed-th-table th-cells above 
       scrolled-td-table td-cells.
     */
    position: relative;
    z-index: 1;
}
.scrolled-td-table-wrapper td {
    /* Place scrolled-td-table td-cells
       above fixed-th-table.
     */
    position: relative;
}
.scrolled-td-table-wrapper {
   /* Make horizonal scrollbar if needed */
   overflow-x: auto;
}


/* Simulating border-collapse: collapse,
   because fixed-th-table borders
   are below ".scrolling-td-wrapper table" borders
*/

table {
    border-spacing: 0;
}
td, th {
   border-style: solid;
   border-color: black;
   border-width: 1px 1px 0 0;
}
th:first-child {
   border-left-width: 1px;
}
tr:last-child td,
tr:last-child th {
   border-bottom-width: 1px;
}

/* Unimportant styles */

.container {
    width: 250px;
}
td, th {
   padding: 5px;
}
<div class="container">
    
<div class="fixed-th-table-wrapper">
<!-- fixed-th-table -->
<table>
    <tr>
         <th>aaaaaaa</th>
         <td>ccccccccccc asdsad asd as</td>
         <td>ccccccccccc asdsad asd as</td>
    </tr>
    <tr>
         <th>cccccccc</th>
         <td>xxxxxxxxxxxxxxxxxxxx yyyyyyyyyyyyyy zzzzzzzzzzzzz</td>
         <td>xxxxxxxxxxxxxxxxxxxx yyyyyyyyyyyyyy zzzzzzzzzzzzz</td>
    </tr>
</table>
</div>
    
<div class="scrolled-td-table-wrapper">
<!-- scrolled-td-table
     - same as fixed-th-table -->
<table>
    <tr>
         <th>aaaaaaa</th>
         <td>ccccccccccc asdsad asd as</td>
         <td>ccccccccccc asdsad asd as</td>
    </tr>
    <tr>
         <th>cccccccc</th>
         <td>xxxxxxxxxxxxxxxxxxxx yyyyyyyyyyyyyy zzzzzzzzzzzzz</td>
         <td>xxxxxxxxxxxxxxxxxxxx yyyyyyyyyyyyyy zzzzzzzzzzzzz</td>
    </tr>
</table>
</div>
    
</div>


推荐阅读