最近のiPadでは「SafariとChromeで表示がいろいろ変わっちゃう」というところから始まり、改めて確認したり、実機を数種試してみたところでメモ。
目次
wp_is_mobileの中身
元々どういう目的で作られたものかは知りませんが、中身は
- ブラウザ情報を覗いて
- あらかじめ設定された文字列が含まれていたら
- 文字列ごとに条件分岐して
- 真偽を返す
というだけのもの。
「is_mobile」も中身は大体同じと思います。
wp_is_mobileやuser agentなどを色々なデバイスで見てみる
現在、ブラウザ右に貼り付いている青いヤツで確認。
厄介なのが最近のiPadのSafari。(調べたのは第4世代iPad Air、OS 15.2~)
mobile判定、user agent、デバイス情報がくっちゃくちゃな感じ。
- デフォルト(環境設定(Safari)「デスクトップ用Webサイトを表示」オン)
wp_is_mobile:false、またuser agentにiPadを含まない - 環境設定(Safari)「デスクトップ用Webサイトを表示」オフ
wp_is_mobile:true、またuser agentにiPadを含む
無理矢理まとめると、
- 基本的にはタッチデバイスであり大画面でもある。
- wp_is_mobileの判定は、ユーザーの設定次第で変わる。
- また常に「iPadである」と特定できるuser agentは無いので、wp_is_mobileをカスタマイズしてもどうにもならない。
「iPad Safari is_moile」等で探すとたくさん見つかる記事の通り。
アップルはなぜこうしているか、をどこかの記事で見かけた気がするのですが、URLを失念。
たしかこんな感じだったと記憶しています。
十分に大きいスクリーンでは、(タッチデバイスであっても)PC用サイトを表示すべき
一方グーグルは、
スマートフォン、タブレットでは、mobile用サイトを表示すべき
のようなことを言っていると思う。(mobileに最適化されたサイト、だったかな?)
参考:user agent(Safari)のコピペ
古いiPad Air
Mozilla/5.0 (iPad; CPU OS 12_5_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.1.2 Mobile/15E148 Safari/604.1
第4世代iPad Air
- デフォルト
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.2 Safari/605.1.15 - 「デスクトップ用Webサイトを表示」をオフ
Mozilla/5.0 (iPad; CPU OS 15_2_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.2 Mobile/15E148 Safari/604.1
iPhoneXS
- デフォルト
Mozilla/5.0 (iPhone; CPU iPhone OS 15_2_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.2 Mobile/15E148 Safari/604.1 - 「デスクトップ用Webサイトを表示」をオン
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.2 Safari/605.1.15
サブメニューの挙動
wp_is_mobileで色々制御していて、SafariとChromeの違いで一番困るのがサブメニュー付きのナビゲーション。
構文は、ワードプレス標準のメニューと仮定して、、
- CSS :hoverでサブメニューの出し入れ、アンカーの挙動をdoubletaptogoなど制御している場合、古いiPadやAndroidでは期待通り動く。
- 新しいiPadでは、タップでサブメニューは開くが、この状態でさらに2回タップしないと遷移しない。(tripletaptogoになっちゃう)
ほかにも、親項目が「<a>アンカー</a>」だとサブメニューが開かなかったり、bodyのタップでサブメニューが閉じたり閉じなかったり、と色々。
今のところ、新旧iPadで期待通り動くスクリプト
jQuery(document).ready(function(){
jQuery('#navigation-menu ul li').hover(function(){
jQuery('ul:not(:animated)', this).slideDown(100);
}, function(){
jQuery('ul.sub-menu', this).slideUp(100);
});
jQuery('#page').on('click', function(e){
jQuery('ul.sub-menu', this).slideUp(100);
});
});
#navigation-menuは、メニューのラッパー。メニュー名で左右されたくないので。
範囲外をタップで閉じるようにしていますが、「body」だと閉じないので、ひとつ内側のラッパー(ここでは#pageにしてますが、テーマによってマチマチなはず。)にしています。
キャッシュ
Is_mobileの判定でいろいろやってる場合、SafariとChromeを行ったり来たりすると、キャッシュによってis_mobile状態も維持されて非常に不安定。
キャッシュ関係のプラグインは一切なし。
同じURLを違うブラウザでしつこく閲覧する、という開発者ならではの行動なので、それほど気にしなくていいとは思うけど、、、
キャッシュ共有の仕組みは調べてもよくわからない。AMPなんとか??
新しいiPadでも、SafariとChromeの表示を常に合わせる
メディアクエリー・スクリーンサイズでの振り分けが一番簡単ですが、ナニカ事情がある場合。
1、Safariでも常にハンバーガーを出す
JavaScriptのタッチデバイス判定だけ。簡単で、動作も一番確実だと思います。
- タッチデバイスではハンバーガー
- 非タッチデバイスではPC用
1-b、「IE非対応」で良ければ
IE無視なら、JacaScript不要、メディアクエリーだけでも処理できます。
PC用 {
display: none;
}
ハンバーガー {
display: block;
}
@media ( hover: hover ) and ( pointer: fine ) {
PC用 {
display: block;
}
ハンバーガー {
display: none;
}
}
タッチデバイス判定や、:hoverに関するあれやこれやも簡単に処理できるので、これからは多用しそう。
参考:下記記事で詳しく解説されています。いろいろ出来るのね~。
CSSのメディアクエリを使ってレスポンシブに対応させる書き方
2、ChromeでもPC用ナビを出す
これはかなり面倒だし、よくよく検証しないとアブない。
- タッチデバイスではハンバーガー
- 非タッチデバイスではPC用ナビ
- user agentに「iPad」が出現していて、かつスクリーン短辺が820px~ならば、例外的にPC用ナビ(OSのバージョンでもいいかもだけど、どっちが長期間確実かなぁ??わからん。)
2-b、縦位置ではハンバーガーを出す
さらに「縦位置ではハンバーガーを出す」なら更に縦横条件を追加するわけだけど、今度はSafari用にも指示が必要。
こっちにはキーワード「iPad」が出現しない可能性大なので、
- タッチデバイス
- user agentにMacintoshまたはiPadが出現
- スクリーン短辺が820px~
- 縦位置
を満たすように条件づければいいはず。ややこしいね。
さらにさらに
ナビゲーションを上部に固定するような場合、ページ内遷移用にスクリプトを使うケースが多いと思います。
これもハンバーガー・PC用ナビで多少の差があるはずなので、スクリプトにも条件分岐を入れて切り替えなきゃならない。
JavaScript、なんちゃってメディアクエリー
screenじゃなくてwindowでやればもっと簡単ですが、CSSやディベロッパーツールと合わせたかったので。
jQuery(function(){
var screenWidth = screen.width;
var screenHeight = screen.height;
if ( screenWidth <= screenHeight ) {
var screenLongSide = screenHeight;
var screenShortSide = screenWidth;
} else {
var screenLongSide = screenWidth;
var screenShortSide = screenHeight;
}
var breakPointMiddle = 768;
var orient = window.onorientation;
if( Math.abs( window.orientation ) === 0 || Math.abs( window.orientation ) === 180 ){
if ( screenShortSide > breakPointMiddle ){
var view_wide = 'wide';
} else {
var view_wide = 'narrow';
}
} else {
if ( screenLongSide > breakPointMiddle ){
var view_wide = 'wide';
} else {
var view_wide = 'narrow';
}
}
/* ---------- デバイス水平方向幅で分岐 ---------- */
if ( view_wide === 'narrow' ) {
var headerHight = 65;
} else {
var headerHight = 105;
}
});
スムーススクロールの余白切り替えなどに。
ハンバーガー、PC用ナビの高さを同じにしちゃう、って手もあるけど、、、
「Jquery依存スクリプトでブレークポイント使ってるの、あったなぁ」と思いだして調べてみると、やっぱりあった。
「window.matchMedia」だけで出来るのね。
:hoverイミュレーションを検知できないのかな、と思って少し検索すると、それっぽい記事がわんさか見つかる。古いiOSでの不具合とか、むしろ:hoverを無効にしたいとか。議論の種だったのね。
「タッチしたつもりなのに遷移しない」と感じることが多いけど、これか。
キチンと調べたら、この記事も色々ひっくり返りそう。
※余談。JavaScriptの判定をそのままphpの関数に出来たらかなり便利な気がしますが、ajaxを使わないと無理みたいで手に余る。でもそのうちチャレンジしてみようかな。
キリがないので、結局JavaScriptのスクリーン幅判定だけで制御することにしました。
- ナビゲーションについては、でかければPC用・小さければハンバーガー
- サブメニューはタッチデバイスでもどうにか動かす。
- wp_is_mobileは一切使わない
まだまだスッキリはしていませんが、ひとまずここでひと区切り。
発見・再認識がたくさんありました。