CSS
jQuery
scss

スマホで触れている間だけhoverする

More than 1 year has passed since last update.

CSSにhoverを与えたとき、スマホではタップして指(指とは限らない)が離れるときに発火します。
感覚的にはタップした瞬間から離れるときまでの間がhoverであって欲しい。

ググるとjQueryのタッチイベントで、触れた瞬間から離れるまでの間にクラスを与えるという方法で回避しているようです。hoverを指定したものはPCではhover、スマホではタッチイベントになります。
個人的な考えですが、CSSで解決出来るものはCSSで解決したいです。

スマホに擬似クラスhoverを与えてはいけません。
指が離れてから発火してしまうので、スマホはtouchイベント、PCは:hoverなコードを書きます。

コード

jQuery
$('a, input[type="button"], input[type="submit"], button, .touch-hover')
  .on('touchstart', function(){
    $(this).addClass('hover');
}).on('touchend', function(){
    $(this).removeClass('hover');
});

hoverで変化がありそうな要素を入れてあります。
加えてhoverが必要になるものに.touch-hoverを与えます。
これでタッチしている間だけ.hoverが付きます。

html
<div class="touch-hover test">テスト</div>
<a href="#" class="test">テスト</a>

今回は.testをホバーしたときに文字色を変更します。

SCSS

mixin
$grid-breakpoints: (
  xs: 0,
  sm: 576px,
  md: 768px,
  lg: 992px,
  xl: 1200px
) !default;


@mixin hover($tap-highlight:false) {
  @if $tap-highlight == false {
    &.hover {
      -webkit-tap-highlight-color: transparent;
      @content;
    }
  } @else {
    &.hover {
      @content;
    }
  }
  @media screen and (min-width: map-get($grid-breakpoints, lg)) {
    &:hover {
      @content;
    }
  }
}

コチラのコードがmixin。ブレークポイントはBootstrap4の値です。
リンクなどをタッチした際に背景がグレーになる-webkit-tap-highlight-color用に分岐してます。

scss
.test {
  @include hover() {
    color: red;
  }
}

includeでmixinを呼び出し、文字色を赤にします。

scss
.test {
  @include hover(true) {
    color: red;
  }
}

-webkit-tap-highlight-colorを活かしたいなら括弧の中に何か入れて下さい。

css

css
.test.hover {
  -webkit-tap-highlight-color: transparent;
  color: red;
}

@media screen and (min-width: 992px) {
  .test:hover {
    color: red;
  }
}

SCSSが吐き出したCSSです。
CSSに直接書くなら上記のコード。

終わり

疑似クラスactiveはPCだけに与えましょう。今回のコードとぶつかります。

今回Bootstrap4のブレークポイントが変更されていてびっくりしました。
Bootstrapを使うならSCSSの値を拾ったほうが安全ですね。