ウェブサイトや何かのアプリケーションを開発しているときに「Internet Explorer(通称:IE)」の対応を求められるときがあります。Internet Explorerは年齢層が高めの方や、主婦の方などが使用しているために、そのような属性の方が利用するサービスを開発している場合はマストです。
自社メディアを運営している会社の方もですが、クライアントの案件をしている受託会社・制作会社の方はほぼ確実に苦しんだことがあるかと思います。
今回は、フロントエンドのエンジニアを苦しめているIEの中でも私のサービスで見つかったIE9とGoogle Chrome、safari、Firefoxなどのモダンブラウザでのレイアウトの違いと、form
タグのブラウザごとの認識でこういう違いがあるんだというハマったポイントをご紹介します。
このページの目次
IE9のフォームのレイアウトはよろしくやってくれない
例えば下記のようなフォームを作成したい場合があります。
名前、かな、メールアドレスなどを入力した後に、登録ボタンと、戻るボタンがある場合です。修正するボタンでは、前のページに戻ったときに入力した値が消えてしまうのは面倒なので、入力した値を引き継いだままに前のページに戻りたいですよね。その場合にform
タグでくくる必要があります。
しかし、登録、修正ボタンともにform
タグでくくり、post
します。その場合に、モダンブラウザでの認識の仕方と、IE9でのフォームのレイアウトの違いがあります。
IE9での補完の違いによってレイアウトが崩れてしまう、具体的にいうと登録ボタンが上で、修正ボタンが段落ちします。ここで、元のソースコード、モダンブラウザでのformタグの認識、IE9でのformタグの認識と分けて紹介します。
レイアウトの関係上特殊なマークアップをあえてしてみた場合
元のマークアップ。少々特殊ですが、上記のようなレイアウトで、form
タグを二つ含む場合、form
タグを使って、JavaScriptを使用しない場合、特殊なDOM構造にする必要がありますよね。レイアウトを実現するために必要なdiv
タグの中に</form>
があるのは非常に違和感があります。
<form action="/regist" method="post"> <input type="hidden" id="lastName" name="lastName" value="田中"> <input type="hidden" id="firstName" name="firstName" value="たなか"> <input type="hidden" id="email" name="email" value="a@gmail.com"> <div class="u-clearfix c-button-column-2"> <p> <button type="submit" name="resistButton">登録する</button> </p> </form> <form action="/back" method="post"> <input type="hidden" id="lastName" name="lastName" value="田中"> <input type="hidden" id="firstName" name="firstName" value="たなか"> <input type="hidden" id="email" name="email" value="a@gmail.com"> <p> <button type="submit" name="return">修正する</button> </p> </form> </div>
続いてモダンブラウザでのDOM構造はどのようになっているのかみてみましょう。
モダンブラウザは良きように閉じタグが認識される
こちらはモダンブラウザのform
タグの構造になっています。モダンブラウザでは勝手にform
タグでform
タグがラッピングされるような構造として補完されています。form
タグの入れ子構造になっていても登録、修正の挙動に問題がないのはモダンブラウザだからでしょうか。
<form action="/register" method="post"> <div class="u-clearfix c-button-column-2"> <input type="hidden" id="lastName" name="lastName" value="田中"> <input type="hidden" id="firstName" name="firstName" value="たなか"> <input type="hidden" id="email" name="email" value="a@gmail.com"> <p> <button type="submit">登録する</button> </p> <form action="/back" method="post"> <input type="hidden" name="_csrf" value=""> <input type="hidden" id="lastName" name="lastName" value="田中"> <input type="hidden" id="firstName name="firstName" value="たなか"> <input type="hidden" id="email" name="email" value="a@gmail.com"> <p> <button type="submit" name="return">修正する</button> </p> </form> </div> </form>
これがモダンブラウザではform
タグで全体を囲うように補完されているので、本来form
タグの入れ子構造はあまりよくありませんが、挙動に問題はないようです。
しかし、これがIEでは違う補完のされ方になります。これが今回ボタンのレイアウトが崩れてしまう要因になっていました。
IE9ではformタグの閉じタグの認識が異なる
上記のフォームがIE9では下記のようにform
タグと、<div class="u-clearfix c-button-column-2">
が勝手に補強されているのです。その結果u-clearfix
によって横長並びになっていたボタンが上下に崩れてしまうという問題が発生します。
form
タグの入れ子構造のマークアップになってしまっているモダンブラウザの方も、本来意図しているマークアップではないですが、モダンブラウザ(スマートフォン端末を含む)では、form
タグの入れ子構造になっていても登録、修正が行えています。なのでモダンブラウザだけでデバッグをしているとIEのレイアウト崩れに気づきません。
<form action="/register" method="post"> <div class="u-clearfix c-button-column-2"> <input type="hidden" id="lastName" name="lastName" value="田中"> <input type="hidden" id="firstName" name="firstName" value="たなか"> <input type="hidden" id="email" name="email" value="a@gmail.com"> <p> <button type="submit">登録する</button> </p> </div> </form> <div class="u-clearfix c-button-column-2"> <form action="/back" method="post"> <input type="hidden" name="_csrf" value=""> <input type="hidden" id="lastName" name="lastName" value="田中"> <input type="hidden" id="firstName" name="firstName" value="たなか"> <input type="hidden" id="email" name="email" value="a@gmail.com"> <p> <button type="submit" name="return">修正する</button> </p> </form> </div>
IEだとなんで逆にここまで高性能な補完のされ方になるのか気になるところですが、それが仇となってレイアウトが崩れてしまいます。ですからform
タグの入れ子構造を変えてあげなければなりません。
この場合のformタグの構造の解決策1
少しハック的な方法になってしまいますが、form
タグのマークアップの方法を変更して、JavaScriptを用いて、入力している値を登録ボタンを押した時に一緒に値を送るようにします。
このコーディングの組み方だとform
タグの上に入力するためのinput
タグがある場合、その値がうまくpostされません。なので、その値をJavaScriptでhidden
にしているinput
タグのvalue
に入れてあげてpostして解決しました。レイアウトを実現して、戻った時にも値を引き継いでユーザーに負荷をかけないためには裏側で細かい配慮が必要ですね。
<input type="text" placeholder="何かテキスト入れるフォームがある" /> <form action="/regist" method="post" id="js-submit-btn"> <#-- IE9フォームのレイアウトの調整のためhiddenにしておいて入力値をvalueに挿入 --> <input "class='js-form-input' style='display:none;'"/> <input type="hidden" name="_csrf" value=""> <input type="hidden" id="lastName" name="lastName" value="田中"> <input type="hidden" id="firstName" name="firstName" value="たなか"> <input type="hidden" id="email" name="email" value="a@gmail.com"> <p class="c-btn c-btn--primary c-btn--ws u-fl-r"> <button type="submit" class="c-btn--ws c-btn__link-item" name="resistButton">登録する</button> </p> </form> <form action="/back" method="post"> <input type="hidden" name="_csrf" value=""> <input type="hidden" id="lastName" name="lastName" value="田中"> <input type="hidden" id="firstName" name="firstName" value="たなか"> <input type="hidden" id="email" name="email" value="a@gmail.com"> <p class="c-btn-prev c-btn--ws u-fl-l"> <button type="submit" name="return">修正する</button> </p> </form>
IE対応は大変だけど面白い
開発しているサービスでは、IEの利用比率が高く、全体の20%程度のユーザーが使っていることもあって対応することになりました。IEでデバックするのは大変なのでモダンブラウザで開発しているという方が多いかと思いますが、最終的にリリース前に確認のために見てみたら、愕然とした。。ということもあるかと思います。
あらかじめブラウザごとの違いを認識しながらコーディングをしておくと最終的に修正する項目が少なくて済みますので、自分の中でIE対策のTipsを貯めて置きたいですよね。
今回はform
タグの例を元に、モダンブラウザとIEでのレイアウトや補完されるDOMの違いについてご紹介しました。
プログラミングやコーディングで悩んだときに相談できるサイトについてこちらにまとめてみました。
1日悩んでしまうのであれば、自分で調べつつ質問をしておいて回答がきたら参考にするというのも手です。
特にクライアントワークだと時間も限られているので、おすすめします。