iOS Safariでタップ時の灰色ハイライトが残る原因と消し方

はじめに

ボタンをタップした瞬間、灰色の半透明な矩形がふわっと表示される。iPhoneでWebページを触ったことがあれば見覚えがあるはずです。デザインカンプにはない要素なので気にならないことも多いのですが、角丸ボタンからはみ出した四角い影として残ったり、タップを離した後もしばらく居座って見た目が崩れて見えたりすることがあります。

この記事では、この灰色ハイライトの正体と消し方、そして消しただけでは失われる「押した感」をどう補うかを解説します。

何が起きているか

この灰色の矩形は、iOS Safari(正確にはWebKit系のモバイルブラウザ全般)がタップ可能な要素を触ったときに自動で表示するデフォルトのフィードバックです。ボタンやリンクにマウスカーソルがないタッチデバイスで、「今どこを押したか」をユーザーに伝えるための仕組みとして用意されています。

意図して付けたスタイルではなく、何も指定しなければブラウザが勝手に描画するものなので、CSSのどこにも原因が見当たらないまま「なぜか灰色の四角が出る」と悩むことになります。

/* CSSで何も指定していなくても、iOS Safariはタップ時に
   この矩形を自動で重ねて表示する */
.btn {
  background: #3b82f6;
  border-radius: 8px;
}

角丸ボタンの上に四角いハイライトが重なるため、角の外側だけ灰色が飛び出て見える崩れ方をするのがよくあるパターンです。

修正方法: -webkit-tap-highlight-colorで消す

ハイライトの色は -webkit-tap-highlight-color というWebKit独自のプロパティで制御できます。transparent を指定すれば、タップ時の矩形自体を表示しないようにできます。

.btn {
  -webkit-tap-highlight-color: transparent;
}

ページ全体で統一したい場合は、*html に対してまとめて指定してしまう方法もよく使われます。ただし、後述するように「消しただけ」だとタップしたことが伝わらなくなるボタンが出てくるので、一括で消す場合でも代替フィードバックの検討はセットで行ってください。

/* サイト全体で一律に消す場合 */
* {
  -webkit-tap-highlight-color: transparent;
}

消すだけで終わらせない: :activeで押した感を用意する

デフォルトのハイライトは見た目が地味な半透明の灰色ですが、役割としては「押したことをユーザーに伝えるフィードバック」です。transparent にして単純に消してしまうと、ボタンを押しても何の反応もない、押せているのか分からないUIになってしまいます。

そこで、ハイライトを消す代わりに :active 疑似クラスで独自のフィードバックを用意します。

.btn {
  -webkit-tap-highlight-color: transparent;
  background: #3b82f6;
  transition: background-color 0.1s, transform 0.1s;
}

.btn:active {
  background: #1d4ed8;  /* 少し濃い色にする */
  transform: scale(0.97); /* わずかに縮小する */
}

色の変化と拡大縮小のどちらか一方だけでも十分です。派手にしすぎるとタップのたびにガタつく印象になるので、0.1〜0.15秒程度の短いトランジションに留めるのがおすすめです。

デモで確認する

このハイライトはタッチデバイスの描画なので、PCのマウス操作では再現できません。お手元のiPhoneで下のボタンを実際にタップして違いを確認してください。

崩れるパターン(tap-highlight-color未指定)
修正パターン(transparent + :active)

「崩れるパターン」のボタンをiPhoneでタップすると灰色の矩形が重なって表示され、指を離した後もしばらく残って見えます。「修正パターン」ではハイライトの代わりに色の変化とわずかな縮小だけが一瞬起こり、灰色の矩形は出ません。

注意点: :activeが効かないケースがある

iOS Safariでは、:active のスタイルが要素にタッチイベントのリスナーが何も付いていないと発火しない、という古くからの挙動があります。ボタンや <a> タグ単体であれば通常は問題になりませんが、独自のタップ処理をJavaScriptで組んでいる要素(div にクリックイベントだけ付けている場合など)では :active が反応しないことがあります。

この場合は、要素に空の touchstart リスナーを1つ付けておくと :active が有効になります。

/* :active が発火しない要素に対するおまじない */
element.addEventListener('touchstart', function () {}, { passive: true });

ページ全体で一度だけ設定しておけば十分なので、初期化処理の中にまとめておくとよいでしょう。

まとめ

iOS Safariの灰色ハイライトは、ブラウザがタッチ操作のフィードバックとして自動で表示しているものです。-webkit-tap-highlight-color: transparent で消せますが、消しただけでは「押した感」が失われてしまいます。:active で色の変化や縮小といった代替フィードバックを必ずセットで用意してください。独自のタップ処理をしている要素で :active が効かない場合は、空の touchstart リスナーを追加する対処も覚えておくと安心です。

コピペで使える正解パターン

/* ===== タップ時の灰色ハイライトを消す ===== */
.btn {
  -webkit-tap-highlight-color: transparent;
  background: #3b82f6;
  color: #fff;
  border: none;
  border-radius: 8px;
  padding: 14px 32px;

  /* 【重要】消すだけで終わらせない。
     :active の変化がタップのフィードバックの代わりになる。 */
  transition: background-color 0.1s, transform 0.1s;
}

.btn:active {
  background: #1d4ed8;
  transform: scale(0.97);
}
/* 【補足】独自のタップ処理をしている要素で :active が効かない場合の対処。
   ページ内で1回呼んでおけば、以降の要素にも :active が反映されるようになる。 */
document.addEventListener('touchstart', function () {}, { passive: true });

最後まで読んでいただきありがとうございました。

関連するUI事例

タップ操作を伴う代表的なUI事例です。いずれもコピペで動くサンプルを掲載しています。

同じiOS Safariシリーズの記事もあわせてどうぞ。