CSS - 为啥不:悬停父隐藏子元素

Posted

技术标签:

【中文标题】CSS - 为啥不:悬停父隐藏子元素【英文标题】:CSS - why doesn't :hover parent hide child elementsCSS - 为什么不:悬停父隐藏子元素 【发布时间】:2011-10-29 17:06:31 【问题描述】:

我有一个带有图像的导航栏,如下所示:

<ul>
  <li class="me">
    <span class="cont"><img src="dummy.png" /></span>
  </li>
  <li class="me">
    <span class="cont"><img src="dummy.png" /></span>
  </li>
</ul>

在将鼠标悬停在列表项上时,我想更改背景颜色以覆盖跨度和图像,如下所示:

.me background-color: none;
.me:hover background-color: rgba(150,150,150,0.5);

问题是,图像没有被覆盖...这是因为背景实际上是...子元素所在的“背景”吗?如果是这样,我怎么能用纯 CSS 实现这种效果?

编辑 - 解决方案

这适用于我原来的 html 结构:

<ul>
  <li>
   <a href="" class="ui-btn">
     <span class="ui-btn-inner"> /* CONTAINS IMAGE AS BACKGROUND */
        <span class="ui-btn-text">text</span>  /* GETS BACKGROUND */
        <span class="ui-icon"></span>
     </span>
   </a>
 </li>
</ul>

“负逻辑”:如果我将背景分配给列表项,它位于所有子元素的后面,所以我想我需要将背景分配给一个元素,该元素是包含 img 的元素的子元素才能让它出现高于所有项目。 span ui-btn-inner 包含图像,因此在 span ui-btn-text 上设置 :hover 背景会使其显示在图像上方...很奇怪,但可以。

【问题讨论】:

是背景在子元素后面 应该是&lt;img src="dummy.png" alt="Picture of a dummy."&gt; @WTP: 正确,缩短太多... :-) @tw16:我无法隐藏图像,因为悬停应该只是在列表项上添加阴影 【参考方案1】:

是的,背景只是一个背景,位于任何子元素的后面。

要实现您要查找的内容,请尝试使用 css :after 伪元素来掩盖悬停时的图像:

.me 
    position: relative;  


.me:hover:after 
    content: "";
    position: absolute;
    top: 0; left: 0;
    width: 100%; height: 100%;
    background: rgba(150,150,150,0.5);

它很闪亮,您可以将图像用作语义图像,并且不需要额外的 HTML 标记。

【讨论】:

me:hover 应该只在 li 上方添加一个阴影(rgba,alpha 0.5),跨度应该是可见的。我正在考虑使用 :before 或 :after 做一些事情并在悬停时显示。这行得通吗? @frequent - 绝对。 :after 只是创建另一个元素,您可以随意操作和定位。在不了解您的具体用例的情况下,您可能只需要调整大小和位置。 @derekdermann - 我让它工作,除了 IE7(不支持)。由于该元素不再可单击该按钮:在我尝试其他方法之前。 :before 和 :after 还是不错的,因为你可以用 :before 指定 IE7 看不到的东西,用 ::before 指定 IE8 看不到的东西。需要在某个地方尝试一下。【参考方案2】:

是的,因为背景实际上就是背景。在原始 css 中实现这一点的最佳方法是继续使用背景:

.me

    background-color: none;
    background-image: url(dummy.png);
    background-repeat: no-repeat;

.me:hover

    background-color: rgba(150,150,150,0.5);
    background-image: ;

你也可以用一点 javascript 来实现这个效果。

<ul>
  <li class="me">
    <span class="cont"><img="dummy.png" onmouseover='this.src="sometransparent.gif";' onmouseout='this.src="dummy.png";'></span>
  </li>
  <li class="me">
    <span class="cont"><img="dummy.png"" onmouseover='this.src="sometransparent.gif";' onmouseout='this.src="dummy.png";></span>
  </li>
</ul>

代码未经测试。它可能需要调整才能使其恰到好处。

编辑:分层概念 这些伪代码都不是测试的,但我以前做过,所以可能只需要稍微调整一下。我手头没有原件的副本,所以我必须把它转过来。第一步是创建一个相对容器和2个子容器。

.meContainer

    position: relative;
    width: 100px;
    height: 30px;   /* I usually specify height/width for these things */


.meContainerLink

    position: absolute;
    top: 0;
    left: 0;        /* You need to use position to get them to overlap */
    z-index: 1;     /* Provide a layer */


.meContainerAlpha

    position: absolute;
    top: -30px;     /* Move it UP 30px */
    left: 0px;
    z-index: 2;     /* Place it on top of the other layer */
    display: none;  /* Hide it */
    background-color: rgba(150,150,150,0.5);   


.meContainerAlpha:hover

    display: inline; /* Show it */

然后您需要将这些放在您的&lt;li&gt; 中的 div 中。

<ul>
  <li class="me">
    <div class="meContainer">
        <div class="meContainerLink">
            <img="dummy.png">
        </div>
        <div class="meContainerAlpha">
            &nbsp;
        </div>
    </div>
  </li>
  <li class="me">
    <div class="meContainer">
        <div class="meContainerLink">
            <img="dummy.png">
        </div>
        <div class="meContainerAlpha">
            &nbsp;
        </div>
    </div>
  </li>
</ul>

我不记得曾经在嵌入的&lt;li&gt; 标签中尝试过这种方法,所以一开始它的行为可能很奇怪。您可能不得不放弃&lt;li&gt; 并完全切换到不同的&lt;div&gt; 结构。

【讨论】:

同上。我需要保持图像可见,并且只在列表项顶部添加 rgba(150,150,150,0.5) 的阴影。 @frequent:最好在 png 本身中创建 2 个具有指定 alpha 设置的图像,然后使用 css 交换它们。这至少会以跨浏览器兼容的方法产生预期的结果。我能想到的唯一其他方法将涉及分层,但要编写这么简单的代码,需要大量的 html 和 css。 @Joel Etherthon:谢谢,但我也已经在悬停时交换了 img。整个事情非常复杂(我刚刚发布了一个基本示例),那么分层是什么意思?另外 - 这样的设置是否有效:我在 li:before 和 display:hidden 添加另一个元素,使其尺寸与 li 相同,添加透明层并仅在悬停时显示此项目?问题是,如果 :before 弄乱了列表结构,ala li, li, before, li... 现在试试这个 @frequent:我对 :before 和 :after 没有足够的经验可以说。到目前为止,我读过并尝试过的所有内容都表明它不是正确的解决方案,因为它只会使父子关系变得愚蠢(特别是在浏览器兼容性方面)。我将发布一个编辑来描述分层概念。 酷。尝试 :after/;before 和您的建议。可能需要一段时间,但我会告诉你结果如何【参考方案3】:

另一个应该比 :after 更跨浏览器的潜在选项可能是:

.me:hover span  display: hidden; 

【讨论】:

以上是关于CSS - 为啥不:悬停父隐藏子元素的主要内容,如果未能解决你的问题,请参考以下文章

如何将鼠标悬停在子元素上而不悬停在 CSS 中的父元素上?

根据悬停的子元素设置不同的父元素样式 | CSS

如何在父元素和子元素上设置 CSS 悬停效果

CSS减轻父鼠标悬停的子元素

将父元素悬停到子标签元素后如何更改相同的css样式?

jQuery悬停隐藏在子元素上