Edited at

-webkit-overflow-scrollingを指定するときについでにやっておいた方がいいこと

More than 3 years have passed since last update.


追記

iOS9で試してみたら、効かなくなってました……。「一部の要素のスクロールがページ全体のスクロールに影響しない」って結構重要だったのに、残念です。iOS8については試していないのでわかりませんが、バグだったということでしょうか。


以下本文


スクロールできる要素の問題点

まず前提として、スクロールできる要素に対して-webkit-overflow-scrolling: touch;と指定すると慣性スクロールが実装できます。例としてグローバルメニューのようなものを作ってみます。


html

<nav id="menu">

<!-- 長いコンテンツ -->
</nav>


css

#menu {

position: fixed;
top: 0;
left: 0;
height: 100%;
overflow-y: auto;
-webkit-overflow-scrolling: touch;
}

これでスクロールはしやすくなるのですが、このままでは『その要素が既に限界まで上/下にスクロールされている状態でさらに上/下までスクロールしようとすると、ページがスクロールされてしまう』という問題が残ります。

何を言ってるのかわかりづらいとは思いますが、ドロワーメニューなんかだと結構気になります。

image01.png

デモを見る

スクロールしやすい大きさにズームしてから、一番上までスクロールされていることを確認して、さらに上までスクロールしてみてください。ページごと動くと思います(なお自分がやってみた限りでは、一回ピンチアウトしないとどっちにしろスクロールが効かない)。


対処法

以下のような二重の構造にすると、これを防ぐことができます。


html

<nav id="menu-outer">

<div id="menu-inner">
<!-- 長いコンテンツ -->
</div>
</nav>


css

/* 外枠はそのまま */

#menu-outer {
position: fixed;
top: 0;
left: 0;
height: 100%;
overflow-y: auto;
-webkit-overflow-scrolling: touch;
}

/* 内枠を追加 */
#menu-inner {
width: 100%;
height: 100%;
overflow-y: auto;
}


image02.png

デモを見る

先ほどと同じようにズームしてから、さらに上までスクロールしてみてください。ページごとは動かず、ちゃんと下方向に引っ張られると思います(こちらも一回ピンチアウトしないとスクロールが効かない)。


その他

個人的に結構気になっていて、JavaScriptを使って試行錯誤していたのですが、結局これが一番最適な方法だと思います。調べてみてもこの問題について書かれているサイトがなかった(というよりどう検索すればいいのかわからなかった)ので、ここに書き記すことにしました。

最初に記した通りiOSでしか確認していませんので、Androidだとどうなるかはわかりません。

ちなみに、Google+のモバイルサイトでも同じような方法を使っているようです。


編集履歴

2015.6.14


  • デモを追加(viewportが設定できない上にiframeなのでどうしても微妙になる)

  • 構造をわかりやすく

2016.3.7