如何让 Bootstrap 下拉菜单显示在粘性 table headers 前面?
How to make a Bootstrap dropdown show up in front of sticky table headers?
我按照 CSS Tricks tutorial 获得了带有粘性 header 和第一列的 table,并尝试在第一列内添加 Bootstrap 下拉列表。
问题是,下拉列表显示在 parent 单元格的前面,但在第一列的所有其他单元格后面:
我试过将单元格的位置更改为相对位置,将下拉菜单的 z-index 切换为更高的值,但下拉菜单仍位于第一列之后。
这是一个 JSFiddle,其中包含一个最小的、可重现的示例:https://jsfiddle.net/maxencelav/hwsrcmL6/14/
@import url("https://fonts.googleapis.com/css2?family=Fraunces:ital,wght@0,700;1,200&display=swap");
table {
font-family: "Fraunces", serif;
font-size: 125%;
white-space: nowrap;
margin: 3px;
border: none;
border-collapse: separate;
border-spacing: 0;
table-layout: fixed;
border: 1px solid black;
}
table td,
table th {
border: 1px solid black;
padding: 0.5rem 1rem;
}
table thead th {
padding: 3px;
position: sticky;
top: 0;
z-index: 1;
width: 25vw;
background: white;
}
table td {
background: #fff;
padding: 4px 5px;
text-align: center;
}
table tbody th {
font-weight: 100;
font-style: italic;
text-align: left;
position: relative;
}
table thead th:first-child {
position: sticky;
left: 0;
z-index: 2;
}
table tbody th {
position: sticky;
left: 0;
background: white;
z-index: 1;
}
caption {
text-align: left;
padding: 0.25rem;
position: sticky;
left: 0;
}
[role="region"][aria-labelledby][tabindex] {
width: 100%;
max-height: 98vh;
overflow: auto;
}
#team-cell-container {
display: grid;
grid-template-columns: 1fr auto;
align-items: center;
margin: 0;
gap: 5px;
}
<script src="https://code.jquery.com/jquery-3.4.1.slim.js"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.js"></script>
<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.css" rel="stylesheet" />
<!-- Based off https://css-tricks.com/a-table-with-both-a-sticky-header-and-a-sticky-first-column/ -->
<table>
<thead>
<tr>
<th>Teams</th>
<th>1</th>
<th>2</th>
<th>3</th>
<th>4</th>
<th>5</th>
<th>6</th>
<th>7</th>
<th>8</th>
<th>9</th>
<th>Runs</th>
</tr>
</thead>
<tbody>
<tr>
<th>
<div id="team-cell-container">
Milwaukee Brewers
<div class="dropdown">
<i class="fa fa-cog" type="button" id="dropdown-item" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"></i>
<div class="dropdown-menu" aria-labelledby="dropdown-item">
<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>
</div>
</th>
<td>2</td>
<td>1</td>
<td>4</td>
<td>0</td>
<td>3</td>
<td>1</td>
<td>1</td>
<td>0</td>
<td>1</td>
<td>13</td>
</tr>
<tr>
<th>Los Angles Dodgers</th>
<td>4</td>
<td>2</td>
<td>0</td>
<td>0</td>
<td>3</td>
<td>2</td>
<td>4</td>
<td>2</td>
<td>3</td>
<td>20</td>
</tr>
<tr>
<th>New York Mets</th>
<td>0</td>
<td>1</td>
<td>2</td>
<td>0</td>
<td>0</td>
<td>2</td>
<td>4</td>
<td>0</td>
<td>3</td>
<td>12</td>
</tr>
<tr>
<th>St. Louis Cardinals</th>
<td>3</td>
<td>4</td>
<td>1</td>
<td>3</td>
<td>2</td>
<td>4</td>
<td>3</td>
<td>2</td>
<td>3</td>
<td>25</td>
</tr>
</tbody>
</table>
这是 CSS position
和 z-index
的问题。由 this question. (Or see my testing) 解释。
要使 position: absolute
高 z-index
出现在其他亲属之上,您必须将其他人的 z-index
设置为低于父级的 z-index
落下 。这证实了 this answer.
的工作
首先,为您的 table 添加一些身份。
<!-- Based off https://css-tricks.com/a-table-with-both-a-sticky-header-and-a-sticky-first-column/ -->
<table id="my-table">
<thead>
<tr>
<th>Teams</th>
<th>1</th>
<th>2</th>
<th>3</th>
<th>4</th>
<th>5</th>
<th>6</th>
<th>7</th>
<th>8</th>
<th>9</th>
<th>Runs</th>
</tr>
</thead>
<tbody>
<tr>
<th>
<div id="team-cell-container">
Milwaukee Brewers
<div class="dropdown">
<i class="fa fa-cog" type="button" id="dropdown-item" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"></i>
<div class="dropdown-menu" aria-labelledby="dropdown-item">
<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>
</div>
</th>
<td>2</td>
<td>1</td>
<td>4</td>
<td>0</td>
<td>3</td>
<td>1</td>
<td>1</td>
<td>0</td>
<td>1</td>
<td>13</td>
</tr>
<tr>
<th>Los Angles Dodgers</th>
<td>4</td>
<td>2</td>
<td>0</td>
<td>0</td>
<td>3</td>
<td>2</td>
<td>4</td>
<td>2</td>
<td>3</td>
<td>20</td>
</tr>
<tr>
<th>New York Mets</th>
<td>0</td>
<td>1</td>
<td>2</td>
<td>0</td>
<td>0</td>
<td>2</td>
<td>4</td>
<td>0</td>
<td>3</td>
<td>12</td>
</tr>
<tr>
<th>St. Louis Cardinals</th>
<td>3</td>
<td>4</td>
<td>1</td>
<td>3</td>
<td>2</td>
<td>4</td>
<td>3</td>
<td>2</td>
<td>3</td>
<td>25</td>
</tr>
<tr>
<th>Houston Astros</th>
<td>3</td>
<td>2</td>
<td>1</td>
<td>4</td>
<td>2</td>
<td>3</td>
<td>1</td>
<td>3</td>
<td>1</td>
<td>20</td>
</tr>
<tr>
<th>Toronto Blue Jays</th>
<td>2</td>
<td>4</td>
<td>4</td>
<td>1</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>1</td>
<td>22</td>
</tr>
<tr>
<th>Boston Red Sox</th>
<td>4</td>
<td>4</td>
<td>4</td>
<td>0</td>
<td>3</td>
<td>0</td>
<td>0</td>
<td>1</td>
<td>1</td>
<td>17</td>
</tr>
<tr>
<th>Chicago Cubs</th>
<td>1</td>
<td>1</td>
<td>0</td>
<td>0</td>
<td>2</td>
<td>2</td>
<td>2</td>
<td>0</td>
<td>4</td>
<td>12</td>
</tr>
<tr>
<th>Philadelphia Phillies</th>
<td>0</td>
<td>4</td>
<td>2</td>
<td>0</td>
<td>4</td>
<td>1</td>
<td>0</td>
<td>4</td>
<td>2</td>
<td>17</td>
</tr>
<tr>
<th>Chicago White Sox</th>
<td>2</td>
<td>0</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>2</td>
<td>4</td>
<td>2</td>
<td>0</td>
<td>19</td>
</tr>
<tr>
<th>San Diego Padres</th>
<td>2</td>
<td>2</td>
<td>3</td>
<td>0</td>
<td>4</td>
<td>2</td>
<td>2</td>
<td>0</td>
<td>2</td>
<td>17</td>
</tr>
<tr>
<th>Cleveland Indians</th>
<td>1</td>
<td>0</td>
<td>0</td>
<td>3</td>
<td>2</td>
<td>1</td>
<td>3</td>
<td>1</td>
<td>0</td>
<td>11</td>
</tr>
<tr>
<th>San Francisco Giants</th>
<td>1</td>
<td>3</td>
<td>1</td>
<td>4</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>17</td>
</tr>
<tr>
<th>Cincinatti Reds</th>
<td>2</td>
<td>2</td>
<td>4</td>
<td>1</td>
<td>4</td>
<td>2</td>
<td>2</td>
<td>3</td>
<td>3</td>
<td>23</td>
</tr>
<tr>
<th>Minnesota Twins</th>
<td>4</td>
<td>4</td>
<td>1</td>
<td>0</td>
<td>2</td>
<td>0</td>
<td>3</td>
<td>1</td>
<td>3</td>
<td>18</td>
</tr>
<tr>
<th>Tampa Bay Rays</th>
<td>4</td>
<td>1</td>
<td>3</td>
<td>0</td>
<td>2</td>
<td>1</td>
<td>4</td>
<td>0</td>
<td>1</td>
<td>16</td>
</tr>
<tr>
<th>Miami Marlins</th>
<td>0</td>
<td>3</td>
<td>0</td>
<td>4</td>
<td>3</td>
<td>3</td>
<td>0</td>
<td>1</td>
<td>4</td>
<td>18</td>
</tr>
<tr>
<th>Oakland Athletics</th>
<td>3</td>
<td>3</td>
<td>2</td>
<td>0</td>
<td>4</td>
<td>2</td>
<td>0</td>
<td>1</td>
<td>0</td>
<td>15</td>
</tr>
<tr>
<th>Detroit Tigers</th>
<td>3</td>
<td>4</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>2</td>
<td>0</td>
<td>0</td>
<td>4</td>
<td>19</td>
</tr>
<tr>
<th>Pittsburgh Pirates</th>
<td>2</td>
<td>2</td>
<td>0</td>
<td>3</td>
<td>0</td>
<td>2</td>
<td>2</td>
<td>2</td>
<td>2</td>
<td>15</td>
</tr>
<tr>
<th>Seattle Mariners</th>
<td>1</td>
<td>3</td>
<td>3</td>
<td>1</td>
<td>2</td>
<td>2</td>
<td>0</td>
<td>4</td>
<td>0</td>
<td>16</td>
</tr>
<tr>
<th>Atlanta Braves</th>
<td>4</td>
<td>3</td>
<td>0</td>
<td>3</td>
<td>4</td>
<td>4</td>
<td>4</td>
<td>4</td>
<td>3</td>
<td>29</td>
</tr>
</tbody>
</table>
</div>
然后使用 Bootstrap dropdown events 监听显示或隐藏下拉列表元素。
$('#my-table .dropdown').on('show.bs.dropdown', (event) => {
let thisTable = event.target.closest('table');
thisTable.classList.add('dropdowns-opened');
// add class to all <tr>
$(thisTable).find('tr').addClass('non-dropdown');
// remove class of this <tr>
event.target.closest('tr').classList.remove('non-dropdown');
});
$('#my-table .dropdown').on('hidden.bs.dropdown', (event) => {
let thisTable = event.target.closest('table');
thisTable.classList.remove('dropdowns-opened');
$(thisTable).find('tr').removeClass('non-dropdown');
});
上面的JavaScript将在下拉元素显示或隐藏时添加和删除class。
现在,添加一些 CSS class 使下拉菜单显示在其他菜单之上。
table.dropdowns-opened tbody tr.non-dropdown th {
z-index: 0;
}
如果粘性功能不起作用,您可以将当前的 z-index: 1
更改为 2
,并使用上面的 class 从 z-index: 0
更改为 1
预期。
我按照 CSS Tricks tutorial 获得了带有粘性 header 和第一列的 table,并尝试在第一列内添加 Bootstrap 下拉列表。
问题是,下拉列表显示在 parent 单元格的前面,但在第一列的所有其他单元格后面:
我试过将单元格的位置更改为相对位置,将下拉菜单的 z-index 切换为更高的值,但下拉菜单仍位于第一列之后。
这是一个 JSFiddle,其中包含一个最小的、可重现的示例:https://jsfiddle.net/maxencelav/hwsrcmL6/14/
@import url("https://fonts.googleapis.com/css2?family=Fraunces:ital,wght@0,700;1,200&display=swap");
table {
font-family: "Fraunces", serif;
font-size: 125%;
white-space: nowrap;
margin: 3px;
border: none;
border-collapse: separate;
border-spacing: 0;
table-layout: fixed;
border: 1px solid black;
}
table td,
table th {
border: 1px solid black;
padding: 0.5rem 1rem;
}
table thead th {
padding: 3px;
position: sticky;
top: 0;
z-index: 1;
width: 25vw;
background: white;
}
table td {
background: #fff;
padding: 4px 5px;
text-align: center;
}
table tbody th {
font-weight: 100;
font-style: italic;
text-align: left;
position: relative;
}
table thead th:first-child {
position: sticky;
left: 0;
z-index: 2;
}
table tbody th {
position: sticky;
left: 0;
background: white;
z-index: 1;
}
caption {
text-align: left;
padding: 0.25rem;
position: sticky;
left: 0;
}
[role="region"][aria-labelledby][tabindex] {
width: 100%;
max-height: 98vh;
overflow: auto;
}
#team-cell-container {
display: grid;
grid-template-columns: 1fr auto;
align-items: center;
margin: 0;
gap: 5px;
}
<script src="https://code.jquery.com/jquery-3.4.1.slim.js"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.js"></script>
<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.css" rel="stylesheet" />
<!-- Based off https://css-tricks.com/a-table-with-both-a-sticky-header-and-a-sticky-first-column/ -->
<table>
<thead>
<tr>
<th>Teams</th>
<th>1</th>
<th>2</th>
<th>3</th>
<th>4</th>
<th>5</th>
<th>6</th>
<th>7</th>
<th>8</th>
<th>9</th>
<th>Runs</th>
</tr>
</thead>
<tbody>
<tr>
<th>
<div id="team-cell-container">
Milwaukee Brewers
<div class="dropdown">
<i class="fa fa-cog" type="button" id="dropdown-item" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"></i>
<div class="dropdown-menu" aria-labelledby="dropdown-item">
<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>
</div>
</th>
<td>2</td>
<td>1</td>
<td>4</td>
<td>0</td>
<td>3</td>
<td>1</td>
<td>1</td>
<td>0</td>
<td>1</td>
<td>13</td>
</tr>
<tr>
<th>Los Angles Dodgers</th>
<td>4</td>
<td>2</td>
<td>0</td>
<td>0</td>
<td>3</td>
<td>2</td>
<td>4</td>
<td>2</td>
<td>3</td>
<td>20</td>
</tr>
<tr>
<th>New York Mets</th>
<td>0</td>
<td>1</td>
<td>2</td>
<td>0</td>
<td>0</td>
<td>2</td>
<td>4</td>
<td>0</td>
<td>3</td>
<td>12</td>
</tr>
<tr>
<th>St. Louis Cardinals</th>
<td>3</td>
<td>4</td>
<td>1</td>
<td>3</td>
<td>2</td>
<td>4</td>
<td>3</td>
<td>2</td>
<td>3</td>
<td>25</td>
</tr>
</tbody>
</table>
这是 CSS position
和 z-index
的问题。由 this question. (Or see my testing) 解释。
要使 position: absolute
高 z-index
出现在其他亲属之上,您必须将其他人的 z-index
设置为低于父级的 z-index
落下 。这证实了 this answer.
首先,为您的 table 添加一些身份。
<!-- Based off https://css-tricks.com/a-table-with-both-a-sticky-header-and-a-sticky-first-column/ -->
<table id="my-table">
<thead>
<tr>
<th>Teams</th>
<th>1</th>
<th>2</th>
<th>3</th>
<th>4</th>
<th>5</th>
<th>6</th>
<th>7</th>
<th>8</th>
<th>9</th>
<th>Runs</th>
</tr>
</thead>
<tbody>
<tr>
<th>
<div id="team-cell-container">
Milwaukee Brewers
<div class="dropdown">
<i class="fa fa-cog" type="button" id="dropdown-item" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"></i>
<div class="dropdown-menu" aria-labelledby="dropdown-item">
<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>
</div>
</th>
<td>2</td>
<td>1</td>
<td>4</td>
<td>0</td>
<td>3</td>
<td>1</td>
<td>1</td>
<td>0</td>
<td>1</td>
<td>13</td>
</tr>
<tr>
<th>Los Angles Dodgers</th>
<td>4</td>
<td>2</td>
<td>0</td>
<td>0</td>
<td>3</td>
<td>2</td>
<td>4</td>
<td>2</td>
<td>3</td>
<td>20</td>
</tr>
<tr>
<th>New York Mets</th>
<td>0</td>
<td>1</td>
<td>2</td>
<td>0</td>
<td>0</td>
<td>2</td>
<td>4</td>
<td>0</td>
<td>3</td>
<td>12</td>
</tr>
<tr>
<th>St. Louis Cardinals</th>
<td>3</td>
<td>4</td>
<td>1</td>
<td>3</td>
<td>2</td>
<td>4</td>
<td>3</td>
<td>2</td>
<td>3</td>
<td>25</td>
</tr>
<tr>
<th>Houston Astros</th>
<td>3</td>
<td>2</td>
<td>1</td>
<td>4</td>
<td>2</td>
<td>3</td>
<td>1</td>
<td>3</td>
<td>1</td>
<td>20</td>
</tr>
<tr>
<th>Toronto Blue Jays</th>
<td>2</td>
<td>4</td>
<td>4</td>
<td>1</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>1</td>
<td>22</td>
</tr>
<tr>
<th>Boston Red Sox</th>
<td>4</td>
<td>4</td>
<td>4</td>
<td>0</td>
<td>3</td>
<td>0</td>
<td>0</td>
<td>1</td>
<td>1</td>
<td>17</td>
</tr>
<tr>
<th>Chicago Cubs</th>
<td>1</td>
<td>1</td>
<td>0</td>
<td>0</td>
<td>2</td>
<td>2</td>
<td>2</td>
<td>0</td>
<td>4</td>
<td>12</td>
</tr>
<tr>
<th>Philadelphia Phillies</th>
<td>0</td>
<td>4</td>
<td>2</td>
<td>0</td>
<td>4</td>
<td>1</td>
<td>0</td>
<td>4</td>
<td>2</td>
<td>17</td>
</tr>
<tr>
<th>Chicago White Sox</th>
<td>2</td>
<td>0</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>2</td>
<td>4</td>
<td>2</td>
<td>0</td>
<td>19</td>
</tr>
<tr>
<th>San Diego Padres</th>
<td>2</td>
<td>2</td>
<td>3</td>
<td>0</td>
<td>4</td>
<td>2</td>
<td>2</td>
<td>0</td>
<td>2</td>
<td>17</td>
</tr>
<tr>
<th>Cleveland Indians</th>
<td>1</td>
<td>0</td>
<td>0</td>
<td>3</td>
<td>2</td>
<td>1</td>
<td>3</td>
<td>1</td>
<td>0</td>
<td>11</td>
</tr>
<tr>
<th>San Francisco Giants</th>
<td>1</td>
<td>3</td>
<td>1</td>
<td>4</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>17</td>
</tr>
<tr>
<th>Cincinatti Reds</th>
<td>2</td>
<td>2</td>
<td>4</td>
<td>1</td>
<td>4</td>
<td>2</td>
<td>2</td>
<td>3</td>
<td>3</td>
<td>23</td>
</tr>
<tr>
<th>Minnesota Twins</th>
<td>4</td>
<td>4</td>
<td>1</td>
<td>0</td>
<td>2</td>
<td>0</td>
<td>3</td>
<td>1</td>
<td>3</td>
<td>18</td>
</tr>
<tr>
<th>Tampa Bay Rays</th>
<td>4</td>
<td>1</td>
<td>3</td>
<td>0</td>
<td>2</td>
<td>1</td>
<td>4</td>
<td>0</td>
<td>1</td>
<td>16</td>
</tr>
<tr>
<th>Miami Marlins</th>
<td>0</td>
<td>3</td>
<td>0</td>
<td>4</td>
<td>3</td>
<td>3</td>
<td>0</td>
<td>1</td>
<td>4</td>
<td>18</td>
</tr>
<tr>
<th>Oakland Athletics</th>
<td>3</td>
<td>3</td>
<td>2</td>
<td>0</td>
<td>4</td>
<td>2</td>
<td>0</td>
<td>1</td>
<td>0</td>
<td>15</td>
</tr>
<tr>
<th>Detroit Tigers</th>
<td>3</td>
<td>4</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>2</td>
<td>0</td>
<td>0</td>
<td>4</td>
<td>19</td>
</tr>
<tr>
<th>Pittsburgh Pirates</th>
<td>2</td>
<td>2</td>
<td>0</td>
<td>3</td>
<td>0</td>
<td>2</td>
<td>2</td>
<td>2</td>
<td>2</td>
<td>15</td>
</tr>
<tr>
<th>Seattle Mariners</th>
<td>1</td>
<td>3</td>
<td>3</td>
<td>1</td>
<td>2</td>
<td>2</td>
<td>0</td>
<td>4</td>
<td>0</td>
<td>16</td>
</tr>
<tr>
<th>Atlanta Braves</th>
<td>4</td>
<td>3</td>
<td>0</td>
<td>3</td>
<td>4</td>
<td>4</td>
<td>4</td>
<td>4</td>
<td>3</td>
<td>29</td>
</tr>
</tbody>
</table>
</div>
然后使用 Bootstrap dropdown events 监听显示或隐藏下拉列表元素。
$('#my-table .dropdown').on('show.bs.dropdown', (event) => {
let thisTable = event.target.closest('table');
thisTable.classList.add('dropdowns-opened');
// add class to all <tr>
$(thisTable).find('tr').addClass('non-dropdown');
// remove class of this <tr>
event.target.closest('tr').classList.remove('non-dropdown');
});
$('#my-table .dropdown').on('hidden.bs.dropdown', (event) => {
let thisTable = event.target.closest('table');
thisTable.classList.remove('dropdowns-opened');
$(thisTable).find('tr').removeClass('non-dropdown');
});
上面的JavaScript将在下拉元素显示或隐藏时添加和删除class。
现在,添加一些 CSS class 使下拉菜单显示在其他菜单之上。
table.dropdowns-opened tbody tr.non-dropdown th {
z-index: 0;
}
如果粘性功能不起作用,您可以将当前的 z-index: 1
更改为 2
,并使用上面的 class 从 z-index: 0
更改为 1
预期。