如何仅显示当前hover节点的info子元素,排除其父/祖先节点的info
解决嵌套节点hover时仅显示当前节点的info信息问题
问题背景
我知道已有大量CSS选择器相关问题,但没找到这个问题的答案,见谅。
我的HTML结构具备以下特性:
- 部分节点始终可见,支持嵌套;
- 每个这类节点都有且仅有一个“info子节点”,仅当其父节点被hover时显示(节点可能包含其他非info子节点,因支持嵌套);
- 希望仅显示当前hover节点对应的info信息。
现有代码大致可用,但存在问题:同一时间会显示多个info节点。例如hover节点D时,节点B的info也会同时显示。需要实现仅选中父节点当前处于hover状态的div.info-on-parent-hover元素,不选中其祖先、兄弟或后代节点的对应元素。
现有代码示例
HTML
<div class="always-visible"> node A [top-level node] <div class="info-on-parent-hover">some info about A</div> </div> <div class="always-visible"> node B [top-level node] <div class="info-on-parent-hover">some info about B</div> <div class="always-visible"> node C [child node of B] <div class="info-on-parent-hover">some info about C</div> </div> <div class="always-visible"> node D [child node of B] <div class="info-on-parent-hover">some info about D</div> </div> </div>
初始CSS
.always-visible { display: block; } .info-on-parent-hover { background-color: #ddd; font-weight: normal; font-style: italic; display: none; } .always-visible { font-weight: bold; background-color: #777; } .always-visible:hover { background-color: #3377cc; } .always-visible:hover>.info-on-parent-hover { display: block; }
问题原因
当鼠标hover子节点时,其父节点的:hover状态仍然有效(因为子节点处于父节点的区域范围内),所以父节点的info元素会被同时触发显示。
解决方案
方案1:利用兄弟选择器兼容旧浏览器
修改CSS,添加规则在子节点被hover时隐藏父节点的info:
.always-visible { display: block; font-weight: bold; background-color: #777; } .info-on-parent-hover { background-color: #ddd; font-weight: normal; font-style: italic; display: none; } .always-visible:hover { background-color: #3377cc; } /* 显示当前hover节点的info */ .always-visible:hover > .info-on-parent-hover { display: block; } /* 当子节点被hover时,隐藏父节点的info */ .always-visible:hover > .always-visible:hover ~ .info-on-parent-hover { display: none; }
原理:当子节点.always-visible被hover时,通过兄弟选择器~选中父节点下的.info-on-parent-hover并设置为隐藏,从而确保只有最内层被hover节点的info显示。
方案2:使用:has()伪类(现代浏览器)
如果目标浏览器支持:has()伪类(Chrome 105+、Firefox 121+等),可以用更直观的写法:
.always-visible { display: block; font-weight: bold; background-color: #777; } .info-on-parent-hover { background-color: #ddd; font-weight: normal; font-style: italic; display: none; } .always-visible:hover { background-color: #3377cc; } /* 仅当当前hover节点没有被hover的子节点时,显示自身的info */ .always-visible:not(:has(.always-visible:hover)):hover > .info-on-parent-hover { display: block; }
原理::has(.always-visible:hover)判断当前节点是否包含被hover的子节点,not()取反,只有不包含被hover子节点的hover节点,才会显示自己的info。
效果验证
- hover节点A:仅显示A的info
- hover节点B:仅显示B的info
- hover节点C/D:仅显示C/D的info,B的info自动隐藏
内容的提问来源于stack exchange,提问作者Philipp Koch
相关产品推荐
相关产品推荐

