如何实现仅悬停人物图片区域显示气泡且可点击气泡内链接
解决方案
核心思路
- 用独立的裁剪区域做hover触发源,避免clip-path裁剪到气泡
- 单独控制气泡的交互事件权限,保证链接可点击同时不异常触发隐藏
方案1:纯CSS实现(兼容Chrome 105+、Firefox 121+、Safari 15.4+)
修改后的CSS代码:
* { margin: 0; padding: 0; } .content { width: 100vw; height: 100vh; display: flex; justify-content: center; align-items: center; background-color: #c5f5f0; } .janes-face { position: relative; background: transparent url(https://sodyot.com/wp-content/uploads/2021/07/portrait-jane.png) no-repeat center center; background-size: 100%; width: 350px; height: 335px; margin-top: 70px; /* 关闭容器默认交互,仅留裁剪后的触发区接收事件 */ pointer-events: none; } /* 新增裁剪后的hover触发区 */ .janes-face::before { content: ''; position: absolute; width: 100%; height: 100%; /* 按卡通人物轮廓调整clip-path参数,可使用在线工具生成对应形状 */ clip-path: polygon(30% 0%, 70% 0%, 90% 20%, 100% 50%, 90% 80%, 70% 100%, 30% 100%, 10% 80%, 0% 50%, 10% 20%); pointer-events: auto; } .janes-face:hover { cursor: pointer; } .janes-line { position: absolute; background: transparent url(https://sodyot.com/wp-content/uploads/2021/07/speech-bubble-round-r-e1627134718615.png) no-repeat top center; font-family: 'Kalam', cursive; left: -90%; margin-top: -23%; padding: 23% 34% 24% 26%; color: #0e324c; font-size: 18pt; font-weight: lighter; line-height: 1.2em; text-align: center; white-space: nowrap; opacity: 0; transition: opacity .3s ease-in-out; /* 气泡自身可接收交互事件 */ pointer-events: auto; } .janes-line a { color: #fff; text-decoration: none; cursor: help; display: inline-block; background-color: #f9745a; padding: 0 5px; } /* 触发显示条件:要么hover触发区,要么hover气泡本身 */ .janes-face:hover .janes-line, .janes-face:has(.janes-line:hover) .janes-line { opacity: 1; }
说明:
- 可根据卡通实际轮廓调整
clip-path的参数,7个不同元素分别设置对应裁剪参数即可 - 不需要修改原有HTML结构
方案2:JS兼容实现(支持全浏览器)
如果需要兼容旧版本浏览器,添加少量JS即可实现,代码如下:
// 批量绑定所有卡通元素事件,7个元素可统一批量处理 document.querySelectorAll('.janes-face').forEach(face => { const bubble = face.querySelector('.janes-line') // 进入卡通区域显示气泡 face.addEventListener('mouseenter', () => bubble.style.opacity = '1') // 离开时判断是否还在气泡内 face.addEventListener('mouseleave', (e) => { const toElement = e.toElement || e.relatedTarget if (!bubble.contains(toElement)) { bubble.style.opacity = '0' } }) // 离开气泡时隐藏 bubble.addEventListener('mouseleave', () => bubble.style.opacity = '0') })
使用该方案时CSS不需要加:has相关的规则,也可以保留clip-path实现精准区域触发。
内容的提问来源于stack exchange,提问作者Ean
相关产品推荐
相关产品推荐

