【问题标题】:CSS Grid - Highlight cells up to the hovered cellCSS Grid - 突出显示单元格直到悬停的单元格
【发布时间】:2020-07-15 12:38:59
【问题描述】:

在网格中,我想突出显示一组单元格 - 一个矩形 - 从左上角单元格开始直到鼠标位置下方的单元格。

假设我们的网格最初看起来像这样:

.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>

现在用户将鼠标悬停在 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>

我更喜欢 css 解决方案。 是否可以仅使用css?如果没有,你会如何在 JS 中做到这一点?

【问题讨论】:

    标签: javascript css css-grid


    【解决方案1】:

    如果您不介意将内容嵌套在更多层次上只是为了将其放在假背景上,那么这是一个纯 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>

    【讨论】:

      【解决方案2】:

      这是带有 flexbox 的纯 CSS 解决方案,但过于复杂。

      .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>

      【讨论】:

        【解决方案3】:

        我认为使用纯 CSS 很难做到这一点,特别是如果您打算扩展此网格。但是它可以用 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>

        您还可以使用去抖动来减少触发mouseover 回调函数的次数。

        【讨论】:

        • 谢谢。但是在您的结果中,单元格在鼠标经过它后突出显示,而不是在鼠标经过它时突出显示。例如 - 如果您将鼠标放在从左到右的第一行,那么单元格 5 将不会是蓝色的,直到您通过它而不是悬停它。
        • 我刚刚重新检查了结果,一旦鼠标悬停,单元格似乎就会突出显示。不过,我正在检查可能导致它在另一台机器上表现不同的原因。
        猜你喜欢
        • 2015-11-03
        • 2020-08-13
        • 2020-03-29
        • 1970-01-01
        • 1970-01-01
        • 2020-03-31
        • 2013-04-08
        • 2022-12-15
        • 1970-01-01
        相关资源
        最近更新 更多