Edited at

css hacks for IE11 ( & Edge )


続編

続編(?)を投稿しました。


はじめに

2017年07月時点のhackです。

ご利用は自己責任の上でお願い致します。


結論

素人の結論を先に記載しておきます。

( demoはこちらより確認くださいませ )

/* IE11 */ _:lang(x)::-ms-backdrop, .selector {}

/* Edge */ _:-ms-lang(x)::backdrop, .selector {}


-ms-high-contrast & -ms-backdrop

@media all and (-ms-high-contrast:none) {

*::-ms-backdrop, .selector {
color: blue;
}
}

IE11の css hack を検索すると、検索結果の上部に出てくる上記のhackですが、

当時はそういうもの、として、あまり深く考えていませんでした。

上記は二つの部位で構成されていますが、各々どういう役割でしょうか。

@media all and (-ms-high-contrast:none) {}

-ms-high-contrastのhackはIE10以上用のhackとして有名(?)でした。

なのでIE9以下を切る役割なのでしょう。

*::-ms-backdrop, .selector {}

では上記の役割は?


-ms-backdrop

MSDNを見ると中段の表に以下が記載されていました。

( MDNに飛ばされてしまい、現在は見れません )

IE11未満は未実装

IE11はベンダープレフィックスが必要

Edgeはベンダープレフィックスが不要

んっ!?、なら以下だけでよくね?

*::-ms-backdrop, .selector {}

IE11反応あり、Edge反応なし、Chrome反応なし、Firefox反応なし、Safari(iOS)反応なし。

(・∀・)イイ!!

念の為、

IE11のドキュメントモードを変更して旧IEの反応も見ていきます。

IE10とIE9とIE8までは反応ないのですが、

IE7とIE5は、カンマの実装方法が違うのか、反応します。

(・A・)イクナイ!!


-ms-high-contrast & -ms-backdrop

つまり、

@media all and (-ms-high-contrast:none) {} => IE11,IE10

*::-ms-backdrop, .selector {} => IE11,IE7,IE5

これを同時に指定することで、IE11のみが反応する、という状態のようです。


media queries & -ms-backdrop

しかし、

IE7以下が反応しなければよいわけですから、

@media all and (-ms-high-contrast:none) {}

の箇所は検討の余地がありそうです。

そもそも、

-ms-high-contrastどうこう以前に、

IEのメディアクエリの多くの実装はIE9からです。

IE7以下を切る役割であれば、

@media all and (-ms-high-contrast:none) {}

などとする必要はなく、

レスポンシブ時によくお世話になる、

@media all and (min-width:hoge) {}

@media all and (man-width:hoge) {}

などを利用すればよいだけなのかと...

@media all and (min-width:0px) {

*::-ms-backdrop, .selector {
color: blue;
}
}


-ms-backdrop & root

ただ、出来れば、

@media@support を使用せず、

ワンライナー的にいける方法が欲しいところです。

IE7以下が反応しないhackで、すぐ思い浮かぶのは :root hack です。

:root はIE8以下未実装なのでIE7,IE5は反応しません。

ただ、詳細度が変化してしまうのが玉にきずです。

*::-ms-backdrop, :root .selector {}


-ms-backdrop & -ms-lang

次に思い浮かんだのは、

IE10以上用hackである_:-ms-lang(x),の利用です。

これと組み合わせてみたところ、うまくいきました。

詳細度の変動もないはずです...

*::-ms-backdrop, _:-ms-lang(x), .selector {}

ところで、

先頭の *_ とはなんでしょうか...


asterisk

*全称セレクタだと思いますが、

以下が*::-ms-backdrop,の自分なりの解釈です。

例えば、

* { color: blue; }

こうすると全要素の文字が青くなります。

*::after { color: blue; }

こうすると全要素の::afterの疑似要素の文字が青くなります。

ということは、

*::backdrop { color: blue; }

こうすると全要素の::backdropの疑似要素の文字が青くなります。

( ::backdropがどんな要素なのかは知りませんが... )

*::-ms-backdrop { color: blue; }

こうすると全要素の::-ms-backdropの疑似要素の文字が青くなります。

( ::-ms-backdropが実装されたブラウザであるIE11のみ )

また、

a, p { color: blue; }

こうするとa要素とp要素の文字が青くなります。

a::after, p { color: blue; }

こうするとa要素の::afterの疑似要素とp要素の文字が青くなります。

*::after, p { color: blue; }

こうすると全要素の::afterの疑似要素とp要素の文字が青くなります。

この時、

::afterの疑似要素は絶対使用しない、と、取り決めしたとします、その場合、

*::after部分に反応する要素は絶対ないので、

*::after, p { color: blue; }p { color: blue; } は同じ効果になります。

では、

*::-ms-backdrop, p { color: blue; }

の場合はどうでしょうか。

::-ms-backdropの疑似要素、使いますか?、使わないよね?、使わないなら、

*::-ms-backdrop, p { color: blue; }p { color: blue; } は同じ効果だよね。

ということは、

*::-ms-backdrop, .selector {}.selector {} は同じ効果だよね、と、なり、

その際、

他のモダンブラウザにとっては、

-ms-backdropという未定義のキーワードがあるため、

*::-ms-backdrop, .selector {}

というスタイル規則(or規則セット)自体が無視され、

結果、-ms-backdropが実装されているIE11だけが反応する、

と、いうことなのだろうと思われます。

つまり、

*::-ms-backdrop, .selector {}は、

-ms-backdropの疑似要素を使用しない、

という暗黙の約束事の上に成り立っているhackなのではないかと。


underscore

_ とは何でしょうか。

正直はっきり分かりません...

The W3C CSS Validation Serviceで、

_ { color: blue; }を検証してもエラーやワーニングは出ません。

なので _ を使用しては駄目ということはないようです。

次にW3Cの仕様書を探してみます。

Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification

4 Syntax and basic data types

4.1.2.1 Vendor-specific extensions

上記によると、

  -_ を識別子の先頭に使用可能、

  -_ で始まるキーワードやプロパティはベンダー固有の拡張用として予約、

  -_ の予約は将来において保証、

ということのようです。

また、

CSS Syntax Module Level 3

10.7. Experimental implementations

CSS3にもCSS2.1の上記の予約の件が記載されています。

つまり、

_ 一文字ではセレクタなどになることは将来的にもないし、

_ 一文字でベンダープレフィックスとするブラウザも普通に考えればないでしょう。

なので、

_ にマッチするものは一切ない、

ということなのだろうと思われます。


underscore + -ms-backdrop & -ms-lang

ですので、素人判断ですが、

IE11の css hack は以下がよいのかな、と思う次第です。

_::-ms-backdrop, _:-ms-lang(x), .selector {}

( hack的な意味合いで ) 短縮して以下は如何でしょうか。

_:-ms-lang(x)::-ms-backdrop, .selector {}

( hack的な意味合いで ) -ms-は1個でよいので、さらに短縮して以下は如何でしょうか。

_:lang(x)::-ms-backdrop, .selector {}


Edge

ちなみに、

IE11未満は未実装

IE11はベンダープレフィックスが必要

Edgeはベンダープレフィックスが不要

ですので、素人判断ですが、

Edgeの css hack は以下がよいのかな、と思う次第です。

_:-ms-lang(x)::backdrop, .selector {}