You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CSS提示框在overflow:scroll的div中被截断隐藏的解决求助

解决滚动容器中Tooltip被裁剪/位置错位问题

问题根源

你的Tooltip出现被裁剪、触发多余滚动的核心原因:

  • Tooltip是设置了position:relative的item-container的子元素,绝对定位的参考对象是该容器
  • 父容器item-options开启了overflow:scroll,绝对定位元素会被容器的溢出规则裁剪,超出部分还会触发X轴滚动、撑开容器底部

解决方案

1. 调整HTML结构

将Tooltip从滚动容器item-options内部移出,放到item-list层级,脱离滚动容器的限制:

<div id="item-list">
  <div id="item-search">//此处为简易搜索栏</div>

  <div id="item-options">
    <div class="item-container" data-tooltip-id="tooltip-1">
      <img src="itemsImages/1001.png" class="item-images" />
    </div>
    <!-- 其他物品容器,每个对应唯一的data-tooltip-id -->
  </div>

  <!-- 所有Tooltip统一放在滚动容器外 -->
  <span class="item-tooltip" id="tooltip-1">
    <maintext>
      <stats> <attention>25</attention> Move Speed </stats>
    </maintext>
  </span>
  <!-- 其他Tooltip -->
</div>

2. 修改CSS样式

  • 移除item-container的position:relative,避免成为Tooltip的定位参考
  • 限制item-options仅开启垂直滚动,隐藏水平滚动条
  • 调整Tooltip的定位规则,确保层级足够高:
#item-list {
  position: relative; /* 让Tooltip的absolute定位参考此容器 */
}

#item-options {
  display: flex;
  justify-content: flex-start;
  align-items: center;
  height: 80%;
  flex-wrap: wrap;
  overflow-y: scroll; /* 仅开启垂直滚动 */
  overflow-x: hidden; /* 隐藏水平滚动条 */
  font-size: 0;
}

#item-options .item-container {
  width: 10%;
  aspect-ratio: 1/1;
  /* 移除position:relative */
}

.item-images {
  width: 100%;
  margin: 0;
}

.item-tooltip {
  position: absolute;
  visibility: hidden;
  width: 200px;
  background-color: #555;
  color: #fff;
  text-align: center;
  padding: 5px 0;
  border-radius: 6px;
  z-index: 999; /* 确保Tooltip在最上层 */
  opacity: 0;
  transition: opacity 500ms ease;
  font-size: 12px;
  user-select: none;
  pointer-events: none;
}

3. 添加JavaScript定位逻辑

通过监听鼠标hover和容器滚动事件,动态计算Tooltip的位置,确保跟随物品且不溢出容器:

// 用事件委托减少事件绑定数量,提升性能
const itemOptions = document.getElementById('item-options');
const itemList = document.getElementById('item-list');

// 鼠标进入物品容器时显示并定位Tooltip
itemOptions.addEventListener('mouseenter', (e) => {
  const container = e.target.closest('.item-container');
  if (!container) return;

  const tooltipId = container.dataset.tooltipId;
  const tooltip = document.getElementById(tooltipId);
  if (!tooltip) return;

  const containerRect = container.getBoundingClientRect();
  const listRect = itemList.getBoundingClientRect();

  // 计算Tooltip位置:物品下方居中
  let left = containerRect.left - listRect.left + (containerRect.width / 2) - (tooltip.offsetWidth / 2);
  let top = containerRect.top - listRect.top + containerRect.height + 10;

  // 处理左右边界溢出,确保Tooltip始终在容器内
  if (left < 10) left = 10;
  if (left + tooltip.offsetWidth > listRect.width - 10) left = listRect.width - tooltip.offsetWidth - 10;

  tooltip.style.left = `${left}px`;
  tooltip.style.top = `${top}px`;
  tooltip.style.visibility = 'visible';
  tooltip.style.opacity = '1';
});

// 鼠标离开物品容器时隐藏Tooltip
itemOptions.addEventListener('mouseleave', (e) => {
  const container = e.target.closest('.item-container');
  if (!container) return;

  const tooltipId = container.dataset.tooltipId;
  const tooltip = document.getElementById(tooltipId);
  if (!tooltip) return;

  tooltip.style.visibility = 'hidden';
  tooltip.style.opacity = '0';
});

// 滚动时更新Tooltip位置,避免错位
itemOptions.addEventListener('scroll', () => {
  const visibleTooltip = document.querySelector('.item-tooltip[style*="visibility: visible"]');
  if (!visibleTooltip) return;

  const tooltipId = visibleTooltip.id;
  const container = document.querySelector(`.item-container[data-tooltip-id="${tooltipId}"]`);
  if (!container) return;

  const containerRect = container.getBoundingClientRect();
  const listRect = itemList.getBoundingClientRect();

  let left = containerRect.left - listRect.left + (containerRect.width / 2) - (visibleTooltip.offsetWidth / 2);
  let top = containerRect.top - listRect.top + containerRect.height + 10;

  if (left < 10) left = 10;
  if (left + visibleTooltip.offsetWidth > listRect.width - 10) left = listRect.width - visibleTooltip.offsetWidth - 10;

  visibleTooltip.style.left = `${left}px`;
  visibleTooltip.style.top = `${top}px`;
});

优化说明

  • 采用事件委托减少事件绑定数量,适配大量物品的场景
  • 自动处理Tooltip的边界溢出问题,确保始终显示在容器可视范围内
  • 滚动时实时更新位置,彻底解决Tooltip错位问题
  • Tooltip脱离滚动容器后,不会触发多余滚动条或撑开容器底部

内容的提问来源于stack exchange,提问作者Gustavo Feijó

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 22:04:52