Wykrywanie IE11 za pomocą CSS Capability / Feature Detection

90

IE10 + nie obsługuje już tagów wykrywania przeglądarki w celu identyfikacji przeglądarki.

Do wykrywania IE10 używam JavaScript i mszdefiniowano technikę testowania możliwości w celu wykrycia pewnych stylów z przedrostkami, takich jak msTouchActioni msWrapFlow.

Chcę zrobić to samo dla IE11, ale zakładam, że wszystkie style IE10 będą również obsługiwane w IE11. Czy ktoś może mi pomóc zidentyfikować tylko style lub możliwości IE11, które pozwolą mi je rozróżnić?

Informacje dodatkowe

  • Nie chcę używać wykrywania typu User Agent, ponieważ jest tak nierówny i można go zmienić, a także wydaje mi się, że czytałem, że IE11 celowo próbuje ukryć fakt, że jest to Internet Explorer.
  • Aby zobaczyć, jak działa testowanie wydajności IE10, użyłem tego JsFiddle (nie mojego) jako podstawy do moich testów.
  • Spodziewam się też wielu odpowiedzi „To zły pomysł…”. Jedną z moich potrzeb jest to, że IE10 twierdzi, że coś obsługuje, ale jest bardzo źle zaimplementowany i chcę móc odróżnić IE10 od IE11 +, aby móc w przyszłości przejść do metody wykrywania opartej na możliwościach.
  • Ten test jest połączony z testem Modernizr, który po prostu sprawi, że niektóre funkcje będą „zastępować” mniej efektowne zachowanie. Nie mówimy o krytycznej funkcjonalności.

TAKŻE używam już Modernizr, ale to nie pomaga tutaj. Potrzebuję pomocy w rozwiązaniu mojego jasno zadanego pytania.

dano
źródło
3
Dlaczego musisz wiedzieć, jaką przeglądarkę ma użytkownik? Czy wykrywanie funkcji / prefiksy css / warunkowe css nie są wystarczające?
David-SkyMesh,
4
Zapomniałem wspomnieć, że mamy powody, dla których musimy wykrywać przeglądarki, w których testowanie możliwości nie pomaga. Jednym z naszych problemów jest to, że IE10 mówi, że coś obsługuje, ale nie robi tego zbyt dobrze.
dano
2
@ David-SkyMesh - Nie. To niestety za mało. Chciałbym, żeby tak było, ale tak nie jest.
dano
1
@Evildonald Nie odpowiedziałeś, dlaczego musisz wiedzieć - konkretnie. Możliwe, że jest to problem XY. (tj .: prosisz o pomoc przy X - wykrywaniu IE11 - kiedy moglibyśmy odpowiedzieć na inne pytanie Y - jak być kompatybilnym z większą liczbą przeglądarek, w tym IE11 dla TASK Z)
David-SkyMesh
1
Miałem plik .js, który wykrywa wersje przeglądarek i powiedział, że ie11 to firefox. co się dzieje, czyli programiści!
Daniel Cheung,

Odpowiedzi:

163

W świetle rozwijającego się wątku zaktualizowałem poniżej:

IE 6

* html .ie6 {property:value;}

lub

.ie6 { _property:value;}

IE 7

*+html .ie7 {property:value;}

lub

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

IE 6 i 7

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

lub

.ie67 { *property:value;}

lub

