【问题标题】:Simulate mouseenter with pure css用纯 css 模拟 mouseenter
【发布时间】:2022-02-11 23:08:41
【问题描述】:

当我将鼠标悬停在元素上方时,我需要为其设置样式。但是,我不想为其父 DOM 元素设置样式。但是,当我使用:hover 时,有问题的元素的样式就像我想要的那样,但不幸的是,它的所有父元素也都被样式化了

*:hover {
    border-color: red;
}

DEMO

main,
article,
div {
  border: 1px solid lightgrey;
  padding: 30px;
}

*:hover {
  border-color: red;
}
<main>
  <article>
    <div>

    </div>
  </article>
</main>

只有当光标在外边框和中间边框之间时,外边框才会是红色的。仅当光标位于中间边框和内边框之间时,中间顺​​序才应为红色。仅当光标位于内边框内时,内边框才会为红色。

有没有办法只设置被悬停的 DOM 元素的样式(可以是任何元素)?还是我只能用 javascript 来实现这个目标?

【问题讨论】:

  • 您的演示与您的示例不匹配,因此我在此处添加了它 - 您确实意识到它完全按照您的指定执行了吗?你告诉父母也要在悬停时设置样式。请指定您希望设置哪些子元素的样式。
  • 您尝试重新创建的 JavaScript 代码是什么?
  • 你想让它应用于所有元素,但不影响父元素吗?因为这里已经有所涉及:CSS hover on a div, but not if hover on his children(尽管根据您的用例,最佳答案的用处有限)
  • 我添加了以下语句:“只有光标在外边框和中间边框之间时,外边框才为红色。只有光标在中间时,中间顺​​序才为红色边框和内边框。只有当光标位于内边框内时,内边框才会为红色。"

标签: javascript html css


【解决方案1】:

今天你无法用纯 CSS 避免父 :hover。 SO上有很多话题讨论这个:

How to apply child:hover but not parent:hover

Safari 引入了对 :has 父选择器的支持,如果其他浏览器也支持它,可能会解决这个问题。但今天它仍然不是一个可行的选择。

您问是否可以使用 javascript 实现此目的,是的,您可以使用 mouseentermouseleave 事件在 javascript 中破解解决方案,切换 CSS 类。

https://jsfiddle.net/sq1kcwdt/4/

【讨论】:

  • 解决方案很棒……但是纯 CSS 部分呢?
  • @カメロン 不能这样做,正如在其他 SO 问题上已经广泛讨论的那样。 OP问“或者我只能用javascript实现这个目标吗?”这就是我想要提供帮助的地方。如果最初的目标是不可能的,展示替代方案会很有用,不是吗?
  • Zoltan 已经证明可以使用纯 CSS 来完成,请参阅他的回答。
  • @www.admiraalit.nl 他的替代方案很有趣,但对我不起作用(当我将鼠标悬停在中心元素上时,顶级元素仍然有红色边框)。覆盖第二个绝对定位边框类似于其他具有绝对定位 div 的 HTML 方法。值得将其视为 hack,但绝不是避免父元素 :hover 的纯 CSS“解决方案”。
【解决方案2】:

实际上,使用::before::after 可以使用一些技巧。您可以使用这些伪元素来掩盖您想要的边框。使用指针事件很重要:无;在这些元素上,所以它们不会打扰任何东西,它们只是用来装饰的。

不过,我的看法是 javascript 在这个用例中更有效。

您可以查看以下快速解决方案: https://codepen.io/serazoltan/pen/WNXOREq

它需要大量更新以供一般使用,但我这样做只是为了表明它是可能的。

:root {
  --general-padding: 30px;
  --general-padding-neg: -33px;
}

main,
article,
div {
  border: 1px solid lightgrey;
  padding: var(--general-padding);
  position: relative;
  transition: all .3s;
}

main {
  height: 400px;
  z-index: 0;
}

article {
  height: 200px;
  z-index: 10;
}

div {
  height: 80px;
  z-index: 20;
}

