如何使用 CSS 网格布局在行 table 上制作悬停状态
How to make hover state on row table with CSS grid layout
这是使用 CSS 网格布局创建的 table,但我有一个问题,我无法在每一行上设置悬停状态。
我只想为此使用 CSS。
任何人都可以给我一个解决方案吗?
.table {
display: grid;
grid-template-columns: [col-start] auto [col-end];
grid-template-rows: [header-start] 50px [header-end row-start] auto [row-end];
grid-auto-rows: auto;
grid-auto-columns: auto;
grid-gap: 1px;
}
.table>* {
background: gray;
padding: 10px;
}
.heading {
background: navy;
color: #fff;
grid-row: header;
}
<div class="table">
<div class="heading">Title 1</div>
<div class="heading">Title 2</div>
<div class="heading">Title 3</div>
<div class="heading">Title 4</div>
<div class="heading">Title 5</div>
<div class="row">Row 1</div>
<div class="row">Row 1</div>
<div class="row">Row 1</div>
<div class="row">Row 1</div>
<div class="row">Row 1</div>
<div class="row">Row 2</div>
<div class="row">Row 2</div>
<div class="row">Row 2</div>
<div class="row">Row 2</div>
<div class="row">Row 2</div>
<div class="row">Row 3</div>
<div class="row">Row 3</div>
<div class="row">Row 3</div>
<div class="row">Row 3</div>
<div class="row">Row 3</div>
</div>
这是一个使用伪元素的技巧。这个想法是将元素用作背景并使其在左侧和右侧溢出,以便它覆盖所有行。就像那样,如果您将鼠标悬停在行内的任何元素上,您会更改颜色,就像您更改了整行的颜色一样。
这个技巧涉及对标记的一些更改,但也有更多 CSS。
.table {
display: grid;
grid-template-columns: [col-start] auto [col-end];
grid-template-rows: [header-start] 50px [header-end row-start] auto [row-end];
grid-auto-rows: auto;
grid-auto-columns: auto;
grid-gap: 1px;
overflow: hidden;
background: gray;
}
.table>* {
padding: 10px;
position: relative;
}
.heading {
background: navy;
color: #fff;
grid-row: header;
}
.row span {
position: relative;
z-index: 2;
}
.row:before {
content: "";
position: absolute;
top: 0;
bottom: 0;
right: -1000%;
left: -1000%;
z-index: 1;
}
.row:after {
content: "";
position: absolute;
top: 0;
bottom: 0;
right: -1px;
width: 1px;
z-index: 2;
background-color: #fff;
}
.row:nth-child(5n+5)::after {
bottom: -1px;
right: 0;
left: -1000%;
height: 1px;
z-index: 3;
width: auto;
top: auto;
background-color: #fff;
}
.row:hover::before {
background-color: red;
}
<div class="table">
<div class="heading">Title 1</div>
<div class="heading">Title 2</div>
<div class="heading">Title 3</div>
<div class="heading">Title 4</div>
<div class="heading">Title 5</div>
<div class="row"><span>Row 1</span></div>
<div class="row"><span>Row 1</span></div>
<div class="row"><span>Row 1</span></div>
<div class="row"><span>Row 1</span></div>
<div class="row"><span>Row 1</span></div>
<div class="row"><span>Row 2</span></div>
<div class="row"><span>Row 2</span></div>
<div class="row"><span>Row 2</span></div>
<div class="row"><span>Row 2</span></div>
<div class="row"><span>Row 2</span></div>
<div class="row"><span>Row 3</span></div>
<div class="row"><span>Row 3</span></div>
<div class="row"><span>Row 3</span></div>
<div class="row"><span>Row 3</span></div>
<div class="row"><span>Row 3</span></div>
</div>
I have solution for your problem. The example below:
.grid .row {
display: grid;
grid-template-columns: repeat(4, 1fr);
border-bottom: 1px solid gray;
}
.grid .row div {
padding: 10px;
display: flex;
align-items: center;
}
.grid .row:last-child {
border: none;
}
.grid .row:hover {
background-color: #cccccc;
transition: .2s all;
}
<div class='grid'>
<div class='row'>
<div>Header</div>
<div>Header</div>
<div>Header</div>
<div>Header</div>
</div>
<div class='row'>
<div>Content</div>
<div>Content</div>
<div>Content</div>
<div>Content</div>
</div>
<div class='row'>
<div>Content</div>
<div>Content</div>
<div>Content</div>
<div>Content</div>
</div>
<div class='row'>
<div>Content</div>
<div>Content</div>
<div>Content</div>
<div>Content</div>
</div>
</div>
这是我的解决方案,基于兄弟组合器。
主要部分是:
.datacell:hover ~ .datarow {
background-color: rgba(255,255,0,0.5);
}
.datacell:hover ~ .datarow + .datacell ~ .datarow{
background-color: transparent;
}
片段:
.datatable{
display:grid;
grid-gap: 0;
grid-template-columns: auto 1fr auto;
position: relative;
}
.datarow{
grid-column: 1 / 4;
z-index: 0;
}
.datacell{
z-index: 1;
padding: 8px;
border-bottom: 1px solid #c0c0c0;
}
.datacell:hover ~ .datarow {
background-color: rgba(255,255,0,0.5);
}
.datacell:hover ~ .datarow + .datacell ~ .datarow{
background-color: transparent;
}
.row-1{ grid-row: 1;}
.row-2{ grid-row: 2;}
.row-3{ grid-row: 3;}
.col-1{ grid-column: 1;}
.col-2{ grid-column: 2;}
.col-3{ grid-column: 3;}
<div class="datatable">
<div class="datacell col-1 row-1">Row 1 Column 1</div>
<div class="datacell col-2 row-1">Row 1 Column 2</div>
<div class="datacell col-3 row-1">Row 1 Column 3</div>
<div class="datarow row-1"></div>
<div class="datacell col-1 row-2">Row 2 Column 1</div>
<div class="datacell col-2 row-2">Row 2 Column 2</div>
<div class="datacell col-3 row-2">Row 2 Column 3</div>
<div class="datarow row-2"></div>
<div class="datacell col-1 row-3">Row 3 Column 1</div>
<div class="datacell col-2 row-3">Row 3 Column 2</div>
<div class="datacell col-3 row-3">Row 3 Column 3</div>
<div class="datarow row-3"></div>
</div>
html 的结构必须使 .datarow
元素关闭虚拟网格行并跨越所有前面的单元格。为了让单元格和行重叠,需要明确网格内的定位。
由于您将其视为 table,其中元素位于同一行,您还可以将每一行包装在 DIV 中,并将 "display" 设置为 "contents." 这形成了一个用于悬停的无害父元素,然后设置子元素的样式。 (显示:Edge 尚不支持内容。)
.table {
display: grid;
grid-template-columns: [col-start] auto [col-end];
grid-template-rows: [header-start] 50px [header-end row-start] auto [row-end];
grid-auto-rows: auto;
grid-auto-columns: auto;
grid-gap: 1px;
overflow: hidden;
background: gray;
}
.table .row, .table .heading{
padding: 10px;
position: relative;
}
.heading {
background: navy;
color: #fff;
grid-row: header;
}
.row span {
position: relative;
z-index: 2;
}
.rowWrapper{
display: contents;
}
.rowWrapper:hover > div{
background-color: orange;
}
<div class="table">
<div class="heading">Title 1</div>
<div class="heading">Title 2</div>
<div class="heading">Title 3</div>
<div class="heading">Title 4</div>
<div class="heading">Title 5</div>
<div class="rowWrapper">
<div class="row"><span>Row 1</span></div>
<div class="row"><span>Row 1</span></div>
<div class="row"><span>Row 1</span></div>
<div class="row"><span>Row 1</span></div>
<div class="row"><span>Row 1</span></div>
</div>
<div class="rowWrapper">
<div class="row"><span>Row 2</span></div>
<div class="row"><span>Row 2</span></div>
<div class="row"><span>Row 2</span></div>
<div class="row"><span>Row 2</span></div>
<div class="row"><span>Row 2</span></div>
</div>
<div class="rowWrapper">
<div class="row"><span>Row 3</span></div>
<div class="row"><span>Row 3</span></div>
<div class="row"><span>Row 3</span></div>
<div class="row"><span>Row 3</span></div>
<div class="row"><span>Row 3</span></div>
</div>
</div>
我遇到了这个问题。首先,我很想知道为什么如果您使用显示网格,为什么不使用网格项 class?没有必要吗?我觉得是这样的。无论如何,答案是,您需要为所有 div 元素提供网格项 class 并将位置设置为 Relative.
.grid-item {
position: relative;
}
我最终得到了一个不同的解决方案。我的 table 看起来像这样:
.table {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
}
<div class="table">
<span>head1</span>
<span>head2</span>
<span>head3</span>
<span>row1 col1</span>
<span>row1 col2</span>
<span>row1 col3</span>
<span>row2 col1</span>
<span>row2 col2</span>
<span>row2 col3</span>
</div>
现在您需要每 行 的悬停状态。添加一个元素包装每一行会破坏父网格,因为它实际上是您试图在网格中布局的那些行包装器的子级。另外,我更喜欢:
- 没有使用
<table>
。这大约使所需的行数增加了一倍,并且需要更多样式。
- 不使用
nth-child
百思不得其解
- 我没有尝试过的一个不错的选择似乎是将每一行包装在
div
中,添加 class .row
和 display: contents
,然后用 .row:hover > span
作为选择器,您可以添加 opacity: 0.6
。看起来很体面!其他一些答案也朝这个方向发展。
我最终选择了以下我觉得更简单的方法:
.row {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
}
.row:hover {
opacity: 0.6
}
<div class="row">
<span>head1</span>
<span>head2</span>
<span>head3</span>
</div>
<div class="row">
<span>row1 col1</span>
<span>row1 col2</span>
<span>row1 col3</span>
</div>
<div class="row">
<span>row2 col1</span>
<span>row2 col2</span>
<span>row2 col3</span>
</div>
这是使用 CSS 网格布局创建的 table,但我有一个问题,我无法在每一行上设置悬停状态。
我只想为此使用 CSS。
任何人都可以给我一个解决方案吗?
.table {
display: grid;
grid-template-columns: [col-start] auto [col-end];
grid-template-rows: [header-start] 50px [header-end row-start] auto [row-end];
grid-auto-rows: auto;
grid-auto-columns: auto;
grid-gap: 1px;
}
.table>* {
background: gray;
padding: 10px;
}
.heading {
background: navy;
color: #fff;
grid-row: header;
}
<div class="table">
<div class="heading">Title 1</div>
<div class="heading">Title 2</div>
<div class="heading">Title 3</div>
<div class="heading">Title 4</div>
<div class="heading">Title 5</div>
<div class="row">Row 1</div>
<div class="row">Row 1</div>
<div class="row">Row 1</div>
<div class="row">Row 1</div>
<div class="row">Row 1</div>
<div class="row">Row 2</div>
<div class="row">Row 2</div>
<div class="row">Row 2</div>
<div class="row">Row 2</div>
<div class="row">Row 2</div>
<div class="row">Row 3</div>
<div class="row">Row 3</div>
<div class="row">Row 3</div>
<div class="row">Row 3</div>
<div class="row">Row 3</div>
</div>
这是一个使用伪元素的技巧。这个想法是将元素用作背景并使其在左侧和右侧溢出,以便它覆盖所有行。就像那样,如果您将鼠标悬停在行内的任何元素上,您会更改颜色,就像您更改了整行的颜色一样。
这个技巧涉及对标记的一些更改,但也有更多 CSS。
.table {
display: grid;
grid-template-columns: [col-start] auto [col-end];
grid-template-rows: [header-start] 50px [header-end row-start] auto [row-end];
grid-auto-rows: auto;
grid-auto-columns: auto;
grid-gap: 1px;
overflow: hidden;
background: gray;
}
.table>* {
padding: 10px;
position: relative;
}
.heading {
background: navy;
color: #fff;
grid-row: header;
}
.row span {
position: relative;
z-index: 2;
}
.row:before {
content: "";
position: absolute;
top: 0;
bottom: 0;
right: -1000%;
left: -1000%;
z-index: 1;
}
.row:after {
content: "";
position: absolute;
top: 0;
bottom: 0;
right: -1px;
width: 1px;
z-index: 2;
background-color: #fff;
}
.row:nth-child(5n+5)::after {
bottom: -1px;
right: 0;
left: -1000%;
height: 1px;
z-index: 3;
width: auto;
top: auto;
background-color: #fff;
}
.row:hover::before {
background-color: red;
}
<div class="table">
<div class="heading">Title 1</div>
<div class="heading">Title 2</div>
<div class="heading">Title 3</div>
<div class="heading">Title 4</div>
<div class="heading">Title 5</div>
<div class="row"><span>Row 1</span></div>
<div class="row"><span>Row 1</span></div>
<div class="row"><span>Row 1</span></div>
<div class="row"><span>Row 1</span></div>
<div class="row"><span>Row 1</span></div>
<div class="row"><span>Row 2</span></div>
<div class="row"><span>Row 2</span></div>
<div class="row"><span>Row 2</span></div>
<div class="row"><span>Row 2</span></div>
<div class="row"><span>Row 2</span></div>
<div class="row"><span>Row 3</span></div>
<div class="row"><span>Row 3</span></div>
<div class="row"><span>Row 3</span></div>
<div class="row"><span>Row 3</span></div>
<div class="row"><span>Row 3</span></div>
</div>
I have solution for your problem. The example below:
.grid .row {
display: grid;
grid-template-columns: repeat(4, 1fr);
border-bottom: 1px solid gray;
}
.grid .row div {
padding: 10px;
display: flex;
align-items: center;
}
.grid .row:last-child {
border: none;
}
.grid .row:hover {
background-color: #cccccc;
transition: .2s all;
}
<div class='grid'>
<div class='row'>
<div>Header</div>
<div>Header</div>
<div>Header</div>
<div>Header</div>
</div>
<div class='row'>
<div>Content</div>
<div>Content</div>
<div>Content</div>
<div>Content</div>
</div>
<div class='row'>
<div>Content</div>
<div>Content</div>
<div>Content</div>
<div>Content</div>
</div>
<div class='row'>
<div>Content</div>
<div>Content</div>
<div>Content</div>
<div>Content</div>
</div>
</div>
这是我的解决方案,基于兄弟组合器。
主要部分是:
.datacell:hover ~ .datarow {
background-color: rgba(255,255,0,0.5);
}
.datacell:hover ~ .datarow + .datacell ~ .datarow{
background-color: transparent;
}
片段:
.datatable{
display:grid;
grid-gap: 0;
grid-template-columns: auto 1fr auto;
position: relative;
}
.datarow{
grid-column: 1 / 4;
z-index: 0;
}
.datacell{
z-index: 1;
padding: 8px;
border-bottom: 1px solid #c0c0c0;
}
.datacell:hover ~ .datarow {
background-color: rgba(255,255,0,0.5);
}
.datacell:hover ~ .datarow + .datacell ~ .datarow{
background-color: transparent;
}
.row-1{ grid-row: 1;}
.row-2{ grid-row: 2;}
.row-3{ grid-row: 3;}
.col-1{ grid-column: 1;}
.col-2{ grid-column: 2;}
.col-3{ grid-column: 3;}
<div class="datatable">
<div class="datacell col-1 row-1">Row 1 Column 1</div>
<div class="datacell col-2 row-1">Row 1 Column 2</div>
<div class="datacell col-3 row-1">Row 1 Column 3</div>
<div class="datarow row-1"></div>
<div class="datacell col-1 row-2">Row 2 Column 1</div>
<div class="datacell col-2 row-2">Row 2 Column 2</div>
<div class="datacell col-3 row-2">Row 2 Column 3</div>
<div class="datarow row-2"></div>
<div class="datacell col-1 row-3">Row 3 Column 1</div>
<div class="datacell col-2 row-3">Row 3 Column 2</div>
<div class="datacell col-3 row-3">Row 3 Column 3</div>
<div class="datarow row-3"></div>
</div>
html 的结构必须使 .datarow
元素关闭虚拟网格行并跨越所有前面的单元格。为了让单元格和行重叠,需要明确网格内的定位。
由于您将其视为 table,其中元素位于同一行,您还可以将每一行包装在 DIV 中,并将 "display" 设置为 "contents." 这形成了一个用于悬停的无害父元素,然后设置子元素的样式。 (显示:Edge 尚不支持内容。)
.table {
display: grid;
grid-template-columns: [col-start] auto [col-end];
grid-template-rows: [header-start] 50px [header-end row-start] auto [row-end];
grid-auto-rows: auto;
grid-auto-columns: auto;
grid-gap: 1px;
overflow: hidden;
background: gray;
}
.table .row, .table .heading{
padding: 10px;
position: relative;
}
.heading {
background: navy;
color: #fff;
grid-row: header;
}
.row span {
position: relative;
z-index: 2;
}
.rowWrapper{
display: contents;
}
.rowWrapper:hover > div{
background-color: orange;
}
<div class="table">
<div class="heading">Title 1</div>
<div class="heading">Title 2</div>
<div class="heading">Title 3</div>
<div class="heading">Title 4</div>
<div class="heading">Title 5</div>
<div class="rowWrapper">
<div class="row"><span>Row 1</span></div>
<div class="row"><span>Row 1</span></div>
<div class="row"><span>Row 1</span></div>
<div class="row"><span>Row 1</span></div>
<div class="row"><span>Row 1</span></div>
</div>
<div class="rowWrapper">
<div class="row"><span>Row 2</span></div>
<div class="row"><span>Row 2</span></div>
<div class="row"><span>Row 2</span></div>
<div class="row"><span>Row 2</span></div>
<div class="row"><span>Row 2</span></div>
</div>
<div class="rowWrapper">
<div class="row"><span>Row 3</span></div>
<div class="row"><span>Row 3</span></div>
<div class="row"><span>Row 3</span></div>
<div class="row"><span>Row 3</span></div>
<div class="row"><span>Row 3</span></div>
</div>
</div>
我遇到了这个问题。首先,我很想知道为什么如果您使用显示网格,为什么不使用网格项 class?没有必要吗?我觉得是这样的。无论如何,答案是,您需要为所有 div 元素提供网格项 class 并将位置设置为 Relative.
.grid-item {
position: relative;
}
我最终得到了一个不同的解决方案。我的 table 看起来像这样:
.table {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
}
<div class="table">
<span>head1</span>
<span>head2</span>
<span>head3</span>
<span>row1 col1</span>
<span>row1 col2</span>
<span>row1 col3</span>
<span>row2 col1</span>
<span>row2 col2</span>
<span>row2 col3</span>
</div>
现在您需要每 行 的悬停状态。添加一个元素包装每一行会破坏父网格,因为它实际上是您试图在网格中布局的那些行包装器的子级。另外,我更喜欢:
- 没有使用
<table>
。这大约使所需的行数增加了一倍,并且需要更多样式。 - 不使用
nth-child
百思不得其解 - 我没有尝试过的一个不错的选择似乎是将每一行包装在
div
中,添加 class.row
和display: contents
,然后用.row:hover > span
作为选择器,您可以添加opacity: 0.6
。看起来很体面!其他一些答案也朝这个方向发展。
我最终选择了以下我觉得更简单的方法:
.row {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
}
.row:hover {
opacity: 0.6
}
<div class="row">
<span>head1</span>
<span>head2</span>
<span>head3</span>
</div>
<div class="row">
<span>row1 col1</span>
<span>row1 col2</span>
<span>row1 col3</span>
</div>
<div class="row">
<span>row2 col1</span>
<span>row2 col2</span>
<span>row2 col3</span>
</div>