简体   繁体   English

CSS 网格 - 突出显示单元格直到悬停的单元格

[英]CSS Grid - Highlight cells up to the hovered cell

In a grid, I want to highlight group of cells - a rectangle shape - starting from top left cell up to the cell under the mouse position.在网格中,我想突出显示一组单元格 - 一个矩形 - 从左上角单元格到鼠标 position 下的单元格。

Let's say our grid initially looks like this:假设我们的网格最初看起来像这样:

 .grid { display: grid; grid-template-columns: repeat(5, 50px); grid-template-rows: repeat(5, 50px); gap: 5px; }.grid-item { display: flex; justify-content: center; align-items: center; background: lightgray; }
 <div class="grid"> <div class="grid-item">1</div> <div class="grid-item">2</div> <div class="grid-item">3</div> <div class="grid-item">4</div> <div class="grid-item">5</div> <div class="grid-item">6</div> <div class="grid-item">7</div> <div class="grid-item">8</div> <div class="grid-item">9</div> <div class="grid-item">10</div> <div class="grid-item">11</div> <div class="grid-item">12</div> <div class="grid-item">13</div> <div class="grid-item">14</div> <div class="grid-item">15</div> <div class="grid-item">16</div> <div class="grid-item">17</div> <div class="grid-item">18</div> <div class="grid-item">19</div> <div class="grid-item">20</div> <div class="grid-item">21</div> <div class="grid-item">22</div> <div class="grid-item">23</div> <div class="grid-item">24</div> <div class="grid-item">25</div> </div>

And now the user hovers with the mouse over cell number 18. The grid should look like this now:现在用户将鼠标悬停在 18 号单元格上。网格现在应该如下所示:

 .grid { display: grid; grid-template-columns: repeat(5, 50px); grid-template-rows: repeat(5, 50px); gap: 5px; }.grid-item { display: flex; justify-content: center; align-items: center; background: lightgray; }.grid-item-blue { background: lightblue; }
 <div class="grid"> <div class="grid-item grid-item-blue">1</div> <div class="grid-item grid-item-blue">2</div> <div class="grid-item grid-item-blue">3</div> <div class="grid-item">4</div> <div class="grid-item">5</div> <div class="grid-item grid-item-blue">6</div> <div class="grid-item grid-item-blue">7</div> <div class="grid-item grid-item-blue">8</div> <div class="grid-item">9</div> <div class="grid-item">10</div> <div class="grid-item grid-item-blue">11</div> <div class="grid-item grid-item-blue">12</div> <div class="grid-item grid-item-blue">13</div> <div class="grid-item">14</div> <div class="grid-item">15</div> <div class="grid-item grid-item-blue">16</div> <div class="grid-item grid-item-blue">17</div> <div class="grid-item grid-item-blue">18</div> <div class="grid-item">19</div> <div class="grid-item">20</div> <div class="grid-item">21</div> <div class="grid-item">22</div> <div class="grid-item">23</div> <div class="grid-item">24</div> <div class="grid-item">25</div> </div>

I prefer css solution.我更喜欢 css 解决方案。 Is is possible using css only?是否可以仅使用 css? If not, how would you do this in JS?如果没有,您将如何在 JS 中执行此操作?

Here is pure CSS solution with flexbox but too complex.这是纯 CSS 解决方案,带有 flexbox 但过于复杂。

 .grid { display: flex; flex-wrap: wrap; flex-flow: wrap-reverse; direction: rtl; width: calc(50px*5 + 5px*4); }.grid-item { width: 50px; height: 50px; display: flex; justify-content: center; align-items: center; background: lightgray; margin-bottom: 5px; }.grid-item:not(:nth-child(5n + 1)) { margin-right: 5px; }.grid-item:nth-child(5n - 4):hover, .grid-item:nth-child(5n - 4):hover~.grid-item, .grid-item:nth-child(5n - 3):hover, .grid-item:nth-child(5n - 3):hover~.grid-item:not(:nth-child(5n + 1)), .grid-item:nth-child(5n - 2):hover, .grid-item:nth-child(5n - 2):hover~.grid-item:not(:nth-child(5n + 1)):not(:nth-child(5n + 2)), .grid-item:nth-child(5n - 1):hover, .grid-item:nth-child(5n - 1):hover~.grid-item:not(:nth-child(5n + 1)):not(:nth-child(5n + 2)):not(:nth-child(5n + 3)), .grid-item:nth-child(5n):hover, .grid-item:nth-child(5n):hover~.grid-item:not(:nth-child(5n + 1)):not(:nth-child(5n + 2)):not(:nth-child(5n + 3)):not(:nth-child(5n + 4)) { background: lightblue; }
 <div class="grid"> <div class="grid-item">25</div> <div class="grid-item">24</div> <div class="grid-item">23</div> <div class="grid-item">22</div> <div class="grid-item">21</div> <div class="grid-item">20</div> <div class="grid-item">19</div> <div class="grid-item">18</div> <div class="grid-item">17</div> <div class="grid-item">16</div> <div class="grid-item">15</div> <div class="grid-item">14</div> <div class="grid-item">13</div> <div class="grid-item">12</div> <div class="grid-item">11</div> <div class="grid-item">10</div> <div class="grid-item">9</div> <div class="grid-item">8</div> <div class="grid-item">7</div> <div class="grid-item">6</div> <div class="grid-item">5</div> <div class="grid-item">4</div> <div class="grid-item">3</div> <div class="grid-item">2</div> <div class="grid-item">1</div> </div>

