♪これもIE、あれもIE、たぶんIE、きっとIE (c) 松坂慶子

<!--[if ie]>などのコンディショナル・コメントをIE11のエミュレーションでも適用させる方法

IE11のコンディショナル・コメントをめぐる挙動は、4/8付の更新で修正されたようです。 例えば、F12のエミュレーションで、ドキュメント・モードでIE9を選んだ場合には、バージョン・ベクターも9となって、<!--[if ie 9]>が適用されるようになっています。

IE11のバージョン:11.0.9600.17041(更新バージョン:11.0.7)で確認。

したがって、最早、以下に掲げたX-UA-Compatibleを付与するなどの手順を踏む必要はありません。

MS独自実装のコンディショナル・コメントは、IE10からもうサポートしなくなったよとすでにMSからアナウンスされている。 実際にIE11では、ドキュメント・モードをIE9とかにしても<--[if ie 9]>といったコンディショナル・コメントは無視される。 だから、コンディショナル・コメントが適用された状態での確認ができず、ちょっと不便な思いをしていたが、そんなものだとも思っていた。

しかしながら、先だって、IE11(IE10も?)のエミュレーションモードでrespond.jsやhtml5.jsが効かない場合の解消法|オレのWEBPADという記事に出会い、追試してみたら、確かに特定の条件下では、IE11でもコンディショナル・コメントが効く場合があるつーじゃないですかw テストケース

その追試結果をまとめると…

  • IE11は<!--[if ie]>などのコンディショナル・コメントは基本的に無視する
  • IE11のF12を開いて、エミュレーションでドキュメント・モードをIE9(以下)に変更して表示させた場合でも、<!--[if lte ie 9]>などの指定は反映されない
  • しかし、これは実はコメントとして無視されたわけではなく<!--[if ie]>だと反映される。 さらに、<!--[if ie 11]>といった指定が反映される
  • つまり、IE11の場合、エミュレーションでIE9とかにしてもバージョン・ベクターは「11」のまま、ということである(!)
  • ただし、<!--[if ie 11]>と明示していても、IE11のスタンダードモードでは、やはり無視される
  • 他方で、そんなIE11でも<meta http-equiv="x-ua-compatible" content="IE=EmulateIE9" />といった指定があった場合には、<!--[if ie 11]>の方ではなく、X-UA-Compatibleで指定されたバージョンとしてのコンディショナルコメント(例:<!--[if lte ie 9]>)が反映される

という、かなりややこしい振る舞いをすることがわかったorz

余談になるが、コンディショナル・コメントはIE9の時もapplication/xhtml+xmlとtext/htmlでは振る舞いが異なるということがあった。 IE11はIEであってIEじゃないと言いながらも、こんなところではやっぱりこれもIEだったのね、つーかorz

コンディショナル・コメントをIE11のエミュレーションでも適用させる最終解

さて、件の記事の中で、

他に良い方法がありませんか

あれば教えて欲しいですね。。。

ということだったので、ここまでの検証結果を踏まえて、


<!--[if (lt ie 9)|(ie 11)]>
(IE8以下用の処理)
<![endif]-->

とORで併記しておけば、IE11のエミュレーションでもコンディショナル・コメントが適用された状態で確認できる旨をツイッターでお知らせした。

なお、先述したが、IE11がコンディショナル・コメントを解釈するようになるのはエミュレーションでドキュメント・モードをIE9以下にしたときだけなので、IE11のスタンダード・モード(さらにIE10のエミュレーションも)の際にはコンディショナル・コメントの指定は一切影響しない。

しかし、実はこの方法には、大きな欠点がある。

コンディショナル・コメントによる振り分けが1つだけならば、この方法でOKなのだが、例えば、


<!--[if (ie 9)|(ie 11)]>
(IE9用の処理)
<![endif]-->
<!--[if (lt ie 9)|(ie 11)]>
(IE8以下用の処理)
<![endif]-->

といった具合に、IEのバージョンによって細かく振り分けるような指定をしている場合には、IE11のIE9エミュレーションで表示などを確認しようとしても、IE8以下用の処理が同時に適用されてしまう。 逆に、IE8エミュレーションで確認しようとした場合も、IE9用の処理が同時に適用されてしまう。

自分で解答を示しておいてなんだがw、これでは何とも使い勝手が悪い。

しかも、IE12がどうなるかわからないけど、そのときに再び改修しなきゃいけなくなる可能性もある。

そこで、IE11のもう一方の振る舞い、つまりX-UA-Compatibleがあったときの振る舞いを利用して表示確認できないものか、と別のアプローチで考えてみたのが以下の方法。

X-UA-Compatibleヘッダは、そもそもは新しいIEを過去のIEの振る舞いにあわせて表示させる目的でMSは導入したのだと思うが、ここでの使い方は、その逆、というか、いわば逆手に取ったもの。

サーバー側でUAをみて、/MSIE\s[5-9]/の文字列があった場合にだけX-UA-Compatibleヘッダを出力して送信する、という方法で、要するに、今回の主目的であるところの開発時などで意図的に互換表示させたいときだけIE11の挙動を変更させる、というわけ。

コードはPHPなら例えばこんな感じ。


<?php
if(preg_match('/MSIE\s([5-9])/', $_SERVER['HTTP_USER_AGENT'], $ua)) {
    header('X-UA-Compatible: IE=EmulateIE'.$ua[1]);
}
?>

…これだけw。 これをファイル化してすべてのHTML文書にinclude()しちゃうなりすれば、それでOK。 そして、コンディショナル・コメントの方は、<--[if ie 9]>などこれまでのままでOK。

で、IE11での表示確認方法は、例えば、

  • IE9での表示を確認する場合は、
    1. ドキュメント・モード:「9」
    2. ユーザー・エージェント:「Internet Explorer 9」
    を選択
  • 同様にIE8での表示を確認する場合は、
    1. ドキュメント・モード:「8」
    2. ユーザー・エージェント:「Internet Explorer 8」
    を選択する

といった具合。 注意事項としては、ドキュメント・モードにあわせて、必ずユーザー・エージェントの文字列も変更すること。 テストケースその2

ちなみに、実際のIE9やIE8でアクセスした場合もX-UA-Compatibleヘッダは送信されることになるが、これはそれぞれのスタンダードモードで表示しろと指定しているにすぎず、ヘッダが付与されたことによる影響はない(はず)。 また、IE12以降も互換表示におけるコンディショナル・コメントがサポートされ続ける限りはこのまま使い続けられる。

さらにちなみに、PHPで出力を振り分けることができるんだったら何もコンディショナル・コメントを使う必要はそもそもなかったりもするのだが、UAの文字列による判別は不確実なところがあるのでその保険という意味でもコンディショナル・コメントを残しておく意味はなくはないはずだ…ということでひとつご理解をw

あと、ローカルで確認したい場合にはどうすりゃいいのかって? それは、PHPやApacheをWindowsにインストールすれば万事解決ですw

つーことで「UAの文字列に/MSIE\s[5-9]/があるときだけX-UA-Compatibleヘッダを出力する」が、愛の水中花、あいのすいちゅうか、IEのすいちゅうか、…IEの最終解!(苦しいなorz

"♪これもIE、あれもIE、たぶんIE、きっとIE (c) 松坂慶子"へのTwitter上でのコメントやRT

9件のツイートがあります。

ツイート 1

ツイート 2

ツイート 3

ツイート 4

ツイート 5

ツイート 6

ツイート 7

ツイート 8

ツイート 9