Help us understand the problem. What is going on with this article?

スマフォでlandscape(横持ち)フルスクリーンサイトを作る際のノウハウ

More than 3 years have passed since last update.

はじめに

通常のブログや縦長サイトをlandscapeで見る場合は特に特別なことをやる必要はないと思いますが、画面にFIXした「アプリっぽい」サイトを制作するときには色々と癖があり、事前に想定しておく必要のあるものがたくさんありますので、そちらを可能な限りまとめていけたらと思います。
※ いったん、Androidを無視して、Mobile Safari(以下、ブラウザ)に限定した記事になります。
※ ここでいうフルスクリーンとは ブラウザの上下にあるUIバーが隠れて、ディスプレイ全体でウェブサイトを表示している状態を指します。

フルスクリーンにするための手段

iOS9 現在の情報です。

有効なもの

  • オリエンテーションが変わって横持ちになったとき(landscape限定)
  • 長いページを下にスクロールしたとき(landscape, portrait共に)
  • <meta name="apple-mobile-web-app-capable" content="yes"> を設定し、ホーム画面登録させて立ち上げる

無効になったもの

  • iOS6以前の window.scrollTo(0, 1) ハック
  • iOS7のみの minimal-ui viewportプロパティ

実現できないもの

  • jsで任意のタイミングでUIバーを隠すこと(擬似的に orientationchange イベントなどを発火してもフルスクリーンにすることは不可能です。タイミングは完全にユーザーに委ねられています)。
  • <meta name="apple-mobile-web-app-capable" content="yes"> を使わない状態でのportraitフルスクリーン
  • landscape状態でサイトにアクセスした際のフルスクリーン化(必ずportrait -> londscape と orientationchangeイベントを発火させる必要があります)

前準備

現在有効なもののうち、
3つ目の「ホーム画面に登録させる」はユーザー頼みになってしまい現実的ではなく、
2つ目も、今回は画面FIXしたアプリ風のサイトを目指すので目的に即していません。
というわけで1つ目の オリエンテーションが変わって横持ちになったとき にフォーカスすることにします。

ただ、単純にlandscapeにしたらフルスクリーンになる(上下のUIバーが隠れる)わけではありません。
ポイントとしては表示コンテンツ(bodyの高さ)がディスプレイサイズ以上になっている必要があります。
なので

<body>
    ...
</body>

body {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 101%; // ここがポイント
}

このようにします。
これでlandscapeにすると確実にフルスクリーンになります。

フルスクリーンを解除させないTips

上記で無事landscapeのフルスクリーンは実現できたので、あとはひたすらウェブサイトを構築していくのみですが、
あくまでこのフルスクリーンは「擬似」的なものなので、「フルスクリーンが解除してしまう(UIバーが出てきてしまう)弱点」がかなりあります。
ここからは、「なるべく」そうならないようなTipsをご紹介していきます。

1.スクロールはjsで制御すべし

上にスクロールした瞬間にUIバーが再表示されてしまいますので

document.body.addEventListener('touchmove', function (e) {
    e.preventDefault();
});

こんな感じで bodyのtouchmoveを無効にしましょう

そしてスクロールで表示したいコンテンツはjsの擬似スクロールで実装しましょう。
※ 要素内スクロール(overflow:scrollとか)でも一見いい感じなのですが、要素を一番上までスクロールしたあとも上方向にスクロールを続けようとするとUIバーが出てきてしまいます。

ちなみに僕は普段 https://github.com/mjohnston/scroller をベースに魔改造した独自ライブラリを使っております。

2.クリックイベント系に注意すべし

クリックイベント系でURLを更新する(ページが切り替わる)とUIバーが出てきてしまいます。
対策は以下のようにします(hashchangeを用いたSPAサイトを想定)。

<a href="#!/hoge/hoge" id="hoge">HOGEのページ</a>
var el = document.getElementById('hoge');
el.addEventListener('click', function (e) {
    e.preventDefault();
}, false);
el.addEventListener('touchstart', function (e) {
    location.hash = '#' + this.href.split('#')[1];
}, false);

このように touchstart リスナー内で hash を更新します。
ちなみにjsで更新すればいいというわけでなく、clicktouchend のリスナー内で hash を更新するとUIバーが出てきてしまいます。
また touchend のリスナー内で setTimeout を用いて非同期でも更新してみましたが、ダメでした。

3.ボタンなどの配置場所に注意すべし

フルスクリーンになったあと、画面の上部や下部をタップするとUIバーが出てきてしまいます。
具体的にはiPhone5sまで(landscape時の高さが320pxの端末)では上は約20px、下は約40px
iPhone6以降は上の約20pxのみ(下はタップしてもUIバーは出てきません)がUIバー表示領域になります。
なので、iPhone5以前も考慮するとなると縦320px中、60px分がタップ禁止区域になるので
縦260px以内にボタンなどが収まるようデザインをしなくてはいけません。

また、個人的には60pxというのはホントにギリギリのラインなので、
できたらもう10pxぐらいは余裕を持って、縦240px以内に収まるようにできればベストかと思います。

naota70
I`m web developer and motion designer.
https://b42.co.jp
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away