#13919·vant

[Bug Report] Tabs开启sticky后,在iOS/iPadOS 27上切换tab,触发内核bug,导致页面元素无法响应点击

Author: tonliverCreated Sep 11, 2026Updated Sep 11, 2026
Labelsbug: need confirm

重现链接

https://github.com/tonliver/vant-tabs-bug

Vant 版本

4.10.2

描述一下你遇到的问题。

在iOS或iPadOS的safari浏览器,使用Tabs组件,开启sticky,滑动至第一个tab页面底部,切换到第二个tab,页面的根节点window/document.documentElememtscrollTop会变成负值(负值=第一个tab的滚动值),这时页面上所有的布局/鼠标事件坐标都会向下偏移这个scrollTop的绝对值,表现出来就是所有元素都无法响应点击/触摸事件。

关键代码

当有滚动时,rect.top是一个负值

https://github.com/youzan/vant/blob/main/packages/vant/src/utils/dom.ts#L43

typescript
// get distance from element top to page top or scroller top
export function getElementTop(el: ScrollElement, scroller?: ScrollElement) {
  if (el === window) {
    return 0;
  }

  const scrollTop = scroller ? getScrollTop(scroller) : getRootScrollTop();
  return useRect(el).top + scrollTop;
}

对root element的scrollTop设置负值

https://github.com/youzan/vant/blob/main/packages/vant/src/tabs/Tabs.tsx#L259

typescript
// scroll to correct position
if (stickyFixed && !props.scrollspy) {
  setRootScrollTop(
    Math.ceil(getElementTop(root.value!) - offsetTopPx.value),
  );
}

问题分析

在iOS 27之前,无论如何给根节点scrollTop设置负值,浏览器内核最终都会自动处理为0。在iOS 27上,正常情况下也能处理成0,但在页面滚动高度发生变化时,而且必须是滚动到页面底部,个人猜测是触发惯性回弹过程中,负值就会保留下来,随后导致整个布局层坐标偏移(但渲染层正常),虽然是触发了内核的bug,但给根节点传入负的scrollTop也是不应该出现的情况,而且触发bug后,所有元素处于无法交互的状态,影响比较严重,可以在setRootScrollTop内处理一下值的合法性。

UserAgent

User Agent: Mozilla/5.0 (iPad; CPU OS 18_7 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/27.0 Mobile/15E148 Safari/604.1

复现视频

https://github.com/user-attachments/assets/9ca5e257-5d51-4c31-984f-b295d198e393

重现步骤

  1. 进入页卡1,将页面滑至最底部
  2. 点击页卡2

设备/浏览器

iOS 27的iphone/ipad上的safari/webview可稳定复现