Here's a pure css Idea if you don't mind nesting the content on more level just to put it over the fake background.这是一个纯粹的 css 想法,如果你不介意将内容嵌套在更多层次上只是为了把它放在假背景上。

 .grid { overflow:hidden; display: grid; grid-template-columns: repeat(5, 50px); grid-template-rows: repeat(5, 50px); gap: 5px; }.grid-item { background: lightgray; position: relative; display: flex; }.grid-item>span { z-index: 2; width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; }.grid-item:hover:before { position: absolute; content: ''; background: linear-gradient(to left,#ff000000 0px 50px,#ffffff 50px 55px) 0 0/55px, linear-gradient(to top,lightblue 0px 50px,#ffffff00 50px 55px) 0 0/1px 55px; z-index: 1; width: calc(55px * 9); height: calc(55px * 9); bottom: 0; right: 0; }
 <div class="grid"> <div class="grid-item"><span>1</span></div> <div class="grid-item"><span>2</span></div> <div class="grid-item"><span>3</span></div> <div class="grid-item"><span>4</span></div> <div class="grid-item"><span>5</span></div> <div class="grid-item"><span>6</span></div> <div class="grid-item"><span>7</span></div> <div class="grid-item"><span>8</span></div> <div class="grid-item"><span>9</span></div> <div class="grid-item"><span>10</span></div> <div class="grid-item"><span>11</span></div> <div class="grid-item"><span>12</span></div> <div class="grid-item"><span>13</span></div> <div class="grid-item"><span>14</span></div> <div class="grid-item"><span>15</span></div> <div class="grid-item"><span>16</span></div> <div class="grid-item"><span>17</span></div> <div class="grid-item"><span>18</span></div> <div class="grid-item"><span>19</span></div> <div class="grid-item"><span>20</span></div> <div class="grid-item"><span>21</span></div> <div class="grid-item"><span>22</span></div> <div class="grid-item"><span>23</span></div> <div class="grid-item"><span>24</span></div> <div class="grid-item"><span>25</span></div> </div>

I think it very hard to do this with pure CSS, especially if you plan to expand this grid.我认为用纯 CSS 很难做到这一点,特别是如果你打算扩展这个网格。 However it can be done with javascript但是它可以用 javascript 来完成

 document.querySelector('.grid').addEventListener("mouseover", function (event) { Array.from(this.querySelectorAll('.grid-item')).forEach(node => { var nodePosition = node.getBoundingClientRect(); if (nodePosition.x <= event.clientX && nodePosition.y <= event.clientY) { node.classList.add('grid-item-blue') } else { node.classList.remove('grid-item-blue') } }) });
 .grid { display: grid; grid-template-columns: repeat(5, 50px); grid-template-rows: repeat(5, 50px); gap: 5px; }.grid-item { display: flex; justify-content: center; align-items: center; background: lightgray; }.grid-item-blue { background: lightblue; }
 <!DOCTYPE html> <html lang="en"> <head> </head> <body> <div class="grid"> <div class="grid-item">1</div> <div class="grid-item">2</div> <div class="grid-item">3</div> <div class="grid-item">4</div> <div class="grid-item">5</div> <div class="grid-item">6</div> <div class="grid-item">7</div> <div class="grid-item">8</div> <div class="grid-item">9</div> <div class="grid-item">10</div> <div class="grid-item">11</div> <div class="grid-item">12</div> <div class="grid-item">13</div> <div class="grid-item">14</div> <div class="grid-item">15</div> <div class="grid-item">16</div> <div class="grid-item">17</div> <div class="grid-item">18</div> <div class="grid-item">19</div> <div class="grid-item">20</div> <div class="grid-item">21</div> <div class="grid-item">22</div> <div class="grid-item">23</div> <div class="grid-item">24</div> <div class="grid-item">25</div> </div> </body>

You can also use debouncing to reduce the number of times the mouseover callback function is triggered.您还可以使用去抖动来减少触发mouseover回调 function 的次数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM