使用CSS能力/特性检测来检测IE版本

100

IE10+不再支持使用浏览器检测标签来识别浏览器。

为了检测IE10,我使用JavaScript和一种能力测试技术来检测是否定义了某些带有ms前缀的样式,例如msTouchActionmsWrapFlow

我想对IE11做同样的事情,但我假设所有的IE10样式在IE11中也会得到支持。有人可以帮我识别只能用于IE11的样式或能力,以便将两者区分开来吗?

额外信息

  • 我不想使用用户代理类型检测,因为它很容易出错,而且可以更改,另外我认为我读过IE11有意试图隐藏它是Internet Explorer的事实。
  • 关于如何进行IE10能力测试的示例,我使用了这个JsFiddle(不是我的),作为我的测试基础。
  • 同时,我预计会有很多答案是“这是一个坏主意……”。我之所以需要这样做,是因为IE10声称支持某些功能,但实现非常糟糕,我想能够区分IE10和IE11+,以便在未来使用基于能力的检测方法。
  • 这个测试与一个Modernizr测试结合使用,它将简单地使一些功能“回退”到不太显眼的行为。我们并不谈论关键功能。

我已经在使用Modernizr了,但它在这里没有帮助。


3
为什么需要知道用户使用的浏览器?特性检测/ CSS前缀 / CSS条件语句不足以满足吗? - David-SkyMesh
4
我忘了提到我们需要检测浏览器的原因,这是能力测试无法解决的。我们面临的问题之一是IE10会声明支持某项功能,但实际表现并不好。 - dano
2
@David-SkyMesh - 不好意思,这还不够。虽然我希望它足够了,但事实并非如此。 - dano
1
@Evildonald,你没有回答为什么需要知道这个问题的具体原因。这可能是一个XY问题(即:当我们可以回答不同的问题Y - 如何兼容更多浏览器包括IE11,以完成任务Z时,你正在寻求帮助解决X - 检测IE11)。 - David-SkyMesh
1
我有一个可以检测浏览器版本的 .js 文件,但它却将 ie11 识别为 firefox。这是怎么回事,ie 开发者! - Daniel Cheung
显示剩余3条评论
18个回答

177

考虑到不断发展的安全威胁,我已经更新了以下内容:

IE 6

* html .ie6 {property:value;}

或者

.ie6 { _property:value;}

IE 7

*+html .ie7 {property:value;}

或者

*:first-child+html .ie7 {property:value;}

IE 6 和 7

@media screen\9 {
    .ie67 {property:value;}
}

或者

.ie67 { *property:value;}

或者

