【问题标题】:Detecting IE11 using CSS Capability/Feature Detection使用 CSS Capability/Feature Detection 检测 IE11
【发布时间】:2013-09-25 06:32:56
【问题描述】:

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

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

我想对 IE11 做同样的事情,但我假设 IE11 也将​​支持所有 IE10 样式。谁能帮我确定我可以用来区分这两者的仅限 IE11 的样式或功能?

额外信息

  • 我不想使用用户代理类型检测,因为它参差不齐,而且可以更改,而且我认为我已经读到 IE11 故意试图隐藏它是 Internet Explorer 的事实。
  • 作为 IE10 功能测试工作原理的示例,我使用 JsFiddle(不是我的)作为测试的基础。
  • 我也期待很多“这是一个坏主意......”的答案。我对此的一个需求是 IE10 声称它支持某些东西,但它的实现非常糟糕,我希望能够区分 IE10 和 IE11+,以便将来继续使用基于能力的检测方法。
  • 此测试与 Modernizr 测试相结合,该测试只会使某些功能“回退”到不那么迷人的行为。我们不是在谈论关键功能。

另外,我已经在使用 Modernizr,但在这里没有帮助。我需要帮助来解决我明确提出的问题。

【问题讨论】:

  • 为什么需要知道用户使用的是什么浏览器?特征检测/css前缀/css条件还不够吗?
  • 我忘了说我们需要检测浏览器是有原因的,但能力测试并没有帮助。我们的问题之一是 IE10 说它支持某些东西,但做的不是很好。
  • @David-SkyMesh - 不。不幸的是,这还不够。我希望它是,但它不是。
  • @Evildonald 你没有回答为什么你需要知道——特别是。这很可能是一个 XY 问题。 (即:您要求使用 X 提供帮助 - 检测 IE11 - 我们何时可以回答不同的问题 Y - 如何与更多浏览器兼容,包括 IE11 for TASK Z)
  • 我有一个 .js 可以检测浏览器版本,它说 ie11 是一个 firefox。发生了什么事,即开发人员!

标签: internet-explorer-11 sample feature-detection


【解决方案1】:

这是 2017 年的答案,您可能只关心区分 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,而all other relevant browser/version combinations 支持。

【讨论】:

  • 我理解这种方法,但从未见过以前使用过的“(旧:ie)”属性和值。有这个参考吗?
  • @GrowthMindset 没有这样的属性或值。由于“支持”规则的性质,它非常独特地必须接受浏览器可能认为无意义的 CSS。如果没有支持不可用的可能性,您就不能制定促进测试支持或不支持某事物的规则。知道了这一点,我发现使用'old: ie' 比记住一些实际属性更简单,特别是因为它支持这里使用的'supports' at 规则,而不是赋予规则的实际参数。它使阅读和摸索变得容易。本质上是:“supports not old ie {
【解决方案2】:

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

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

【讨论】:

  • 类似的东西也可能是一个 sass mixin!
  • 是只针对 IE11 还是针对 Edge?
  • 针对 IE10 和 IE11,但不针对边缘。
  • 这条评论保存了我的 a*s。我只想在 IE 上更改 css 的特定宽度,而不是在其他浏览器上。这对我有用:@media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) and (max-width: 960px;) { /* add your IE10-IE11 css here */ } 这不会影响边缘,正是我想要的。
【解决方案3】:

我在 IE11 中使用 Gravity Form (WordPress) 时遇到了同样的问题。表单的列样式“display: inline-grid”破坏了布局;应用上面的答案解决了差异!

@media all and (-ms-high-contrast:none){
  *::-ms-backdrop, .gfmc-column { display: inline-block;} /* IE11 */
}

