在现代Web开发中,随着触摸设备的普及,传统的:hover
伪类在触摸设备上的表现常常不尽如人意。本文档旨在提供一套规范,帮助开发者为触摸设备提供更好的:hover
交互体验。
问题背景
在桌面设备上,:hover
状态会在鼠标悬停时触发;但在触摸设备上,:hover
状态通常会在第一次点击(触摸)时触发,并保持到用户点击其他元素为止。这可能导致以下问题:
- 意外的样式变化
- 交互逻辑混乱
- 可访问性问题
规范建议
1. 使用媒体查询检测触摸设备
scss
// 反面例子:直接使用:hover而不考虑触摸设备
.button {
&:hover {
background-color: blue;
}
}
// 正面例子:使用媒体查询针对不同设备
.button {
@media (hover: hover) {
&:hover {
background-color: blue;
}
}
@media (hover: none) {
&:active {
background-color: blue;
}
}
}
2. 结合:active
和:focus
状态
scss
// 反面例子:仅依赖:hover
.nav-item {
&:hover {
color: red;
}
}
// 正面例子:结合多种状态
.nav-item {
@media (hover: hover) {
&:hover {
color: red;
}
}
&:active, &:focus {
color: red;
}
}
3. 使用JavaScript增强触摸体验
scss
// SCSS部分
.touch-hover {
&--active {
background-color: #f0f0f0;
}
}
javascript
// JavaScript部分
if ('ontouchstart' in window) {
document.addEventListener('touchstart', function(e) {}, {passive: true});
const items = document.querySelectorAll('.touch-hover');
items.forEach(item => {
item.addEventListener('touchstart', function() {
this.classList.add('touch-hover--active');
});
item.addEventListener('touchend', function() {
this.classList.remove('touch-hover--active');
});
});
}
4. 避免仅依赖视觉变化传达信息
scss
// 反面例子:仅通过颜色变化表示可交互性
.link {
color: blue;
&:hover {
color: darkblue;
}
}
// 正面例子:结合多种视觉提示
.link {
color: blue;
text-decoration: underline;
@media (hover: hover) {
&:hover {
color: darkblue;
text-decoration: none;
background-color: #f0f0f0;
}
}
}
最佳实践
-
渐进增强:首先确保基本功能在没有
:hover
的情况下也能工作,然后为支持悬停的设备添加增强效果。 -
明确反馈:为触摸设备提供即时、明显的反馈,通常使用
:active
状态。 -
测试策略:
- 在真实设备上测试
- 使用Chrome DevTools的移动模拟器
- 测试不同尺寸和输入类型的设备
-
性能考虑:避免在
:hover
上触发昂贵的样式计算或布局变化。
反模式
-
仅依赖
:hover
显示重要内容scss// 反面例子 .tooltip { display: none; .parent:hover & { display: block; } }
-
复杂的
:hover
动画在触摸设备上无法触发scss// 反面例子 .card { transition: transform 0.3s; &:hover { transform: scale(1.05); } }
-
忽略
:focus
状态scss// 反面例子 button { &:hover { background: blue; } // 缺少:focus样式 }
解决方案示例
下拉菜单解决方案
scss
// SCSS
.nav-menu {
&__dropdown {
display: none;
}
@media (hover: hover) {
&:hover &__dropdown {
display: block;
}
}
&.is-open &__dropdown {
display: block;
}
}
javascript
// JavaScript
if ('ontouchstart' in window) {
const menus = document.querySelectorAll('.nav-menu');
menus.forEach(menu => {
menu.addEventListener('click', function(e) {
if (e.target.closest('.nav-menu__toggle')) {
this.classList.toggle('is-open');
}
});
});
}
结论
为触摸设备提供良好的:hover
支持需要综合考虑CSS、JavaScript和用户体验设计。通过遵循本规范,开发者可以创建在各种输入设备上都能提供一致、可访问体验的Web应用。关键点是:
- 使用
@media (hover: hover)
和@media (hover: none)
区分设备 - 为触摸设备提供替代交互方式
- 确保重要内容不依赖
:hover
状态 - 全面测试各种使用场景
通过实施这些策略,可以显著提高网站在触摸设备上的可用性和用户体验。