.ie67 { #property:value;}

IE 6, 7 i 8

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

IE 8

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

lub

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

Tylko tryb standardów IE 8

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

IE 8,9 i 10

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

Tylko IE 9

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

IE 9 i nowsze

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

IE 9 i 10

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

Tylko IE 10

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

IE 10 i nowsze

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

lub

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

Użycie -ms-high-contrastoznacza, że ​​MS Edge nie będzie celem, ponieważ Edge nie obsługuje-ms-high-contrast .

IE 11

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

Alternatywy dla JavaScript

Modernizr

Modernizr działa szybko podczas ładowania strony, aby wykrywać funkcje; następnie tworzy obiekt JavaScript z wynikami i dodaje klasy do elementu html

Wybór klienta użytkownika

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':'');

Dodaje (np.) Poniższe do htmlelementu:

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'

Umożliwienie bardzo ukierunkowanych selektorów CSS, np .:

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

Notatka

Jeśli to możliwe, zidentyfikuj i napraw wszelkie problemy bez hacków. Wspieraj stopniowe ulepszanie i wdzięczną degradację . Jest to jednak scenariusz „idealnego świata”, który nie zawsze jest możliwy do uzyskania, jako taki - powyższe powinno pomóc w zapewnieniu kilku dobrych opcji.


Atrybucja / Essential Reading

SW4
źródło
3
To naprawdę powinna być odpowiedź. Dobry szczegół!
egr103
Tylko IE10 nie działa dla mnie. Backslash-9 nie usuwa IE11. Próbuję wyświetlić element div dla IE 10, ale nie dla IE11 ... Nadal pojawia się w IE 11 ...
Merc
Ach, dziwne. Działa w przypadku większości właściwości, ale clip: auto\9;nadal jest interpretowany tak, jak clip: auto;w IE 11. W jakiś sposób nie jest to ignorowane ...
Merc
2
Dla mnie druga opcja IE10 działała dla IE11: @media all and (-ms-high-contrast: none), (-ms-high-contrast: active) { .relevant_selectors_for_situation {property:value;} }znalazłem ją na mediacurrent.com/blog/ ...
cedricdlb
1
Po przeczytaniu tego wszystkiego myślę, że -ms-high-contrast: activemoże być coś, czego należy unikać, ponieważ zgodnie ze specyfikacjami MS faktycznie będziesz kierować reklamy do użytkowników o wysokim kontraście w Edge z regułami IE 10/11. Na stronie, do której prowadzi ta odpowiedź -ms-high-contrast, w rzeczywistości mówi, że tylko -ms-high-contrast: nonewartość nie jest już obsługiwana. Myślę, że nikt o tym nie wspomina, ponieważ większość ludzi nie ma włączonego trybu wysokiego kontrastu i większość ludzi nie używa Edge. Ale nadal jest ktoś , kto ma taką konfigurację i prawdopodobnie nie jest to dla niego fajne.
dmatamales
40

Aby kierować reklamy tylko na IE10 i IE11 (a nie Edge):

@media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {  
   /* add your IE10-IE11 css here */   
}
Apps Tawale
źródło
1
Coś takiego może być też bezczelną mieszanką!
dano
2
Czy to jest przeznaczone tylko dla IE11 czy też Edge?
Matthew Felgate,
2
Jest przeznaczony dla IE10 i IE11, ale nie dla krawędzi.
Jeff Clayton,
23

Więc w końcu znalazłem własne rozwiązanie tego problemu.

Po przeszukaniu dokumentacji Microsoftu udało mi się znaleźć nowy styl tylko dla IE11msTextCombineHorizontal

W moim teście sprawdzam style IE10 i jeśli są one zgodne, sprawdzam tylko styl IE11. Jeśli go znajdę, to IE11 +, jeśli nie, to IE10.

Przykład kodu: Wykryj IE10 i IE11 za pomocą testów możliwości CSS (JSFiddle)

Zaktualizuję przykładowy kod o więcej stylów, gdy je odkryję.

UWAGA: To prawie na pewno zidentyfikuje IE12 i IE13 jako „IE11”, ponieważ te style prawdopodobnie będą kontynuowane. Dodam kolejne testy, gdy pojawią się nowe wersje i mam nadzieję, że będę mógł ponownie polegać na Modernizrze.

Używam tego testu do zachowania awaryjnego. Zachowanie rezerwowe jest po prostu mniej efektowną stylizacją, nie ma ograniczonej funkcjonalności.

dano
źródło
8
Jeśli ktoś ma zamiar -1 to odpowiedź, proszę przynajmniej przyznać się do tego z przyczyn technicznych . Możesz się z tym nie zgadzać ... ale jest poprawne i działa.
dano,
7
Skąd wiesz, czy ten kod da prawidłowe wyniki w IE12, IE13 i tak dalej?
Evgeny,
6
Dlaczego zamiast tego używasz tej metody if (document.documentMode === 11) { ... }? Chyba że, oczywiście, chcesz użyć właściwości CSS w @supportsregule at (która, nawiasem mówiąc, nie jest jeszcze obsługiwana w IE).
Rob W
1
Jeśli masz istniejące klasy w swoim tagu body, spowoduje to ich zastąpienie. Oto bardzo drobna poprawka: jsfiddle.net/jmjpro/njvr1jq2/1 .
jbustamovej
1
Będziesz także chciał ukryć element ieVersion za pomocą css: #ieVersion {display: none}
jbustamovej
19

To wydaje się działać:

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

geoff
źródło
Ten nie rozróżnia ie10 i ie11, ale jeśli nie masz nic przeciwko wykrywaniu ie10, to jesteś dobry z tym.
Jeff Clayton,
9

Możesz napisać swój kod IE11 w normalny sposób, a następnie użyć @supportsi sprawdzić na przykład właściwość, która nie jest obsługiwana w IE11 grid-area: auto.

Następnie możesz w nim napisać nowoczesne style przeglądarki. IE nie obsługuje @supportsreguły i użyje oryginalnych stylów, podczas gdy te zostaną nadpisane w nowoczesnych przeglądarkach, które obsługują @supports.

.my-class {
// IE the background will be red
background: red;

   // Modern browsers the background will be blue
    @supports (grid-area: auto) {
      background: blue;
    }
}
Mrówka
źródło
2
To działa i jest dobrym rozwiązaniem, ale podane rozumowanie jest nieprawidłowe. IE11 w ogóle nie obsługuje @supports, więc ignoruje wszystko w @supportsbloku. Możesz więc umieścić cokolwiek w warunku @supports (np. @supports (display: block)), A IE11 nadal będzie to pomijać.
CodeBiker
1
To właśnie miałem na myśli mówiąc „IE 11 będzie ignorować”, ale masz rację, to nie jest do końca jasne. Zaktualizowałem odpowiedź, aby była bardziej jasna, że ​​IE nie obsługuje @supports.
Antfish
9

Oto odpowiedź na 2017 rok, gdzie prawdopodobnie zależy Ci tylko na odróżnieniu <= IE11 od> IE11 ("Edge"):

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

Bardziej poglądowy przykład:

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

To działa, ponieważ IE11 w rzeczywistości nawet nie obsługuje @supports, a wszystkie inne odpowiednie kombinacje przeglądarki / wersji tak.

Jan Kyu Peblik
źródło
4

To zadziałało dla mnie

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

A potem w pliku css rzeczy z prefiksem

body.ie11 #some-other-div

Kiedy ta przeglądarka jest gotowa na śmierć?

Bert Oost
źródło
4

Spróbuj tego:

/*------Specific style for IE11---------*/
 _:-ms-fullscreen, :root 
 .legend 
{ 
  line-height: 1.5em;
  position: relative;
  top: -1.1em;   
}
Mahyar Farshi
źródło
3

Spójrz na ten artykuł: CSS: selektory agenta użytkownika

Zasadniczo, gdy używasz tego skryptu:

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':'');

Możesz teraz używać CSS do kierowania reklam na dowolną przeglądarkę / wersję.

Więc dla IE11 możemy to zrobić:

SKRZYPCE

html[data-useragent*='rv:11.0']
{
    color: green;
}
Danield
źródło
1
To by się zepsuło w Firefoksie 11 (chociaż nie jest teraz obsługiwane, ma to znaczenie). Ma również rv:11.0w swoim ciągu agenta użytkownika.
PhistucK
3

Użyj następujących właściwości:

  • !! window.MSInputMethodContext
  • !! document.msFullscreenEnabled
Paul Sweatte
źródło
2

Powinieneś użyć Modernizr, doda klasę do tagu body.

również:

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

Należy zauważyć, że IE11 jest nadal w wersji zapoznawczej, a agent użytkownika może ulec zmianie przed wydaniem.

Ciąg agenta użytkownika dla IE 11 to obecnie:

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

Oznacza to, że możesz po prostu przetestować, dla wersji 11.xx,

var isIE11 = !!navigator.userAgent.match(/Trident.*rv 11\./)
Neo
źródło
Dzięki Neo, ale już dodaję klasę do mojego tagu body ORAZ używam Modernizr. Szukam sposobu na odróżnienie IE10 od IE11 bez użycia agenta użytkownika, który nie jest godny zaufania.
dano
Brak dwukropka w rv 11. var isIE11 = !! navigator.userAgent.match (/Trident.*rv:11 \ ./)
T.CK
2

Być może Layout Engine v0.7.0 jest dobrym rozwiązaniem w Twojej sytuacji. Wykorzystuje wykrywanie funkcji przeglądarki i może wykryć nie tylko IE11 i IE10, ale także IE9, IE8 i IE7. Wykrywa także inne popularne przeglądarki, w tym niektóre przeglądarki mobilne. Dodaje klasę do tagu html, jest łatwy w użyciu i dobrze się sprawdza w dość dokładnych testach.

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

Talkingrock
źródło
2

Jeśli używasz Modernizr - możesz łatwo odróżnić IE10 od IE11.

IE10 nie obsługuje tej pointer-eventswłaściwości. IE11 tak. ( caniuse )

Teraz, w oparciu o klasę wstawioną przez Modernizr, możesz mieć następujący CSS:

.class
{ 
   /* for IE11 */
}

.no-pointerevents .class
{ 
   /* for IE10 */
}
Danield
źródło
2

Możesz użyć js i dodać klasę w html, aby zachować standard warunkowych komentarzy :

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

Lub użyj biblioteki, takiej jak bowser:

https://github.com/ded/bowser

Lub zmodernizuj do wykrywania funkcji:

http://modernizr.com/

Liko
źródło
2

Wykrywanie IE i jego wersji jest w rzeczywistości niezwykle łatwe, a przynajmniej niezwykle intuicyjne:

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

.

W ten sposób wychwytujesz również wersje z wysokim IE w trybie / widoku zgodności. Następnie chodzi o przypisanie klas warunkowych:

var htmlTag = document.documentElement;
if (browser == 'IE' && ieVersion <= 11)
    htmlTag.className += ' ie11-';
Frank Conijn
źródło
2

Możesz spróbować tego:

if(document.documentMode) {
  document.documentElement.className+=' ie'+document.documentMode;
}
Adrian Miranda
źródło
2

Napotkałem ten sam problem z Gravity Form (WordPress) w IE11. Styl kolumny formularza „display: inline-grid” zepsuł układ; zastosowanie powyższych odpowiedzi rozwiązało tę rozbieżność!

@media all and (-ms-high-contrast:none){
  *::-ms-backdrop, .gfmc-column { display: inline-block;} /* IE11 */
}
leonel.ai
źródło
1

Cofnij się: dlaczego w ogóle próbujesz wykryć „Internet Explorer” zamiast „moja witryna musi wykonać X. Czy ta przeglądarka obsługuje tę funkcję? Jeśli tak, dobra przeglądarka. Jeśli nie, to powinienem ostrzec użytkownika”.

Powinieneś trafić na http://modernizr.com/ zamiast kontynuować to, co robisz.

Mike 'Pomax' Kamermans
źródło
Dzięki za alternatywne rozwiązanie, ale już używam Modernizr, a IE10 źle reprezentuje jego możliwości.
dano
4
Zakładam, że wiesz, które z nich, i zgłosiłeś problem do Modernizr, aby mogli dodać więcej sprawdzeń Modernizatorów dla tej konkretnej przeglądarki? (Jeśli nie, powinieneś. Jeśli znajdziesz coś, co ma wpływ na setki tysięcy programistów, zgłoszenie tego do osób odpowiedzialnych za podkładkę jest jedyną właściwą rzeczą)
Mike 'Pomax' Kamermans
7
Ci z nas, którzy piszą kod skierowany do użytkownika, często potrzebują teraz odpowiedzi , a nie zgłoszenia błędu w bibliotece innej firmy i tamtejszej łatki. To znaczy, fajnie, że chcesz, aby ulepszyli Modernizr, ale to nie pasuje tutaj.
Dean J
1
Myślę, że wykrycie prawdziwej przeglądarki jest rozsądnym celem per se.
gwg
@DeanJ jasne, a na te pytania ktoś inny też udzieli odpowiedzi. Nie oznacza to, że otrzymywanie takich odpowiedzi, które każą ci myśleć o tym, co robisz, nie jest mniej ważne. Poza tym w czasie repy nie było żadnych zmian w poście i nie było wzmianki o tym, że „potrzebuję go teraz do pracy”, więc nie miałem powodu zakładać, że nie chcą sprawdzania rzeczywistości.
Mike 'Pomax' Kamermans