应使用@media (hover: none) and (pointer: coarse)判断触控主导场景,它跨浏览器兼容且反映真实输入状态;单独用(hover: hover)或(pointer: coarse)均不可靠,需结合JS监听输入变化。

在 H5 中,**不能用媒体查询直接检测“设备是否支持触摸屏 hover”**——因为触摸屏本身不支持 hover,这是物理限制。真正该问的是:当前用户是否正处于一个无法可靠悬停的交互环境(比如纯手指触控),以及是否应禁用或降级 hover 样式。
用 (hover: none) and (pointer: coarse) 组合判断触控主导场景
这是目前最稳定、跨浏览器(Safari / Chrome / Firefox)都支持的方案,它不依赖设备型号,而是反映真实输入状态:
- (hover: none) 表示主输入设备不具备悬停能力(如 iPhone、多数安卓手机、未接外设的 iPad)
- (pointer: coarse) 表示当前活跃指针是粗粒度的(典型为手指触控)
- 两者同时成立,基本可认定用户正以触控方式操作,应启用触控优化逻辑
示例 CSS:
@media (hover: none) and (pointer: coarse) {.tooltip { display: block; }
.nav-item > .submenu { display: block; }
.btn { min-height: 44px; padding: 12px 16px; }
}
别单独用 (hover: hover) 判断“是否能 hover”
这个查询检测的是设备能力,不是当前输入方式:
生成可在 deepbi 沙箱 iframe 内运行或作为独立文件运行的交互式 HTML 页面,使用 `window.deepbi` JS SDK 实现数据查询、空间管理、文件浏览及用户操作。当用户提出以下需求时启用该能力: - 创建 KPI 仪表盘、数据表格、文件浏览器、成员列表、管理页面; - 明确要求“转成 dhtml”、“转译成 HTML”、“把 XX 页面转成……”、“控制台页面”、“管理后台”、“DeepBI 页面迁移”; - 提及位于 `apps/console/src/featur
- iPadOS、ChromeOS、macOS Safari 在插着鼠标时始终报告
(hover: hover),哪怕你正用手指点屏幕 - 它会导致下拉菜单、tooltip 等 hover 触发内容对触控用户不可见——点不中、找不到
- 所以
@media (hover: hover)只适合包裹 hover 动效和 transition,而不是作为“桌面专属开关”
JavaScript 动态响应输入切换
CSS 媒体查询只在加载或窗口大小变化时重算,而用户可能中途插拔鼠标、切换笔/指操作。需 JS 协同:
- 用
window.matchMedia("(hover: none) and (pointer: coarse)")获取初始状态 - 监听
change事件,实时响应输入模式变化 - 首次
pointerdown且event.pointerType === 'touch'时,可临时强化触控逻辑(如展开菜单、显示常驻按钮) - 避免用
'ontouchstart' in window或navigator.maxTouchPoints,它们已不可靠或被废弃
为什么不用 (pointer: coarse) 单独判断?
因为 Surface、二合一笔记本等混合设备,可能同时满足 pointer: coarse 和 hover: hover:
- 仅靠
pointer: coarse就移除 hover,会在用户用鼠标操作时误伤体验 - 组合条件
(hover: none) and (pointer: coarse)才真正逼近“此刻只能触控”的事实 - 它排除了带触控屏但主输入仍是鼠标的场景,也规避了 Android 浏览器误报 hover 的问题