.ie67 { #property:value;}

IE 6, 7和8

@media \0screen\,screen\9 {
    .ie678 {property:value;}
}

IE 8

html>/**/body .ie8 {property:value;}

或者

@media \0screen {
    .ie8 {property:value;}
}

只支持IE 8标准模式

.ie8 { property /*\**/: value\9 }

IE 8、9和10

@media screen\0 {
    .ie8910 {property:value;}
}

仅适用于IE 9

@media screen and (min-width:0\0) and (min-resolution: .001dpcm) { 
 // IE9 CSS
 .ie9{property:value;}
}

IE 9 及以上版本

@media screen and (min-width:0\0) and (min-resolution: +72dpi) {
  // IE9+ CSS
  .ie9up{property:value;}
}

IE 9和10

@media screen and (min-width:0) {
    .ie910{property:value;}
}

仅适用于IE 10

_:-ms-lang(x), .ie10 { property:value\9; }

IE 10及以上版本

_:-ms-lang(x), .ie10up { property:value; }

或者

@media all and (-ms-high-contrast: none), (-ms-high-contrast: active) {
   .ie10up{property:value;}
}

-ms-high-contrast 的使用意味着 MS Edge 不会被针对,因为 Edge 不支持 -ms-high-contrast

IE 11

_:-ms-fullscreen, :root .ie11up { property:value; }

Javascript的替代方案

Modernizr

Modernizr在页面加载时快速运行以检测特性;然后它会创建一个JavaScript对象来保存检测结果,并将类添加到html元素中。

用户代理选择

Javascript:

var b = document.documentElement;
        b.setAttribute('data-useragent',  navigator.userAgent);
        b.setAttribute('data-platform', navigator.platform );
        b.className += ((!!('ontouchstart' in window) || !!('onmsgesturechange' in window))?' touch':'');

将以下内容添加到 html 元素中:
data-useragent='Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C)'
data-platform='Win32'

允许非常精准的CSS选择器,例如:

html[data-useragent*='Chrome/13.0'] .nav{
    background:url(img/radial_grad.png) center bottom no-repeat;
}

脚注

如果可能的话,识别和修复任何问题而不使用hack手段。支持渐进增强优雅降级。然而,这是一个“理想世界”的情况,不总是可得到的,因此以上内容应该能够提供一些好的选项。


归属 / 必读


IE10 对我来说无法工作。反斜杠-9 无法移除 IE11。我正在尝试在 IE10 中显示一个 div,但不在 IE11 中显示... 但它仍然在 IE11 上显示... - Merc
啊,奇怪。大多数属性都能正常工作,但是在IE 11中clip: auto\9;仍然被解释为clip: auto;。不知何故这个属性没有被忽略... - Merc
2
对我来说,第二个IE10选项适用于IE11: .relevant_selectors_for_situation {property:value;} }``` 我在https://www.mediacurrent.com/blog/pro-tip-how-write-conditional-css-ie10-and-11/中找到了它。 - cedricdlb
1
阅读完所有内容后,我认为应该避免使用-ms-high-contrast: active,因为根据微软的规范,您实际上将针对在Edge中使用IE 10/11规则的高对比度主题用户。在此答案链接到的页面中,关于-ms-high-contrast,它实际上说只有-ms-high-contrast: none值不再受支持。我认为没有人提到这一点,因为大多数人没有启用高对比度模式,也没有使用Edge。但仍然有“某些人”拥有这种配置,这对他们来说可能不太好。 - dmatamales
这个答案需要更新,以说明那些规则也影响Edge 12到Edge 18。并且需要注意避免某些配置上会受到破坏的规则,例如高对比度模式允许black-on-whitewhite-on-black的值,但是根据MSDN,这里的CSS选择器将无法为具有该配置的用户提供支持 - 可能可以使用(-ms-high-contrast: none) or not (-ms-high-contrast: none)? - robocat
很棒的答案!您可以更清楚地表明.ie11up是您需要的任何选择器来实际定位元素。另外回答上面的问题:IE11解决方案仅限于影响IE11,例如Edge >=15 - 尚未检查是否影响低版本,如IE10,但我认为不会。 - OZZIE

50

仅针对IE10和IE11(而不是Edge):

@media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {  
   /* add your IE10-IE11 css here */   
}

1
这也可以是一个Sass混合器! - dano
2
这个目标是仅针对IE11还是同样适用于Edge? - Matthew Felgate
2
目标为IE10和IE11,但不支持Edge。 - Jeff Clayton
这个注释救了我的命。我想仅在IE上更改特定宽度的CSS而不影响其他浏览器。这是对我有用的代码: @media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) and (max-width: 960px;) { /* 在此添加您的IE10-IE11 CSS */ } 这不会影响Edge,正是我想要的。 - K. Shaikh

24
所以最后我找到了自己的解决方案。
在搜索了Microsoft文档之后,我成功地找到了一个新的只能用于IE11的样式msTextCombineHorizontal 在我的测试中,我检查IE10样式,如果它们匹配成功,然后我检查只能用于IE11的样式。如果我找到了它,那么它就是IE11+,如果没有找到,那么它就是IE10。 代码示例:通过CSS能力测试检测IE10和IE11(JSFiddle)
 /**
  Target IE 10 with JavaScript and CSS property detection.
  
  # 2013 by Tim Pietrusky
  # timpietrusky.com
 **/

 // IE 10 only CSS properties
 var ie10Styles = [
     'msTouchAction',
     'msWrapFlow',
     'msWrapMargin',
     'msWrapThrough',
     'msOverflowStyle',
     'msScrollChaining',
     'msScrollLimit',
     'msScrollLimitXMin',
     'msScrollLimitYMin',
     'msScrollLimitXMax',
     'msScrollLimitYMax',
     'msScrollRails',
     'msScrollSnapPointsX',
     'msScrollSnapPointsY',
     'msScrollSnapType',
     'msScrollSnapX',
     'msScrollSnapY',
     'msScrollTranslation',
     'msFlexbox',
     'msFlex',
     'msFlexOrder'];

 var ie11Styles = [
     'msTextCombineHorizontal'];

 /*
  * Test all IE only CSS properties
  */
 var d = document;
 var b = d.body;
 var s = b.style;
 var ieVersion = null;
 var property;

 // Test IE10 properties
 for (var i = 0; i < ie10Styles.length; i++) {
     property = ie10Styles[i];

     if (s[property] != undefined) {
         ieVersion = "ie10";
         createEl("IE10 style found: " + property);
     }
 }

 // Test IE11 properties
 for (var i = 0; i < ie11Styles.length; i++) {
     property = ie11Styles[i];

     if (s[property] != undefined) {
         ieVersion = "ie11";
         createEl("IE11 style found: " + property);
     }
 }

 if (ieVersion) {
     b.className = ieVersion;
     $('#versionId').html('Version: ' + ieVersion);
 } else {
     createEl('Not IE10 or 11.');
 }

 /*
  * Just a little helper to create a DOM element
  */
 function createEl(content) {
     el = d.createElement('div');
     el.innerHTML = content;
     b.appendChild(el);
 }

 /*
  * List of IE CSS stuff:
  * http://msdn.microsoft.com/en-us/library/ie/hh869403(v=vs.85).aspx
  */
body {
    font: 1.25em sans-serif;
}
div {
    background: red;
    color:#fff;
    padding: 1em;
}
.ie10 div {
    background: green;
    margin-bottom:.5em;
}
.ie11 div {
    background: purple;
    margin-bottom:.5em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<h1>Detect IE10 and IE11 by CSS Capability Testing</h1>


<h2 id="versionId"></h2>

当我发现更多样式时,我将更新代码示例。

注意:这几乎肯定会将IE12和IE13识别为“IE11”,因为这些样式很可能会继承下去。随着新版本的推出,我将添加更多测试,并希望能够再次依靠Modernizr。

我正在使用此测试以进行备用行为。备用行为只是较少引人注目的样式,它没有降低功能性。


9
如果有人要点踩这个回答,请至少有点基本的礼貌并给出一个技术方面的理由。你可能不同意,但它是正确的,而且可以运作。 - dano
7
您如何知道这段代码是否能在IE12、IE13等浏览器中产生正确的结果? - Evgeny
6
为什么你使用这种方法而不是 if (document.documentMode === 11) { ... } 呢?除非你想在 @supports at-rule 中使用 CSS 属性(顺便说一下,这在 IE 中还没有得到支持)。 - Rob W
1
如果您在body标签中有现有的类,这将覆盖它们。这是非常小的修复:http://jsfiddle.net/jmjpro/njvr1jq2/1/. - jbustamovej
1
另外,您需要使用CSS隐藏ieVersion元素:#ieVersion { display: none }。 - jbustamovej
显示剩余3条评论

21

这个不区分ie10和ie11,但如果你不介意也检测ie10,那么这个就可以了。 - Jeff Clayton

13

这里是一个2017年之后的答案,您可能只关心如何区分<=IE11和>IE11(“Edge”):

@supports not (old: ie) { /* code for not old IE here */ }

更具体的例子:

body:before { content: 'old ie'; }
/**/@supports not (old: ie) {
body:before { content: 'not old ie'; }
/**/}

这个可以工作是因为IE11实际上不支持@supports,而所有其他相关的浏览器/版本组合都支持。


我理解这种方法,但从未见过“(old: ie)”属性和值的使用。是否有相关参考资料? - Growth Mindset
1
@GrowthMindset 没有这样的属性或值。由于“supports”规则的性质,它必须接受浏览器可能认为是无意义的CSS,这在相当大程度上是独特的。你不能有一个规则来测试支持或不支持某个东西,而没有可能出现不支持的情况。基于此,我发现使用“old: ie”比记住某个实际属性更简单,特别是因为这里使用的是“supports”规则的支持,而不是规则给定的实际参数。这使得阅读和理解变得容易。本质上:“supports not old ie {”。 - Jan Kyu Peblik

9
您可以像平常一样编写IE11代码,然后使用@supports检查IE11不支持的属性,例如grid-area: auto
然后,您可以在此范围内编写现代浏览器样式。IE不支持@supports规则,并将使用原始样式,而这些样式将在支持@supports的现代浏览器中被覆盖。
.my-class {
// IE the background will be red
background: red;

   // Modern browsers the background will be blue
    @supports (grid-area: auto) {
      background: blue;
    }
}

2
这个方法可行且是一个好的解决方案,但给出的理由是不正确的。IE11根本不支持@supports,因此它会忽略@supports块中的任何内容。因此,您可以在@supports条件语句中放置任何内容(例如@supports(display:block)),IE11仍将跳过它。 - CodeBiker
1
这就是我所说的“IE 11将忽略”的意思,但你是对的,那并不完全清楚。我已经更新了答案,更明确地表明IE不支持@supports。 - Antfish

4

试试这个:

/*------Specific style for IE11---------*/
 _:-ms-fullscreen, :root 
 .legend 
{ 
  line-height: 1.5em;
  position: relative;
  top: -1.1em;   
}

4

这对我有效

if(navigator.userAgent.match(/Trident.*rv:11\./)) {
    $('body').addClass('ie11');
}

然后在 CSS 文件中,以以下内容为前缀:

body.ie11 #some-other-div

这个浏览器何时可以退出历史舞台呢?

3
请看这篇文章:CSS: User Agent Selectors 基本上,当你使用这个脚本时:
var b = document.documentElement;
b.setAttribute('data-useragent',  navigator.userAgent);
b.setAttribute('data-platform', navigator.platform );
b.className += ((!!('ontouchstart' in window) || !!('onmsgesturechange' in window))?' touch':'');

现在,您可以使用CSS来针对任何浏览器/版本进行定位。

因此,对于IE11,我们可以这样做:

查看代码

html[data-useragent*='rv:11.0']
{
    color: green;
}

1
这会在Firefox 11中出现错误(即使它现在不受支持,也很重要)。它的用户代理字符串中还有rv:11.0 - PhistucK

3

请使用以下属性:

  • !!window.MSInputMethodContext
  • !!document.msFullscreenEnabled

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接