main:hover {
  border-color: red;
}

article:hover {
  border-color: red;
}

article:hover::after {
  content: "";
  position: absolute;
  top: var(--general-padding-neg);
  left: var(--general-padding-neg);
  width: calc(100% + var(--general-padding)*2 + 4px);
  height: 460px;
  border: 1px solid lightgrey;
  pointer-events: none;
}

div:hover {
  border: 1px solid red;
  z-index: 20;
}

div:hover::after {
  content: "";
  position: absolute;
  top: var(--general-padding-neg);
  left: var(--general-padding-neg);
  width: calc(100% + var(--general-padding)*2 + 4px);
  height: 260px;
  border: 1px solid lightgrey;
  pointer-events: none;
}

【讨论】:

    【解决方案3】:

    main,
    article,
    div {
      border: 1px solid lightgrey;
      padding: 30px;
    }
    
    div:hover {
      border-color: red;
    }
    <main>
      <article>
        <div id='myDiv'>
    
        </div>
      </article>
    </main>

    【讨论】:

    • 我的代码只是一个例子,我想我并不清楚。所以,它应该适用于任何元素,而不仅仅是那个 div
    【解决方案4】:

    更新您的 CSS (demo):

    div:hover {
        border-color: red;
    }
    

    或者,将类添加到您想要共享通用样式的元素 (demo)。

    <main>
      <article>
        <div class="highlight-on-hover">
    
        </div>
        <div>
    
        </div>
        <div class="highlight-on-hover">
    
        </div>
      </article>
    </main>
    
    .highlight-on-hover:hover {
        border-color: red;
    }
    

    【讨论】:

    • 很抱歉给您带来了困惑。我不应该只为那个 div 工作(这只是一个例子)。但它应该适用于任何元素
    • @JeanlucaScaljeri 是的,您可以向元素添加一个类,然后将应用相关的样式。我已经更新了答案以反映这一点。
    【解决方案5】:

    只是通过模棱两可的问题示例进行猜测。你也可以说什么不适合风格。你用*:hover 说“全部”,所以它做到了。

    main,
    article,
    div {
      border: 1px solid lightgrey;
      padding: 30px;
    }
    
    *:hover:not(.not-me) {
      border-color: red;
    }
    
    main:hover:not(.not-me) {
      border-color: green;
    }
    
    article:hover:not(.not-me) {
      border-color: blue;
    }
    
    main>article>div:hover:not(.not-me) {
      border-color: inherit;
      border-color: orange;
      background-color: #ffdddd;
    }
    
    main.not-me:hover:not(*),
    main.not-me *.not-me *:hover:not(*) {}
    <main>
      <article>
        <div>
    
        </div>
        <div class="not-me">
          not me
        </div>
      </article>
      <article class="not-me">
        <div>
          not me either, I am inside not-me
        </div>
        <div class="not-me">
          not me
        </div>
      </article>
    </main>
    <main class="not-me">
      nothing in here
      <article class="not-me">
        <div>
          ME I want in also!
        </div>
        <div>
          ME!
        </div>
      </article>
      <article class="not-me">
        <div>
          Me ME! I am inside not-me
        </div>
        <div class="not-me">
          not me
        </div>
      </article>
    </main>

    【讨论】:

      【解决方案6】:

      目前您正在使用 *-selector 将 :hover 应用于页面上的所有元素,您可以在此处阅读更多相关信息:https://developer.mozilla.org/en-US/docs/Web/CSS/Universal_selectors

      通过选择 div 使其更具体:

      div:hover {
        /* your rules here */
      }
      

      【讨论】:

        【解决方案7】:

        您可以简单地使用以下代码:

        $("main, article, div").hover(function () {
              $(this).parent().css('border-color', 'lightgrey');
        }, function () {
              $(this).parent().css('border-color', '');
        });
        

        【讨论】:

        • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-02-18
        • 1970-01-01
        • 2019-02-19
        • 1970-01-01
        相关资源
        最近更新 更多