【问题标题】:Hover on mouse-over, un-hover on mouse-out of parent鼠标悬停在鼠标悬停上,鼠标悬停在父级上悬停
【发布时间】:2017-04-20 03:40:01
【问题描述】:

在下面的简单示例中,我想让纯蓝色 div 在鼠标悬停时增长,但只要光标在橙色框内,就保持这种状态。

一旦光标离开橙色框,实心蓝色框应折叠。橙色框代表列表中的一行。

真正的实现是在充满其他细节的复杂行上的类似工具提示的滑出。

.row {
  border: 1px solid orange;
  display: block;
  height: 20%;
  padding: 20px;
  width: 400px;
}

.row div {
  border: 1px dashed blue;
  display: inline-block;
  text-align: center;
  padding: 20px;
  width: 100px;
}

.row .right {
  background: blue;
  padding: 20px 0;
  transition: width 0.5s ease;
  width: 10px;
}

.row .right:hover {
  width: 100px;
}
<div class="row">
  <div class="left"></div>
  <div class="middle"></div>
  <div class="right"></div>
</div>

当然,这可以通过 JavaScript 轻松完成(目前是这样实现的):

let right = $('.right');

right.mouseenter(() => right.addClass('hover'))

$('.row').mouseleave(() => right.removeClass('hover'))
.row {
  border: 1px solid orange;
  display: block;
  height: 20%;
  padding: 20px;
  width: 400px;
}

.row div {
  border: 1px dashed blue;
  display: inline-block;
  text-align: center;
  padding: 20px;
  width: 100px;
}

.row .right {
  background: blue;
  padding: 20px 0;
  transition: width 0.5s ease;
  width: 10px;
}

.row .right.hover {
  width: 100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="row">
  <div class="left"></div>
  <div class="middle"></div>
  <div class="right"></div>
</div>

但如果可能的话,出于代码可读性、性能和可维护性的原因,我希望使用纯 CSS 方法。

如果事实上不可能,我会接受它作为答案。

当前的实现是在一个 Angular4 模板中,所以我们需要在模板中添加像 (mouseleave)="tooltipElement &amp;&amp; hideTooltip($event.target.children) 这样的指令,这对我来说似乎是不必要的。

【问题讨论】:

    标签: css css-selectors


    【解决方案1】:

    这是一种使用小技巧来模拟保持悬停状态的方法。它不会永远保留它,而是在您定义为动画延迟的持续时间内保留。在大多数情况下,大概 10 分钟的悬停就像永远一样,如果你想让它持续更长时间,你只需要增加下面代码中的数字。

    .row {
      border: 1px solid orange;
      display: block;
      height: 20%;
      padding: 20px;
      width: 400px;
    }
    
    .row div {
      border: 1px dashed blue;
      display: inline-block;
      text-align: center;
      padding: 20px;
      width: 100px;
    }
    
    .row .right {
      background: blue;
      padding: 20px 0;
      transition: width 0.5s ease 600s;
      width: 10px; /* Unfortunately, this has to be 'different' from ... */
    }
    
    .row .right:hover {
      width: 100px;
      transition: 0.5s;
    }
    
    .row:not(:hover) .right {
      width: 10.01px; /* ... this width. See http://stackoverflow.com/q/43393653 */
      transition: 0.5s ease;
    }
    <div class="row">
      <div class="left"></div>
      <div class="middle"></div>
      <div class="right"></div>
    </div>

    【讨论】:

    • 哦,我去看看。刚刚在 Firefox 中对其进行了测试,它显示了预期的行为。
    • 我找到了导致它在 Chrome 中失败的行。我会尽快更新我的答案,使其适用于所有浏览器。
    • 这个技术很有趣。然而,这是一个技巧,但我赞成一个非常有创意的解决方案。正如我在回答中所说,检测某些条件是不可能的纯 CSS,但大脑可以做任何事情!
    • @MarcosPérezGude 谢谢。一开始我也认为这是不可能的,但我很少对这样的答案感到满意:P msanford:它现在应该可以在 FF 和 Chrome 中使用。我不确定后面有 cmets 的部分,也许我能够找出这种行为的原因(并且可能找到一种比使用双精度值更“干净”的方法来解决这个问题)。当我将来再次回到这个问题时,我会在你的问题下发表评论(不确定你是否收到有关编辑的通知)。
    • 我不明白为什么它需要10.01px,或者你说的不同的值。你能解释一下吗?
    【解决方案2】:

    使用纯 CSS,您无法完全按照您的描述进行操作。您可以在悬停行时使蓝色边框增大,但在悬停蓝色元素时不会增大,并在悬停在行上时保留。

    因此您可以将行悬停并应用于正确的元素,如果它符合您的要求,将如下所示:

    .row {
      border: 1px solid orange;
      display: block;
      height: 20%;
      padding: 20px;
      width: 400px;
    }
    
    .row div {
      border: 1px dashed blue;
      display: inline-block;
      text-align: center;
      padding: 20px;
      width: 100px;
    }
    
    .row .right {
      background: blue;
      padding: 20px 0;
      transition: width 0.5s ease;
      width: 10px;
    }
    
    .row:hover  .right{
      width: 100px;
    }
    <div class="row">
      <div class="left"></div>
      <div class="middle"></div>
      <div class="right"></div>
    </div>

    【讨论】:

    • 感谢马科斯。我编辑了我的问题以提供有关该问题的更多详细信息。
    • 好的,我认为您将获得的唯一方法是@Marvin 答案。这是一个创造性技术的好答案,所以我建议你抓住它,不要浪费更多时间:D
    【解决方案3】:

    我只是想在上面的评论中嵌入@Shaggy 提出的the single-listener solution,因为在那些有事件监听器的情况下实际上可能没问题。

    {
        let current=0;
        document.getElementById("group").addEventListener("mouseover",event=>{
            let target=event.target;
            if(target.classList.contains("right"))
                (current=target).classList.add("hover");
            else if(target===event.currentTarget&&current){
                current.classList.remove("hover");
                current=0;
            }
        },0)
    }
    body{
      margin:0;
      padding:20px;
    }
    #group{
      border:1px solid #999;
      display:inline-block;
      padding:20px 20px 0;
    }
    .row{
      border:1px solid #f90;
      display:block;
      height:20%;
      margin:0 0 20px;
      padding:20px;
      width:400px;
    }
    .row>div{
      border:1px dashed #00f;
      display:inline-block;
      padding:20px;
      width:100px;
    }
    .row>.right{
      background:#00f;
      padding:20px 0;
      transition:width .5s ease;
      width:10px;
    }
    .row>.right.hover{
      width:100px;
    }
    <div id="group">
    <div class="row">
      <div class="left"></div>
      <div class="middle"></div>
      <div class="right"></div>
    </div>
    <div class="row">
      <div class="left"></div>
      <div class="middle"></div>
      <div class="right"></div>
    </div>
    <div class="row">
      <div class="left"></div>
      <div class="middle"></div>
      <div class="right"></div>
    </div>
    </div>

    【讨论】:

      猜你喜欢
      • 2011-08-04
      • 2018-09-03
      • 2015-04-22
      • 2011-05-26
      • 2017-10-14
      • 1970-01-01
      • 1970-01-01
      • 2011-07-07
      • 1970-01-01
      相关资源
      最近更新 更多