-webkit-touch-callout: none 仅对含 tel:/mailto:/sms: 等 scheme 的链接生效,控制是否弹出原生调用菜单;禁用长按文本菜单需配合 user-select: none 并确保元素有 layout。

为什么 -webkit-touch-callout: none 单独写没用
它只在 iOS Safari 和部分 Webview 中生效,且必须和 user-select: none 配合使用——单独设 -webkit-touch-callout: none 无法阻止长按后弹出“复制”“搜索”等系统菜单,因为该属性仅控制「是否唤起通话/邮件等原生调用菜单」,对文本选中类菜单无效。
-webkit-touch-callout 的真实作用范围
这个属性只影响带 tel:、mailto:、sms: 等 scheme 的链接。比如:@#@#@#@#@#@#@#@#@#@0,长按时是否弹出「拨打」按钮。它对纯文本、普通按钮、div 内容完全无感。
- ✅ 生效场景:含
tel:/mailto:的<a></a>标签 - ❌ 无效场景:普通段落、
<span></span>、<div>、<code><button></button>、无 scheme 的链接 - ⚠️ 注意:即使写了,iOS 15.4+ 仍可能因元素未触发可点击状态(如缺少
cursor: pointer或tabindex)而忽略该声明 - 给目标元素加
-webkit-user-select: none+user-select: none,并确保它有 layout(比如min-height: 1em或display: inline-block) - 移除可能干扰的样式,例如
pointer-events: none(它会让user-select失效) - 如果元素内是纯文本,样式必须落在直接包裹文本的标签上(如
<p class="no-select">文字</p>),不能只写在父容器
真正要禁掉长按菜单,得靠这三步组合拳
单靠 -webkit-touch-callout 是个常见误解。实际要拦住“复制”“搜索”“翻译”这类菜单,核心是让系统认为「这里没有可选内容」:
兜底方案:JS 拦截 selectstart 事件
当 CSS 层面因 Webview 版本或嵌套结构失效时,可用 JS 补救,但注意它只防高亮,不防菜单弹出:
element.addEventListener('selectstart', e => e.preventDefault());
⚠️ 别用 touchstart + preventDefault(),那会同时禁掉滚动;也别对 <input> 或 <textarea></textarea> 做这事——用户需要选中编辑内容。
最常被忽略的点是:那个你要禁选的元素,在 iOS 里是不是「被识别为文本可交互区域」。有时候删掉 tabindex="-1" 或加上 outline: 0,反而就生效了。











