スマホでスクロール要素があると画面全体スクロールが動作しなくなる件

またもや嫁スマホで不具合検知してくれました。
うちの家族は子供4人で、一番下が小学6年生なので、スマホをもたせていて、嫁も含めて6人家族で全てがiPhoneで揃えています。
でも、一家の主である自分以外は全て自分のお下がりiPhoneを渡しているのですが、その6人の中で最もITリテラシが低い嫁のスマホがスペシャルデバッガーになっているという事を前提にお話します。
そもそも、ITリテラシの低い嫁スマホといのは、OSのアップデートも自分では行えないため、手を貸してあげないと未来永劫ずっと古いOSをアップデートしないまま何の疑問も持たずに使い続けてしまうため、旧型スマホを使っている人の環境がそのまま残っているため、PCで開発して、手持ちのスマホで検証するが、見つけられない事象を山のように吐き出してくれます。
今回も、自宅専用家計簿システムを作った時に、嫁のスマホでバグが出るわ出るわで、思いっきりバグ対応表を作成する事になり、その中の一つに、下位互換機能に関する比較的重要なものがあったので、ブログに残しておきます。
scroll in scroll不具合について
それは、家計簿の一覧が表示される表組みの画面で発生しました。
小さなスマホ画面では、当たり前のように入り切らないtable構成の表を横スクロールにして、縦はブラウザのスクロールにまかせていた所、
嫁スマホで、画面の一番下が見れないという報告が入る。
確認してみたところ、自分のスマホ(iOS13)では全く問題なく画面下部までスクロールできるのに、嫁スマホ(iOS12)では、確かに一番下までスクロールしない・・・
というか、縦スクロールがされていない感じである。
どうやら、bodyタグ(htmlタグ)が画面の縦スクロールをしていて、内部要素で横スクロールを行っているのですが、横スクロールのエレメント箇所で縦ドラッグしても、画面が固定化されて、縦スクロールされないという事象らしい。
スマホ全体でその使用であれば、そのままにしておいても良かったのだが、OSバージョンによって違う挙動がするのは、原因究明をしておく必要があったので、さらに詳しく調査してみることにした。
scroll in scrollのサンプルソースコード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
<!DOCTYPE html> <html lang="ja"><head> <title>重複スクロール</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no, minimum-scale=1.0, maximum-scale=0.5"> <!-- <meta name="description" content=""> <meta name="author" content=""> <meta http-equiv="Pragma" content="no-cache"> <meta http-equiv="Cache-Control" content="no-cache"> <meta http-equiv="Expires" content="0"> --> <style> html,body{ width:100%; height:100%; margin:0; padding:0; overflow-x:hidden; } *, *:before, *:after { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; -o-box-sizing: border-box; -ms-box-sizing: border-box; box-sizing: border-box; } .contents{ width:90%; height:auto; margin:0 auto; padding:20px; border:1px dashed #5673F7; background: -moz-linear-gradient(180deg, white, #5DBBFE); background: -webkit-linear-gradient(180deg, white, #5DBBFE); background: linear-gradient(180deg, white, #5DBBFE); overflow-x:auto; } .object{ width:120%; height:1000px; border:1px dashed black; background: -moz-linear-gradient(90deg, #ccc, #666); background: -webkit-linear-gradient(90deg, #ccc, #666); background: linear-gradient(90deg, #ccc, #666); opacity:0.5; } </style> <body> <h1>多重スクロール調査</h1> <div class="contents"> <div class="object"></div> </div> <br> <h2>スクロール下部</h2> </body> </html> |
See the Pen
scroll-in-scroll by YugetaKoji (@geta1972)
on CodePen.
気になる人はhtmlファイルをコピペして実際にiOS12のsafariアプリで閲覧してみてもらいたいのだけれども、確かに2つの軸のoverflowが混在していると、タッチしている要素に依存してしまうことがわかると思います。
この時点で最新OSのみの開発で問題ないという方は今回の記事は全く無視してもらって構いませんが、公開型のWEBページを構築する人は是非とも知っておいてほしい。
原因と解決方法
この事象の原因は、タッチするエレメント要素が問題なのではなく、慣性スクロールがデフォルトでONになっているかどうかが問題でした。
あとはOSのそもそものスクロール検知の問題もあるのですが、問題の発生しているiOS12でも、慣性スクロールをONにすることで、最新OSと同じ挙動になることが確認できました。
ポイントは、下記のようなスクロールさせる要素に対して、
1 2 3 |
overflow:auto; overflow-x:auto; overflow-y:auto; |
1 |
-webkit-overflow-scrolling:touch; |
を付けてあげるだけで、正常に動作するようになります。
“-webkit-overflow-scrolling”は、慣性スクロールを許容するかどうかの設定で、”auto”がoffで、”touch”がonになるという仕様ですが、その指定が気持ち悪いという感覚もあるのですが、この機能はスマホのデフォルト設定として、htmlやbodyにデフォルト記述して下層継承させるのがいいかもしれませんね。
機能の詳しくは以下リファレンスページを御覧ください。
https://developer.mozilla.org/ja/docs/Web/CSS/-webkit-overflow-scrolling