Обнаружение IE11 с помощью CSS Capability/Feature Detection

IE10+ больше не поддерживает теги обнаружения браузера для идентификации браузера.

Для обнаружения IE10 я использую JavaScript и технику тестирования возможностей для обнаружения определенных ms определены префиксные стили, такие как msTouchAction а также msWrapFlow,

Я хочу сделать то же самое для IE11, но я предполагаю, что все стили IE10 будут поддерживаться и в IE11. Может ли кто-нибудь помочь мне определить IE11 только стили или возможности, которые я мог бы использовать, чтобы разделить эти два элемента?

Дополнительная информация

  • Я не хочу использовать определение типа агента пользователя, потому что оно очень нестабильно и может быть изменено, а также я думаю, что я читал, что IE11 намеренно пытается скрыть тот факт, что это Internet Explorer.
  • Для примера того, как работает тестирование возможностей IE10, я использовал этот JsFiddle (не мой) в качестве основы для моего тестирования.
  • Также я ожидаю много ответов "Это плохая идея...". Одна из моих потребностей в этом заключается в том, что IE10 утверждает, что он что-то поддерживает, но он очень плохо реализован, и я хочу иметь возможность различать IE10 и IE11 +, чтобы в будущем я мог перейти к методу обнаружения на основе возможностей.
  • Этот тест в сочетании с тестом Modernizr, который просто сделает некоторую функциональность "откатом" к менее гламурному поведению. Мы не говорим о критической функциональности.

ТАКЖЕ я уже использую Modernizr, но здесь это не помогает. Мне нужна помощь для решения моего четко заданного вопроса, пожалуйста.

17 ответов

Решение

Так что в конце концов я нашел свое решение этой проблемы.

После поиска в документации Microsoft мне удалось найти новый стиль только для IE11 msTextCombineHorizontal

В моем тесте я проверяю стили IE10 и, если они имеют положительное совпадение, то я проверяю только стиль IE11. Если я найду его, то это IE11+, если нет, то это IE10.

Пример кода: определение IE10 и IE11 с помощью тестирования возможностей CSS (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.

Я использую этот тест для резервного поведения. Резервное поведение - просто менее гламурный стиль, у него нет ограниченной функциональности.

В свете развивающейся темы я обновил ниже:

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

сноска

Если возможно, выявляйте и устраняйте любые проблемы без взлома. Поддержка прогрессивного улучшения и постепенной деградации. Тем не менее, это сценарий "идеального мира", который не всегда доступен, поэтому вышеизложенное должно помочь предложить некоторые хорошие варианты.


Атрибуция / Основное чтение

@media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {  

}

добавьте все свои классы или свойства CSS.

Это похоже на работу:

@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/

Вот ответ на 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и все другие соответствующие комбинации браузер / версия.

Также вероятно, что некоторые -ms-foo Собственное свойство, которое поддерживает IE11, но> IE11 не поддерживает, также в этом случае вы можете использовать @supports (--what: evr) { } вместо этого непосредственно на IE11, используя вышеупомянутое переопределение.

Вы можете написать свой код 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;
    }
}

Попробуй это:

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

Это сработало для меня

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

А затем в файле CSS вещи с префиксом

body.ie11 #some-other-div

Когда этот браузер готов умереть?

Взгляните на эту статью: CSS: Выбор пользовательских агентов

В основном, когда вы используете этот скрипт:

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

Используйте следующие свойства:

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

Вы можете использовать js и добавить класс в html, чтобы поддерживать стандарт условных комментариев:

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

Или используйте lib как bowser:

https://github.com/ded/bowser

Или модернизр для обнаружения функций:

http://modernizr.com/

Возможно, Layout Engine v0.7.0 - хорошее решение для вашей ситуации. Он использует функцию обнаружения браузера и может обнаруживать не только IE11 и IE10, но также IE9, IE8 и IE7. Он также обнаруживает другие популярные браузеры, в том числе некоторые мобильные браузеры. Он добавляет класс к тегу html, прост в использовании и хорошо работает при довольно глубоком тестировании.

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

Я столкнулся с той же проблемой с Gravity Form (WordPress) в IE11. Стиль столбца формы "display: inline-grid" нарушил макет; применение ответов выше решило несоответствие!

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

Обнаружение 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-';

Если вы используете Modernizr - тогда вы можете легко отличить IE10 от IE11.

IE10 не поддерживает pointer-events имущество. IE11 делает. ( caniuse)

Теперь, основываясь на классе, который вставляет Modernizr, у вас может быть следующий CSS:

.class
{ 
   /* for IE11 */
}

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

Вы можете попробовать это:

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

Вы должны использовать 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 все еще находится в режиме предварительного просмотра, и пользовательский агент может измениться до выпуска.

Строка User-agent для 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\./)

Шаг назад: почему вы даже пытаетесь обнаружить "Internet Explorer", а не "мой веб-сайт должен делать X, поддерживает ли этот браузер эту функцию? Если это так, хороший браузер. Если нет, то я должен предупредить пользователя".

Вы должны найти http://modernizr.com/ вместо того, чтобы продолжать то, что вы делаете.

Другие вопросы по тегам