你正在调试一个带tooltip的下拉菜单,在桌面端一切完美。等你把Surface从键盘上摘下来,切换到平板模式用触控操作——完蛋,所有菜单都点不动。不是bug,是规范行为,但就是这么让人跳脚。 问题的根源在于,像Surface、iPad Pro、Chromebook这类混合型设备,会同时报告hove
你正在调试一个带tooltip的下拉菜单,在桌面端一切完美。等你把Surface从键盘上摘下来,切换到平板模式用触控操作——完蛋,所有菜单都点不动。不是bug,是规范行为,但就是这么让人跳脚。
问题的根源在于,像Surface、iPad Pro、Chromebook这类混合型设备,会同时报告hover和any-hover为true。CSS媒体查询一看:“哦,支持悬停”,就把针对触摸屏的tooltip、常驻按钮全都隐藏了。用户拿手指戳了半天,就是找不到入口。你这边代码检查,发现@media (hover: hover)在iPad上返回true?它不骗你,但它在骗你自己。
长期稳定更新的攒劲资源: >>>点此立即查看<<<
@media (hover: hover)在iPad或Chromebook上返回true?CSS规范写得明白:只要设备有能力悬停——哪怕只是偶尔接个蓝牙鼠标——就必须返回hover: hover。iOS 13.4+、iPadOS、ChromeOS都严格遵循这条规则。换言之,它检查的是设备能力,不是当前输入方式。
(hover: hover)里藏着的是“我能”,而不是“我正在”(any-hover: hover)也一样不可靠,它只告诉你“存在某种设备可以悬停”,不关心你此刻是不是正用手指戳屏幕(hover: none) and (pointer: coarse)的组合。它翻译乘人话就是:这一刻,你只能摸@media (hover: none) and (pointer: coarse)替代单一hover判断这是目前最稳的方案。Safari、Chrome、Firefox都支持,没有悬念。它能精准捕获“不能悬停 + 粗粒度指针(也就是手指)”的场景。
(hover: hover)做“仅桌面显示”的判断——Surface平板合上键盘、触控模式时,它还是true,坑你没商量代码示例:
@media (hover: none) and (pointer: coarse) {
.tooltip { display: block; } /* 触控设备默认显示提示 */
.na v-dropdown { display: block; } /* 展开一级菜单,取消 hover 触发 */
}
pointerdown + matchMedia动态降级纯CSS有一个致命短板:它无法响应“用户从鼠标切到手指”这瞬间。需要JS出马。关键不是监听touchstart(iOS上这个事件有延迟),而是用pointerdown + matchMedia一起干活。
window.matchMedia('(hover: none)').matches的变化,效率比轮询高得多pointerdown且event.pointerType === 'touch'时,马上打标签:当前是触控模式ontouchstart全局事件检测,现代iOS已经把它禁掉了逻辑示例:
const hoverQuery = window.matchMedia('(hover: none)');
let isTouchMode = hoverQuery.matches;
hoverQuery.addEventListener('change', e => {
isTouchMode = e.matches;
});
document.addEventListener('pointerdown', e => {
if (e.pointerType === 'touch') {
isTouchMode = true;
document.documentElement.setAttribute('data-input-mode', 'touch');
}
});
pen输入类型Surface Pen或Wacom手写笔接入时,pointerType值是pen。它不是mouse,也不是touch,但同样不支持悬停。CSS中pointer: fine会匹配笔,但好消息是hover: none通常也成立——所以你的触控适配逻辑必须把pen算进去。
e.pointerType === 'pen'的判断,把笔归进触控逻辑分支(pointer: pen)——笔属于fine类型,但hover: none已经足够把它区分出来说到底,真正难处理的不是“设备有没有悬停能力”,而是“悬停能力存在但当前没激活”。所有基于能力的静态判断都慢半拍,必须靠pointer事件流加媒体查询变更事件,双管齐下。很多团队改完CSS就收工,不加JS监听,结果iPad上第一次点击永远失效——样式没来得及切,用户的耐心已经没了。
侠游戏发布此文仅为了传递信息,不代表侠游戏网站认同其观点或证实其描述