[CSS] PCとスマホのhover問題はこう解決しろ!という話

2024年5月29日

CSS

eyecatch これまであまり来にしなかったけど、スマホとhoverはちゃんとcssで対応しておかないといけないと思いました。 ちなみに、この対応方法についてググって見た所、複数の方法があり、どれがどのように良いのかという事で最も簡単で適切なものを自分の定番方法として定着しておくことにします。 ホームページ制作をする人でhover対応をまだ行っていない人は是非このブログを一読して、ご自身の定番hover対応について思考してください。

スマホのhover問題って何?

パソコンってマウス操作(トラックパッド操作)によって、マウスポインタを動かすインターフェイスですが、 スマホって、指で画面を直接タッチするので、ポインタが存在しません。 hoverというのは、このポインターが対象のエレメントに乗っかっているかどうかを判定する処理で、 ボタンに乗っかっていれば、「あとはクリックをするだけで処理ができますよ」的なお知らせをUIとして表現する事ができるんですが、 スマホはマウスオーバーの概念が無いので、ボタンを直接クリックするしかありません。 (このUIをもっと良くする方法については別途考えたいと思います) そして、cssにおける問題点は、スマホではマウスポインタが無いのに、ToushStartイベントでhoverが動作してしまうという、ありがた迷惑な機能が存在します。 するとどうなるかというと・・・ クリックした時に、マウスオーバーの挙動をして、その後解除されないというなんとも不具合チックな見た目が残ってしまう現象が発生します。 多くの場合、リンクボタンやフォーム送信ボタンにhoverがセットされていることが多いので、リンクやボタンを押したら画面遷移するので、スマホでは気が付きにくいのですが、 リンクが別タブで開いて、元のページに戻った時にうっすら半透明になってたり、ボタンがアクティブに見えてしまうという事象です。 一昔前のhover問題はスマホでcssのhover疑似属性が動作しないというもので、対象タグにontouchstart=""を記述すればいいという裏技があったようですが、最近のスマホではその心配は無くなったようです。

対応方法

スマホでのhover対応をする方法を検索すると、複数の方法が出てきます。 とりあえず、解決に向けた方法をメソッドに沿って書いてみます。

基本コード

hover.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <link rel="stylesheet" href="style.css"/> </head> <body> <button class="hover" type="button">Click</button> </body> </html> style.css .hover{ width:200px; padding:10px; cursor:pointer; border:1px solid black; background-color:#ddd; border-radius:5px; } .hover:hover{ background-color:red; color:white; } デモ : hover スマホでは、クリックしたらボタンが赤くなりっぱなしになります。

active疑似要素

hoverの代わりにactiveを使うとスマホでは思った通りの動きをします。 :hoverを:activeに書き換えてみます。 .hover:active{ background-color:red; color:white; } デモ : active

メディアクエリを使ってhoverを制御

hover疑似属性がある場合のみhoverを対応させるメディアクエリがありました。 @media (hover:hover){ .hover:hover{ background-color:red; color:white; } } .hover:active{ background-color:red; color:white; } デモ : スマホ対応版

javascriptでの対応

もちろんjavascriptでやれば、簡単にできますが・・・cssで完結しないので、逆にめんどくさいと感じる人も多いでしょう。 hover.html <script src="main.js"></script> style.css .js[data-status="mouseover"]{ background-color:red; color:white; } hover.js function Main(){ const btn = document.querySelector("button.js") // スマホ if('ontouchstart' in window || navigator.maxTouchPoints){ btn.addEventListener("touchstart" , (e => {e.target.setAttribute("data-status","mouseover")})) btn.addEventListener("touchend" , (e => {e.target.removeAttribute("data-status")})) btn.addEventListener("touchcancel" , (e => {e.target.removeAttribute("data-status")})) } // pc else{ btn.addEventListener("mouseover", (e => {e.target.setAttribute("data-status","mouseover")})) btn.addEventListener("mouseout" , (e => {e.target.removeAttribute("data-status")})) } } switch(document.readyState){ case "complete": case "interactive": Main() default: window.addEventListener("DOMContentLoaded", (()=>Main())) } デモ

あとがき

おわかりいただけたでしょうか? Javascriptで確実に対応するというケースを否定するつもりはないですが、 WebサイトにおけるUI挙動はできる限りCSSで制御できたほうが効率的です。 Javascriptは、エラーが起きると他の機能などに影響がでる事がありますが、cssは、エラーでもその部分だけの不具合で済みますし、 よほどの粗悪な書き方をしない限り大きな問題につながることが少ないはずです。 ブラウザのアップデートに伴ってできることは増えていきますが、デバイス毎の対応についての検証テストなどの煩雑化なども問題になりますが、 許容範囲のデバイス対応と、そこで確実に動作するという確証さえもっていれば、効率的にWevサイト制作が行えるでしょう。

人気の投稿

このブログを検索

ごあいさつ

このWebサイトは、独自思考で我が道を行くユゲタの少し尖った思考のTechブログです。 毎日興味がどんどん切り替わるので、テーマはマルチになっています。 もしかしたらアイデアに困っている人の助けになるかもしれません。

ブログ アーカイブ