##続編
続編(?)を投稿しました。
##はじめに
2017年07月時点の内容であり、
2017年07月時点のhackです。
ご利用は自己責任の上でお願い致します。
##結論
素人の結論を先に記載しておきます。
( demoはこちらより確認くださいませ )
/* IE11 */ _:-ms-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 {}
##Edge ( EdgeHTML )
ちなみに、
IE11未満は未実装
IE11はベンダープレフィックスが必要
Edgeはベンダープレフィックスが不要
ですので、素人判断ですが、
Edgeの css hack は以下がよいのかな、と思う次第です。
_:-ms-lang(x)::backdrop, .selector {}