[HTML & CSS General] モバイルブラウザでピンチアウトすると position:fixed した要素がただよう

PC向けにデザインされたサイトをモバイルブラウザでも表示させるという条件ではまりました。

Contents

症状

モバイルブラウザでも同じデザインレイアウトで表示させたい。

  • PC向けにデザインされた Fixed-Width レイアウト
  • メインコンテンツの左右に固定配置要素

ナビゲーションやページタイトルといった要素が position:fixed されています。

モバイル用のデザインはありません。
ユーザーの使い勝手を考えると、横幅を指定して表示し、ピンチイン/ピンチアウトによるスケールの変更を許可する必要がありそうです。

<meta name="viewport" content="width=1280, user-scalable=yes" />

この状況で、モバイルブラウザでピンチアウトすると position:fixed した要素がただようように表示され、拡大して読みたいメインコンテンツの邪魔をします。

調査

調査をすると モバイルブラウザで position:fixed を利用するのはいろいろとリスクがあることが分かりました。

全般

いわゆるスマホサイトの制作について。
今回の件とは直接関係しませんが色々あることが分かりました。

(スライド 38-44) CSS Nite LP, Disk 13 の講演スライド。iOS の話。

(スライド 28-32) CSS Nite in OSAKA, Vol.29 の講演スライド。Android の話が主。

(スライド 52-53)

補足

Android 2.x 系では、position: fixed を使う場合、viewport user-scalable=no の指定が必須とのこと。

Android 2.x 系のシェアは、約14%(2014/07 現在)。

また、何かの際にはこちらのまとめが役立ちそうです。

今回のケース

いろいろ探し回って、こちらで救われました。

ピンチインピンチアウトやダブルタップにより画面が拡大された場合、SPモードではposition:fixedの指定がposition:staticの状態に変更されますが、PCモードではposition:fixedの状態が保たれます。これによりPCモードでは拡大した際にposition:fixedを指定した要素が画面内に常にいるようになり結構邪魔になりますので、PCモードを利用する場合はposition:fixedは利用しないほうがよいでしょう。

viewport の設定との両立で困ったわけですが、width 設定によって振るまいが変わるとのこと。

対応

今回のケースを解決するためには、JavaScript で position:fixed を指定したクラスを外すような処理が良さそうです。
CSS クラスに下記を用意し、固定したい要素に指定しておき、

.fixed {
  position: fixed;
}

jQuery でピンチアウトを検出して、.fixed クラスを外します。

/*
  モバイル端末でピンチ時に position: fixed を外す
*/
$("body").on("gestureend", function(){
  'use strict';
  $('#nav-fixed').removeClass('fixed');
  $('#page-title-fixed').removeClass('fixed');
});

但し、gestureend が iOS のみで有効らしく、Android でどのように実装するのかは別途調査が必要そうです。
Android 端末を手に入れてからまた調べます。