技術的な内容の記事です。
現在、まめわざでは管理ページのスマホ対応化を進めています。
問合せフォームなどの設定をiframeで行っていますが、position:fixedで表現する小窓内にiframeを置いた場合、iOSのSafariでスクロールしなくなる現象に悩まされました。
試行錯誤の結果、解決方法を見つけたのでここに記します。
以下のHTMLとCSSの組み合わせで、position:fixedのiframeがスクロールするかを、iOSのSafariで検証しています。
結果 | HTML・CSSの説明 | HTML例 | CSS例 |
---|---|---|---|
× | iframeにposition:fixed | <iframe class="type1" frameborder="0"></iframe> | iframe.type1 { position:fixed; overflow:auto; left:0; top:0; width:100%; height:100%; } |
× | position:fixedの下にiframe | <div class="type2"><iframe frameborder="0"></iframe></div> | div.type2 { position:fixed; left:0; top:0; width:100%; height:100%; } div.type2 firame { width:100%; height:100%; } |
× | position:fixedの下にiframe & -webkit-overflow-scrolling:touch;の魔法 | <div class="type3"><iframe frameborder="0"></iframe></div> | div.type3 { position:fixed; left:0; top:0; width:100%; height:100%; } div.type3 firame { width:100%; height:100%; -webkit-overflow-scrolling:touch; } |
× | スクロールするposition:fixedの下にiframe | <div class="type4"><iframe frameborder="0"></iframe></div> | div.type4 { position:fixed; left:0; top:0; width:100%; height:100%; overflow: auto; } div.type4 firame { width:100%; height:100%; } |
○ | スクロールするposition:fixedの下にiframe & -webkit-overflow-scrolling:touch;の魔法 | <div class="type5"><iframe frameborder="0"></iframe></div> | div.type5 { position:fixed; left:0; top:0; width:100%; height:100%; overflow: auto; -webkit-overflow-scrolling:touch; } div.type5 firame { width:100%; height:100%; } |
重要なポイントは以下です。
まず、iframeそのものをposition:fixedにする場合はiOSでスクロールできません。必ずposition:fixedとなる上位の要素の中にiframeを設置する必要があります。
次に、iframeにscrollを担当させてはいけません。ここがなかなか気がつかないポイントです。position:fixedとした上位の要素をoverflow:autoにして、iframeのスクロールの仕事を上位の要素に担当させます。
またに、iOSのスクロール系の解決策として検索すると出てくる
-webkit-overflow-scrolling:touch;
という魔法が必要ですが、これも上と同じ理由で、iframeではなく上位の要素(スクロールを担当する要素)にセットする必要があります。
最後に、このギミックで出来上がった要素をiframeっぽく見せるため、またクロスブラウザ化するために、iframeのwidthとheightを100%にして、frameborder=0をHTMLに設置します。この状態ではiframeの枠が消えるので、上位の要素に枠を定義します。
この問題は、iOSのSafariが「iframeの中身をスクロール不要で全て表示する」ことに起因しています。
position:fixedに限らず、文章の一部としてiframeを利用する場合でも、heightは無視され中身が全て表示されてしまいます。
この場合も、
このようにして対策が可能です。
iframeを使った処理は今後なるべく減らしたほうが良い、と考えています。例えば次のような理由が挙げられます。
2番目は特に重要です。モバイル環境を第一に考えるモバイルファーストという言葉がありますが、使いやすいインターフェースを考えた場合、iframeは既に避けた方が無難な選択肢の1つだと言えます。
まめわざではiframeによる処理を実装してしまいましたが、少しずつ使用しないようにプログラムを変更していこうと考えています。