가상클래스 :hover
를 이용하여 선택지 위에 마우스를 올렸을 때 트랜지션 및 백그라운드 컬러를 적용하고자 했으나, 모바일 디바이스 환경에서 선택지 터치 시 해당 css가 적용되어 유지되고 외부 요소를 다시 터치해야 원래대로 돌아가는 side effect가 발생했다.
const Testcard = tw.button`
...
hover: bg-violet-400
hover:border-transparent
hover:-translate-y-1
hover:text-white
...
`
마우스 포인터가 없고 터치 이벤트로 상호작용하는 모바일 디바이스 환경에서 해당 가상 클래스를 사용할 경우, 요소가 터치되면 브라우저는 포인터가 계속해서 해당 요소에 머무르고 있는 것으로 인식하기 때문에 위와 같은 현상이 발생했다.
터치 시에 동작하는 이벤트 순서
touchstart - touchend - mouseover - mousemove - mousedown - mouseup - click
→ 마우스가 존재하지는 않지만, 내부적으로는 터치 이벤트 뿐만 아니라 마우스 이벤트도 함께 발생한다.
터치 인터페이스에서는 hover 효과를 없애주는 분기처리가 필요하다.
아래 코드와 같이 Media Queries Level 4에서 지원하는 @media hover 를 이용하여 해당 문제를 해결했다.
const Testcard = tw.button`
...
[@media(hover:hover){&:hover}]:bg-violet-400
[@media(hover:hover){&:hover}]:border-transparent
[@media(hover:hover){&:hover}]:-translate-y-1
[@media(hover:hover){&:hover}]:text-white
...
`
@media (hover: hover) {
a:hover {
color: white;
background: violet;
}
}
그러나 일부 Android 기기에서 요소를 길게 터치할 경우 동일한 문제가 발생할 수 있으므로 @media pointer 를 이용하여 장치에서의 포인터 존재 여부와 포인팅 장치의 정확도를 확인해, 더욱 명확하게 구분하여 적용할 수 있다고한다.
corase | 터치 스크린에 사용되는 손가락 처럼 부정확한 포인터 장치 지원 |
---|---|
fine | 마우스처럼 정확한 포인터 장치 지원 |
none | 포인터가 없는 장치 |
아래와 같이 적용해 볼 수 있겠다.
@media (hover: hover) and (pointer: fine) {
a:hover {
color: white;
background: violet;
}
}
참고 url