Bootstrap表格粘性列z-index问题:下拉菜单被下方列遮挡
问题描述
为表格第一列设置position: sticky属性后,Bootstrap 4的Dropdown下拉菜单展开时会被下方的表格列遮挡,即使给下拉菜单设置更高的z-index也无效。
原因分析
所有设置了position: sticky的第一列单元格(td:first-child)都被赋予了z-index: 1,它们属于同一层级的堆叠上下文。由于DOM顺序中后面的行在前面的行之后,后面行的sticky单元格会覆盖前面行的单元格及其子元素——哪怕给下拉菜单设置更高的z-index,它也受限于父单元格的堆叠上下文,无法突破后面行单元格的覆盖。
解决方案
方法1:使用Bootstrap内置属性脱离堆叠上下文
给下拉按钮添加data-boundary="body"属性,让下拉菜单被渲染到<body>标签下,脱离表格单元格的堆叠上下文,这样它默认的z-index: 1000就能覆盖所有sticky单元格的z-index: 1。
修改后的下拉按钮代码片段:
<button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" data-boundary="body">Dropdown</button>
方法2:调整CSS层级(备选)
如果不想修改HTML结构,可以通过CSS调整堆叠上下文:
- 移除sticky单元格的
z-index: 1(改为z-index: auto),避免创建独立堆叠上下文; - 给表格容器设置
position: relative和z-index: 1,确保sticky列在其他列上方; - 给下拉菜单设置更高的
z-index:
th:first-child, td:first-child { position: sticky; left: 0; z-index: auto; /* 移除原有z-index,避免创建堆叠上下文 */ background-color: #ff0000; } .table-container { width: 100%; overflow-x: scroll; position: relative; /* 创建堆叠上下文 */ z-index: 1; } .dropdown-menu { z-index: 2; /* 高于表格容器的z-index */ }
完整示例代码(方法1)
td { min-width: 160px; } th:first-child, td:first-child { position: sticky; left: 0; z-index: 1; background-color: #ff0000; } .table-container { width: 100%; overflow-x: scroll; } table { width: 200%; }
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"> <div class="container-fluid"> <div class="table-container"> <table class="table table-striped table-bordered"> <thead> <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> <th>Column 7</th> <th>Column 8</th> <th>Column 9</th> <th>Column 10</th> </tr> </thead> <tbody> <tr> <td> <div class="dropdown"> <button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" data-boundary="body">Dropdown</button> <div class="dropdown-menu" aria-labelledby="dropdownMenuButton"> <a class="dropdown-item" href="#">Action</a> <a class="dropdown-item" href="#">Another action</a> <a class="dropdown-item" href="#">Something else here</a> </div> </div> </td> <td>Row 1, Column 2</td> <td>Row 1, Column 3</td> <td>Row 1, Column 4</td> <td>Row 1, Column 5</td> <td>Row 1, Column 6</td> <td>Row 1, Column 7</td> <td>Row 1, Column 8</td> <td>Row 1, Column 9</td> <td>Row 1, Column 10</td> </tr> <tr> <td> <div class="dropdown"> <button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" data-boundary="body">Dropdown</button> <div class="dropdown-menu" aria-labelledby="dropdownMenuButton"> <a class="dropdown-item" href="#">Action</a> <a class="dropdown-item" href="#">Another action</a> <a class="dropdown-item" href="#">Something else here</a> </div> </div> </td> <td>Row 2, Column 2</td> <td>Row 2 Column 3</td> <td>Row 2, Column 4</td> <td>Row 2, Column 5</td> <td>Row 2, Column 6</td> <td>Row 2, Column 7</td> <td>Row 2, Column 8</td> <td>Row 2, Column 9</td> <td>Row 2, Column 10</td> </tr> <tr> <td> <div class="dropdown"> <button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" data-boundary="body">Dropdown</button> <div class="dropdown-menu" aria-labelledby="dropdownMenuButton"> <a class="dropdown-item" href="#">Action</a> <a class="dropdown-item" href="#">Another action</a> <a class="dropdown-item" href="#">Something else here</a> </div> </div> </td> <td>Row 3, Column 2</td> <td>Row 3, Column 3</td> <td>Row 3, Column 4</td> <td>Row 3, Column 5</td> <td>Row 3, Column 6</td> <td>Row 3, Column 7</td> <td>Row 3, Column 8</td> <td>Row 3, Column 9</td> <td>Row 3, Column 10</td> </tr> </tbody> </table> </div> </div> <script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-Fy6S3B9q64WdZWQUiU+q4/2Lc9npb8tCaSX9FK7E8HnRr0Jz8D6OP9dO5Vg3Q9ct" crossorigin="anonymous"></script>
内容的提问来源于stack exchange,提问作者Eddy Marais
相关产品推荐
相关产品推荐