【讨论】:

    【解决方案4】:

    您可以正常编写 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;
        }
    }
    

    【讨论】:

    • 这可行并且是一个很好的解决方案,但给出的推理不正确。 IE11 根本不支持@supports,因此它会忽略@supports 块中的任何内容。因此,您可以在@supports 条件中添加任何内容(例如@supports (display: block)),IE11 仍然会跳过它。
    • 这就是我所说的“IE 11 将忽略”的意思,但你是对的,这并不完全清楚。我已经更新了答案,更清楚地表明 IE 不支持 @supports。
    【解决方案5】:

    这似乎有效:

    @media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {  
       /* IE10+ specific styles go here */  
    }
    

    https://www.limecanvas.com/css-hacks-for-targeting-ie-10-and-above/

    【讨论】:

    • 这个不能区分 ie10 和 ie11 但如果你不介意也检测 ie10 那么你就可以用这个了。
    【解决方案6】:

    鉴于不断发展的线程,我更新了以下内容:

    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,as Edge does not support -ms-high-contrast

    IE 11

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

    Javascript 替代品

    Modernizr

    Modernizr 在页面加载时快速运行以检测功能;然后 使用结果创建一个 JavaScript 对象,并将类添加到 html元素

    User agent selection

    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;
    }
    

    脚注

    如果可能,请在没有黑客攻击的情况下识别并修复任何问题。支持progressive enhancementgraceful degradation。然而,这是一个“理想世界”的场景,并不总是可以实现,因此,以上内容应该有助于提供一些不错的选择。


    署名/必读

    【讨论】:

    • 这应该是真正的答案。好详细!
    • 只有 IE10 对我不起作用。反斜杠 9 不会删除 IE11。我正在尝试为 IE 10 显示一个 div,但不是为 IE11...它仍然显示在 IE 11...
    • 对我来说,第二个 IE10 选项适用于 IE11:@media all and (-ms-high-contrast: none), (-ms-high-contrast: active) { .relevant_selectors_for_situation {property:value;} } 我在 mediacurrent.com/blog/… 中找到了它
    • 阅读完所有这些后,我认为-ms-high-contrast: active 可能是要避免的,因为根据 MS 规范,您实际上将使用 IE 10/11 规则针对 Edge 中的高对比度主题用户。在页面中,此答案链接到有关 -ms-high-contrast 的链接,它实际上表示不再支持 -ms-high-contrast: none 值。我认为没有人提到这一点,因为大多数人没有启用高对比度模式,而且大多数人不使用 Edge。但是,仍然有某人拥有这种配置,这对他们来说可能并不酷。
    • 这让我的眼睛流血......让我讨厌成为一名开发人员......不应该这么难。
    【解决方案7】:

    所以我最终找到了自己的解决方案。

    在搜索Microsoft documentation 之后,我设法找到了一个新的IE11 风格msTextCombineHorizontal

    在我的测试中,我检查 IE10 样式,如果它们是正匹配,那么我检查仅 IE11 样式。如果我找到了,那么它是 IE11+,如果我没有找到,那么它就是 IE10。

    代码示例: Detect IE10 and IE11 by CSS Capability Testing (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。

    我正在将此测试用于回退行为。回退行为只是不那么迷人的样式,它没有减少功能。

    【讨论】:

    • 如果有人要-1这个答案,请至少有礼貌地以技术的理由承认它。你可能不同意它..但它是正确的并且有效。
    • 如何知道这段代码在IE12、IE13等下是否会产生正确的结果?
    • 你为什么用这个方法而不是if (document.documentMode === 11) { ... }?当然,除非您想在 @supports 规则中使用 CSS 属性(顺便说一下,IE 尚不支持)。
    • 如果您的 body 标签中有现有的类,这将覆盖它们。这是非常小的修复:jsfiddle.net/jmjpro/njvr1jq2/1.
    • 另外,你会想用 css 隐藏 ieVersion 元素:#ieVersion { display: none }
    【解决方案8】:

    你可以试试这个:

    if(document.documentMode) {
      document.documentElement.className+=' ie'+document.documentMode;
    }
    

    【讨论】:

      【解决方案9】:

      退一步:为什么你甚至试图检测“Internet Explorer”而不是“我的网站需要做 X,这个浏览器是否支持该功能?如果支持,好的浏览器。如果没有,那么我应该警告用户” .

      您应该拨打http://modernizr.com/ 而不是继续您正在做的事情。

      【讨论】:

      • 感谢您提供替代解决方案,但我已经在使用 Modernizr,而 IE10 错误地表示了它的功能。
      • 我假设您知道哪些,并且已经向 Modernizr 提交了问题,以便他们可以为该特定浏览器添加更多 Modernizrs 检查? (如果没有,您应该这样做。如果您发现影响数十万开发人员的东西,将其提交给负责 shim 的人员是唯一正确的做法)
      • 对于我们这些编写面向用户的代码的人来说,您通常现在需要一个答案,而不是在第三方库中提交的错误和那里的补丁。也就是说,您希望他们改进 Modernizr 很好,但这里不适合。
      • 我认为检测真正的浏览器本身是一个合理的目标。
      • @DeanJ 当然,对于这些问题,其他人也会提供答案。这并没有降低获得类似这样的回应的重要性,这些回应告诉你思考你在做什么。此外,在回复时,帖子没有任何编辑,也没有提到“我现在需要它才能工作”,所以我没有理由假设他们不想要现实检查。
      【解决方案10】:

      试试这个:

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

      【讨论】:

        【解决方案11】:

        检测 IE 及其版本实际上非常容易,至少非常直观:

        var uA = navigator.userAgent;
        var browser = null;
        var ieVersion = null;
        
        if (uA.indexOf('MSIE 6') >= 0) {
            browser = 'IE';
            ieVersion = 6;
        }
        if (uA.indexOf('MSIE 7') >= 0) {
            browser = 'IE';
            ieVersion = 7;
        }
        if (document.documentMode) { // as of IE8
            browser = 'IE';
            ieVersion = document.documentMode;
        }
        

        这样,您还可以在兼容模式/视图中捕获高 IE 版本。接下来是分配条件类的问题:

        var htmlTag = document.documentElement;
        if (browser == 'IE' && ieVersion <= 11)
            htmlTag.className += ' ie11-';
        

        【讨论】:

          【解决方案12】:

          使用以下属性:

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

          【讨论】:

            【解决方案13】:

            可以使用js,在html中添加一个类,保持conditional comments的标准:

              var ua = navigator.userAgent,
                  doc = document.documentElement;
            
              if ((ua.match(/MSIE 10.0/i))) {
                doc.className = doc.className + " ie10";
            
              } else if((ua.match(/rv:11.0/i))){
                doc.className = doc.className + " ie11";
              }
            

            或者使用类似 bowser 的库:

            https://github.com/ded/bowser

            或用于特征检测的modernizr:

            http://modernizr.com/

            【讨论】:

              【解决方案14】:

              看看这篇文章: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 我们可以这样做:

              FIDDLE

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

              【讨论】:

              • 这会在 Firefox 11 中中断(即使它现在不受支持,但这很重要)。它的用户代理字符串中还有rv:11.0
              【解决方案15】:

              如果您使用的是Modernizr - 那么您可以轻松区分 IE10 和 IE11。

              IE10 不支持pointer-events 属性。 IE11 可以。 (caniuse)

              现在,根据 Modernizr 插入的类,您可以拥有以下 CSS:

              .class
              { 
                 /* for IE11 */
              }
              
              .no-pointerevents .class
              { 
                 /* for IE10 */
              }
              

              【讨论】:

                【解决方案16】:

                这对我有用

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

                然后在css文件中以

                为前缀
                body.ie11 #some-other-div
                

                这个浏览器什么时候死?

                【讨论】:

                  【解决方案17】:

                  也许 Layout Engine v0.7.0 是适合您情况的一个很好的解决方案。它使用浏览器特征检测,不仅可以检测IE11和IE10,还可以检测IE9、IE8和IE7。它还检测其他流行的浏览器,包括一些移动浏览器。它在 html 标签中添加了一个类,易于使用,并且在一些相当深入的测试下表现良好。

                  http://mattstow.com/layout-engine.html

                  【讨论】:

                    【解决方案18】:

                    你应该使用 Modernizr,它会在 body 标签中添加一个类。

                    还有:

                    function getIeVersion()
                    {
                      var rv = -1;
                      if (navigator.appName == 'Microsoft Internet Explorer')
                      {
                        var ua = navigator.userAgent;
                        var re  = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
                        if (re.exec(ua) != null)
                          rv = parseFloat( RegExp.$1 );
                      }
                      else if (navigator.appName == 'Netscape')
                      {
                        var ua = navigator.userAgent;
                        var re  = new RegExp("Trident/.*rv:([0-9]{1,}[\.0-9]{0,})");
                        if (re.exec(ua) != null)
                          rv = parseFloat( RegExp.$1 );
                      }
                      return rv;
                    }
                    

                    请注意,IE11 仍处于预览阶段,用户代理可能会在发布前更改。

                    IE 11 的用户代理字符串目前是这个:

                    Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv 11.0) like Gecko
                    

                    这意味着您可以简单地测试版本 11.xx,

                    var isIE11 = !!navigator.userAgent.match(/Trident.*rv 11\./)
                    

                    【讨论】:

                    • 感谢 Neo,但我已经在我的 body 标签中添加了一个类并使用了 Modernizr。我正在寻找一种在不使用不可信的用户代理的情况下区分 IE10 和 IE11 的方法。
                    • rv 11 中缺少冒号。var isIE11 = !!navigator.userAgent.match(/Trident.*rv:11\./)
                    猜你喜欢
                    • 2014-01-12
                    • 2013-07-28
                    • 2013-12-04
                    • 2014-02-07
                    • 2014-02-24
                    • 1970-01-01
                    • 2020-09-16
                    • 1970-01-01
                    • 2016-04-20
                    相关资源
                    最近更新 更多