スマホでhoverの動きをSassで矯正させるmixin
スマホでhoverの動きをSassで矯正させるmixin:
最近、スマホで触れている間だけhoverするがチョコチョコいいねをして頂いて嬉しいが、中途半端なコードなので申し訳ないやら。
と、いうことでちゃんとしたのを書いてみました。
土日あたりにGithubに上げますね。
動作サンプルはめんどくさいので用意していません。あしからず。
古いバージョンだと
Sass 4.0.0以降なら動作確認済みです。
まずはじめにuserAgentでブラウザ&デバイス判別 2017年版 - QiitaのGithubからユーザーエージェント判定用のスクリプトを拝借します。
※ 何が条件なのか分からないが、
参考:タッチデバイスでCSSの:activeや:hoverを機能させる。 - Qiita
mixinを書きました。
なにも考えずにmixinを利用すると以下のようになる。
autoprefixerを利用しているのでベンダープレフィックスがついています。
デフォルトでは
上記CSSのon、offに加え、
※ 太字がデフォルト値
※
こんな感じで簡単にスマホがタッチされたときの挙動を
iphoneで
最近、スマホで触れている間だけhoverするがチョコチョコいいねをして頂いて嬉しいが、中途半端なコードなので申し訳ないやら。
と、いうことでちゃんとしたのを書いてみました。
土日あたりにGithubに上げますね。
動作サンプルはめんどくさいので用意していません。あしからず。
古いバージョンだと
&の扱い方が違うので正しく吐き出されないかもしれません。Sass 4.0.0以降なら動作確認済みです。
Scss こんな書き方でスマホに対応できます
smple.scss
a {
color: gray;
@include hover {
color: red;
}
@include active {
color: green;
}
}
準備
まずはじめにuserAgentでブラウザ&デバイス判別 2017年版 - QiitaのGithubからユーザーエージェント判定用のスクリプトを拝借します。index.html
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Title</title> <link rel="stylesheet" href="/css/style.css"> </head> <body> <div ontouchstart=""> </div> <script src="/js/userAgentChecker.min.js"></script> </body> </html>
userAgentChecker.min.jsを読み込みます。<div>をラッパーにして(全てを<div>で囲む)ontouchstart=""を記述します。※ 何が条件なのか分からないが、
<body ontouchstart="">では動かないことがあったので<div ontouchstart="">としたら動いたのでラッパーに与えた。参考:タッチデバイスでCSSの:activeや:hoverを機能させる。 - Qiita
userAgentChecker.min.jsを読み込んだ時点で<html>にclass=""が付与されています。ここでタッチデバイス.touchか、マウス操作.mouseか分かる様になるので、これをCSSで利用します。
SCSS mixin
mixin/_hover.scss
@mixin hover ($touch: false, $highlight: false, $userSelect: false, $focus: true) {
// mouse
@at-root .mouse &:hover {
@content;
}
@if $focus == true {
@at-root .mouse &:focus {
@content;
}
}
// touch
@if $touch == true {
@at-root .touch &:active {
@content;
}
// $highlight
@if $highlight == false {
-webkit-tap-highlight-color: rgba(#000, 0);
appearance: none;
}
// $userSelect
@if $userSelect == false {
@at-root .touch & {
user-select: none;
input, select {
user-select: auto;
}
}
}
} @else if $touch == false {
} @else {
@warn 'mixin hover $touchの値が正しくありません';
}
}
mixin/_active.scss
@mixin active ($touch: true, $highlight: false, $userSelect: false) {
$e: &;
// mouse
@at-root .mouse #{$e}:active {
@content;
}
// touch
@if $touch == true {
@at-root .touch #{$e}:active {
@content;
}
// $highlight
@if $highlight == false {
-webkit-tap-highlight-color: rgba(#000, 0);
appearance: none;
}
// $userSelect
@if $userSelect == false {
@at-root .touch #{$e} {
user-select: none;
input, select {
user-select: auto;
}
}
}
} @else if $touch == false {
} @else {
@warn 'mixin active $touchの値が正しくありません';
}
}
mixin/_focus.scss
@mixin focus () {
@at-root .mouse &:focus {
@content;
}
@at-root .touch &:focus {
@content;
}
}
:hover、:activeを書くような感じで利用したかったので使い方は事項のようになります。:focusを利用したいとき、:focus {}と書くとmixinで吐き出す.mouse a:hoverに優先度で負けてしまうので、頭に.mouse、.touchをつけるだけのfocus用のmixinを作成しました。
mixinを利用
なにも考えずにmixinを利用すると以下のようになる。style.scss
a {
color: gray;
@include hover {
color: red;
}
@include active {
color: green;
}
}
コンパイル結果
a {
color: gray;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
}
.mouse a:hover {
color: red;
}
.mouse a:focus {
color: red;
}
.mouse a:active {
color: green;
}
.touch a:active {
color: green;
}
.touch a {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.touch a input, .touch a select {
-webkit-user-select: auto;
-moz-user-select: auto;
-ms-user-select: auto;
user-select: auto;
}
デフォルトでは
user-select: none、-webkit-tap-highlight-colorが透明、appearance: noneが付与されて出力されます。上記CSSのon、offに加え、
.touchのCSSがhoverと一緒なのかactiveと一緒なのかを引数で選択できるようにしています。| touch | user-select | -webkit-tap-highlight-color | appearance | focus | |
|---|---|---|---|---|---|
| hover | true/false |
true/false |
true/false |
true/false |
true/false |
| active | true/false | true/false |
true/false |
true/false |
- |
| focus | - | - | - | - | - |
※
user-select, -webkit-tap-highlight-color, appearanceはtouchがtrueのとき利用できる。
引数を利用したサンプル
style.scss
a {
color: gray;
@include hover (true, false, true) {
color: red;
}
@include active (false) {
color: green;
}
@include focus () {
}
}
コンパイル結果
a {
color: gray;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
}
.mouse a:hover {
color: red;
}
.mouse a:focus {
color: red;
}
.touch a:active {
color: red;
}
.mouse a:active {
color: green;
}
hoverではなく、感覚的なものに変更できたかと思います。
余談
iphoneでcolorの指定がないと、colorが背景色になるバグ発見!a:hover {
background-color: red;
}
コメント
コメントを投稿