iPhone で iframe を fixed にする場合の問題

はてなブログ(当サイト)に Google Forms でお問い合わせフォームを作ろうとしているのですが、iframe をポップアップで表示する際に iPhone で引っかっています。

Googleフォーム自体は、すでに別記事で完成していますのでリンクで済ませればいいんですが、始めてしまったがために深みにはまり込んでしまった感じです(笑)。



www.imuza.com


reCAPTCHA がはみ出す

順番に問題を整理していきますと、まずデバイスは、iPhone5s ですので、ブラウザの解像度は 320px 、iOS は現在 10.2.1 です。


Google Forms は、設定で「メールアドレスを収集」にしますと自動的に reCAPTCHA が挿入されます。この reCAPTCH の幅そのものは 300px 程なのですが、マージン等で 320px からはみ出してしまいます。

サンプルサイト

サンプルサイトをスクロールさせますと、reCAPTCHA ありなしリンクがあります。下の画像は「あり」の場合の Googleフォームです。


f:id:ausnichts:20170530120535j:plain


iPhone って、コンテンツが横にはみ出しますと、画面がヌルヌルと左右に動いて気持ち悪いですね。

ただ、この reCAPTCHA のサイズは変更しようがありませんので、はみ出しを我慢するか、reCAPTCHA をあきらめるしかありません。


iframe の Googleフォームを fixed で表示する

やりたいことは、ブログのボトムに Googleフォームへのリンクを貼っておき、クリックするとポップアップで表示するようにしたいわけです。


まず、Google Forms で「送信」から iframe を選びますと下のコードを取得できます。

<iframe src="https://docs.google.com/forms/d/e/1FAIpQLScPWyaGOjtYQWS1uLzNXc7FHc1Iyij_LGqiP4rOKGY2N48-bA/viewform?embedded=true" width="760" height="500" frameborder="0" marginheight="0" marginwidth="0">読み込んでいます...</iframe>


width, height は css で指定すればいいですので削除し、その他いろいろ処理を施し、次の HTML を カスタマイズ > フッタ に貼り付けます。URL は長いので省略しています。

<a class="btn" href="javascript:gForm();">GoogleForm On/Off</a>

<div id="ifm-wrapper">
<a class="btn hide-gform" href="javascript:gForm();">GoogleForm On/Off</a>
<iframe src="フォームURL" frameborder="0" marginheight="0" marginwidth="0"></iframe>
</div>

<script>
function gForm(){
document.body.classList.toggle('gform');
}
</script>


CSS をデザインCSS に貼り付けます。

.btn {
  padding: 10px;
  border: 2px solid #ccc; }

#ifm-wrapper {
  display: none; }

.gform #ifm-wrapper {
  display: block;
  position: fixed;
  top: 0;
  left: 0;
  z-index: 9999; }

.hide-gform {
  display: block; }


これですとうまくいきません。


fixed が iPhone ではスクロールしない

横幅、高さを指定していないのですが、iPhone では、画面いっぱいに表示され、スクロールできません。スクロールさせますと、iframe ではなく背景のコンテンツがスクロールします。

f:id:ausnichts:20170530125648j:plain


この問題は、こちらのサイトに詳しく解説されています。

mamewaza.com


このサイトを参考に下の CSS を追加しましたら、見事に解消しました。

.gform #ifm-wrapper {
  width: 100%;
  height: 100%;
  overflow: auto;
  -webkit-overflow-scrolling: touch; }

  .gform #ifm-wrapper iframe {
    width: 100%;
    height: 100%; }


ポイントは、スクロールを iframe ではなく、ラッパーに担当させるということのようです。上記のサイトによりますと、

この問題は、iOSのSafariが「iframeの中身をスクロール不要で全て表示する」ことに起因しています。

とのことですが、これは Chrome でも症状が出ます。


キーボードを出すと fixed 要素が消える

これで解決かと思いきや、新たな問題が発生します。


フォームに入力するために input要素にフォーカスを当てますとキーボードが出ますが、同時にフォーム自体が消えてしまいます。どこへいったんだろうとスクロールさせますと、上の方へ飛んでしまっています。

これはどうやら、キーボードを出しますと、強制的に position:fixedposition:absolute に変更されてしまうようです。フォームが表示された状態で上までスクロールさせた後に input をタッチしますと、その位置でキーボードが出ます。これは、iOS のバグなのか仕様なのか、ググりますといろいろヒットしますが決定打はなさそうです。


スクロール量を取得し、iframe を absolute でその位置に出せばどうなんでしょう?

やってみる価値はありそうですが、ちょっと小休止です。