如何仅为直接hover的.h-me元素添加悬浮样式?
问题描述
我有多个嵌套的带有.h-me类的元素,结构示例如下:
<span class="h-me"> <span class="h-me"> <span class="h-me"> x </span> <span class="h-me"> y </span> </span> </span>
当前使用的CSS代码:
.h-me:hover { background: rgba(0, 0, 0, 0.1); }
当鼠标悬浮在内容为"x"的span上时,所有包含它的父级.h-me元素背景都会变色——因为技术上鼠标同时处于所有父元素的hover范围内。我需要实现仅让直接被悬浮的元素背景变化,同时满足两个限制:
- 完全不能修改HTML结构,只能用CSS或JavaScript实现;
- HTML内容会频繁更新,方案需适配动态生成的元素。
典型的实际应用结构(KaTeX生成的公式代码):
<span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height: 1em; vertical-align: -0.25em;"></span><span style="margin-right: 0.1076em;" class="h-me mathnormal">f</span><span class="mopen">(</span><span class="h-me mathnormal">x</span><span class="mclose">)</span><span class="mspace" style="margin-right: 0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right: 0.2778em;"></span></span><span class="base"><span class="strut" style="height: 2.3846em; vertical-align: -0.9703em;"></span><span class="mop"><span style="margin-right: 0.4445em; position: relative; top: -0.0011em;" class="mop op-symbol large-op">∫</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height: 1.4143em;"><span class="" style="top: -1.7881em; margin-left: -0.4445em; margin-right: 0.05em;"><span class="pstrut" style="height: 2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="h-me mtight"><span class="h-me mtight">−</span><span class="h-me mtight">∞</span></span></span></span><span class="" style="top: -3.8129em; margin-right: 0.05em;"><span class="pstrut" style="height: 2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="h-me mtight">∞</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height: 0.9703em;"><span class=""></span></span></span></span></span></span><span class="mspace" style="margin-right: 0.1667em;"></span><span class="h-me accent"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height: 0.9579em;"><span class="" style="top: -3em;"><span class="pstrut" style="height: 3em;"></span><span style="margin-right: 0.1076em;" class="h-me mathnormal">f</span></span><span class="" style="top: -3.2634em;"><span class="pstrut" style="height: 3em;"></span><span class="accent-body" style="left: -0.0833em;"><span class="h-me">^</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height: 0.1944em;"><span class=""></span></span></span></span></span><span class="mopen">(</span><span style="margin-right: 0.046em;" class="h-me mathnormal">ξ</span><span class="mclose">)</span><span class="mspace" style="margin-right: 0.1667em;"></span><span class="h-me"><span class="h-me mathnormal">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height: 0.8991em;"><span class="" style="top: -3.113em; margin-right: 0.05em;"><span class="pstrut" style="height: 2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="h-me mtight"><span class="h-me mtight">2</span><span class="h-me mathnormal mtight">πi</span><span style="margin-right: 0.046em;" class="h-me mathnormal mtight">ξ</span><span class="h-me mathnormal mtight">x</span></span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right: 0.1667em;"></span><span class="h-me mathnormal">d</span><span style="margin-right: 0.046em;" class="h-me mathnormal">ξ</span></span></span>
解决方案
方案1:纯CSS(仅支持现代浏览器)
利用:has()伪类反向控制父元素的hover样式,实现仅当前元素变色:
/* 默认hover样式 */ .h-me:hover { background: rgba(0, 0, 0, 0.1); } /* 当父级.h-me包含被hover的子级时,取消父级的hover背景 */ .h-me:has(.h-me:hover) { background: transparent; }
注意::has()伪类目前支持Chrome、Edge、Safari;Firefox需在about:config中开启layout.css.has-selector.enabled才能使用。
方案2:JavaScript(兼容性好,适配动态元素)
通过事件委托监听鼠标事件,精准控制当前hover元素的背景,同时适配动态更新的HTML:
let lastHovered = null; // 监听鼠标移入事件 document.addEventListener('mouseover', function(e) { const target = e.target.closest('.h-me'); if (!target) return; // 清除上一个hover元素的背景 if (lastHovered) { lastHovered.style.background = 'transparent'; } // 给当前hover元素设置背景 target.style.background = 'rgba(0, 0, 0, 0.1)'; lastHovered = target; }); // 监听鼠标移出事件 document.addEventListener('mouseout', function(e) { const target = e.target.closest('.h-me'); if (!target || target !== lastHovered) return; target.style.background = 'transparent'; lastHovered = null; });
这个方案的优势是全浏览器兼容,且事件委托机制会自动适配动态生成的.h-me元素,无需重新绑定事件。
内容的提问来源于stack exchange,提问作者Real Noob
相关产品推荐
相关产品推荐

