touch-action: manipulation必须显式加在点击目标元素上(如button、a、[role="button"]、自定义div等),不继承,父容器设置无效;仅解决300ms延迟,不防点击穿透;需配合viewport meta、-webkit-tap-highlight-color和:active样式。

touch-action: manipulation 必须加在点击目标元素上,不是父容器
点击穿透和300ms延迟常被混为一谈,但它们的成因不同:穿透是事件冒泡+层叠遮罩未阻断,延迟是浏览器双击判定逻辑。而 touch-action: manipulation 只解决后者,且只对它直接作用的元素生效。
常见错误是给弹层 wrapper 加了该属性,但关闭按钮是个 <div class="close">,没单独加——结果弹层能点开,但点关闭时仍卡 300ms,甚至因延迟导致快速连点穿透到下层。<ul><li>必须显式加在所有绑定 <code>onclick、@click、onClick 的元素上,包括 <div class="btn">、<code><li data-tab="home">、轮播图小圆点
<button></button> 默认已优化,但一旦你写了 display: inline-flex 或 touch-action: auto,就得手动补回 touch-action: manipulation
touch-action: none(比如某些模态框类名 .modal),子元素即使写 manipulation 也无效viewport meta 错位或缺失会让 touch-action 失效
touch-action: manipulation 不是开关,它依赖浏览器进入“非双击判定模式”。这个模式的前提是:浏览器确认页面不需要双击缩放——而这由 <meta name="viewport"> 决定。
如果 <meta> 被塞在 <title></title> 后面、CSS 之后,或漏了 width=device-width,iOS Safari 会默认启用双击检测,此时无论你怎么写 touch-action,computed 值都显示 auto。
-
<meta>必须放在最顶部,早于所有 CSS 和 JS - 必须包含
width=device-width和initial-scale=1.0;只写user-scalable=no不够 - 动态插入的
<meta>(如 SSR 后用 JS 注入)不生效,首屏渲染已完成,延迟已固化
:active 和 -webkit-tap-highlight-color 缺一不可
禁掉 300ms 延迟后,click 立刻触发,但用户看不到任何反馈——这不是 bug,是你忘了提供视觉锚点。系统默认的蓝灰高亮(-webkit-tap-highlight-color)和 :active 伪类是两套独立机制,必须同时处理。
-
-webkit-tap-highlight-color: transparent只关掉高亮,不提供新样式;写成none或unset无效 -
:active必须配合真实变化,比如opacity: 0.7、background-color: #eee;纯color变化在部分 Android 上不可见 - 带物理键盘的 iPad 或 Windows 触摸本会进
:focus,建议统一加:focus { outline: none; }
哪些地方绝对不能加 touch-action: manipulation
它不是性能开关,而是手势意图声明。加错位置会直接破坏滚动、缩放等基础交互,比延迟更难排查。
- 轮播图外层容器、地图
<div id="map">、横向滚动列表:加了就无法拖动<li>固定定位元素(<code>position: fixed)或含transform的区域:部分老 Android WebView 会忽略该声明 - 全局写
* { touch-action: manipulation; }或body { touch-action: manipulation; }:等于主动禁用整个页面的手势能力
真机验证比模拟器可靠得多;延迟消失后,务必检查滚动是否正常、双指缩放是否还能用——否则就是加错了地方。











