Rilevamento di IE11 utilizzando CSS Capability / Feature Detection


90

IE10 + non supporta più i tag di rilevamento del browser per identificare un browser.

Per rilevare IE10 sto usando JavaScript e una tecnica di test di capacità per rilevare determinati msstili con prefisso sono definiti come msTouchActione msWrapFlow.

Voglio fare lo stesso per IE11, ma presumo che tutti gli stili di IE10 saranno supportati anche in IE11. Qualcuno può aiutarmi a identificare solo gli stili o le capacità di IE11 che potrei usare per distinguere i due?

Informazioni extra

  • Non voglio utilizzare il rilevamento del tipo di agente utente perché è così irregolare e può essere modificato, così come penso di aver letto che IE11 sta intenzionalmente cercando di nascondere il fatto che sia Internet Explorer.
  • Per un esempio di come funziona il test di capacità di IE10, ho usato questo JsFiddle (non il mio) come base per i miei test.
  • Inoltre mi aspetto molte risposte di "Questa è una cattiva idea ...". Uno dei miei bisogni è che IE10 affermi di supportare qualcosa, ma è implementato molto male e voglio essere in grado di distinguere tra IE10 e IE11 + in modo da poter andare avanti con un metodo di rilevamento basato sulle capacità in futuro.
  • Questo test è abbinato a un test Modernizr che semplicemente renderà alcune funzionalità "di riserva" a comportamenti meno affascinanti. Non stiamo parlando di funzionalità critiche.

INOLTRE sto già usando Modernizr, ma qui non aiuta. Ho bisogno di aiuto per una soluzione alla mia domanda chiaramente posta per favore.


3
Perché hai bisogno di sapere quale browser ha l'utente? Non sono sufficienti il ​​rilevamento delle funzionalità / prefissi css / css condizionali?
David-SkyMesh,

4
Ho dimenticato di dire che abbiamo le nostre ragioni per aver bisogno di rilevare i browser, per cui il test di capacità non aiuta. Solo uno dei nostri problemi è che IE10 dice di supportare qualcosa, ma non lo fa molto bene.
dano

2
@ David-SkyMesh - No. Purtroppo non è abbastanza. Vorrei che lo fosse, ma non lo è.
dano

1
@Evildonald Non hai risposto perché hai bisogno di sapere, in particolare. Potrebbe benissimo essere che questo sia un problema XY. (ad esempio: stai chiedendo di aiutare con X - rilevamento di IE11 - quando potremmo rispondere a una domanda diversa Y - come essere compatibili con più browser incluso IE11 per TASK Z)
David-SkyMesh

1
Avevo un .js che rileva le versioni del browser e diceva che ie11 era un Firefox. cosa sta succedendo, cioè sviluppatori!
Daniel Cheung

Risposte:


163

Alla luce del thread in evoluzione, ho aggiornato quanto segue:

IE 6

* html .ie6 {property:value;}

o

.ie6 { _property:value;}

IE 7

*+html .ie7 {property:value;}

o

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

IE 6 e 7

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

o

.ie67 { *property:value;}

o

.ie67 { #property:value;}

IE 6, 7 e 8

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

IE 8

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

o

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

Solo modalità IE 8 Standards

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

IE 8,9 e 10

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

Solo IE 9

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

IE 9 e versioni successive

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

IE 9 e 10

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

Solo IE 10

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

IE 10 e versioni successive

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

o

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

L'uso di -ms-high-contrastsignifica che MS Edge non sarà preso di mira, poiché Edge non supporta-ms-high-contrast .

IE 11

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

Alternative Javascript

Modernizr

Modernizr viene eseguito rapidamente al caricamento della pagina per rilevare le funzionalità; quindi crea un oggetto JavaScript con i risultati e aggiunge classi all'elemento html

Selezione agente utente

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

Aggiunge (ad esempio) il seguente htmlall'elemento:

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'

Consentire selettori CSS molto mirati, ad esempio:

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

Nota

Se possibile, identifica e risolvi eventuali problemi senza hack. Supporta il miglioramento progressivo e il degrado grazioso . Tuttavia, questo è uno scenario di "mondo ideale" non sempre ottenibile, in quanto tale, quanto sopra dovrebbe aiutare a fornire alcune buone opzioni.


Attribuzione / Lettura essenziale


3
Questa dovrebbe essere davvero la risposta. Ottimo dettaglio!
egr103

Solo IE10 non funziona per me. Il backslash-9 non rimuove IE11. Sto cercando di mostrare un div per IE 10 ma non per IE11 ... Viene ancora visualizzato su IE 11 ...
Merc

Ah strano. Funziona sulla maggior parte delle proprietà ma clip: auto\9;è ancora interpretato come clip: auto;in IE 11. In qualche modo questo non viene ignorato ...
Merc

2
Per me, la seconda opzione di IE10 ha funzionato per IE11: l' @media all and (-ms-high-contrast: none), (-ms-high-contrast: active) { .relevant_selectors_for_situation {property:value;} }ho trovata in mediacurrent.com/blog/…
cedricdlb

1
Dopo aver letto tutto questo, penso che -ms-high-contrast: activepotrebbe essere qualcosa da evitare perché secondo le specifiche di MS, in Edge, sceglierai come target gli utenti di temi ad alto contrasto con le tue regole IE 10/11. Nella pagina a cui si collega questa risposta -ms-high-contrast, in realtà dice che solo il -ms-high-contrast: nonevalore non è più supportato. Penso che nessuno lo menzioni perché la maggior parte delle persone non ha la modalità ad alto contrasto abilitata e la maggior parte delle persone non usa Edge. Tuttavia, c'è qualcuno là fuori che ha quella configurazione e questo probabilmente non è bello per loro.
dmatamales

40

Per scegliere come target solo IE10 e IE11 (e non Edge):

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

1
Qualcosa del genere potrebbe anche essere un miscuglio impertinente!
dano

2
Questo target è solo IE11 o anche Edge?
Matthew Felgate

2
Ha come target IE10 e IE11 ma non Edge.
Jeff Clayton

23

Quindi alla fine ho trovato la mia soluzione a questo problema.

Dopo aver cercato nella documentazione Microsoft sono riuscito a trovare un nuovo stile unico per IE11msTextCombineHorizontal

Nel mio test, controllo gli stili IE10 e se sono una corrispondenza positiva, allora cerco solo lo stile IE11. Se lo trovo, allora è IE11 +, se non lo trovo, allora è IE10.

Esempio di codice: rilevamento di IE10 e IE11 tramite CSS Capability Testing (JSFiddle)

Aggiornerò l'esempio di codice con più stili quando li scoprirò.

NOTA: Questo quasi certamente identificherà IE12 e IE13 come "IE11", poiché questi stili probabilmente continueranno. Aggiungerò ulteriori test man mano che verranno lanciate nuove versioni e, si spera, potrò fare di nuovo affidamento su Modernizr.

Sto usando questo test per il comportamento di fallback. Il comportamento di riserva è solo uno stile meno affascinante, non ha funzionalità ridotte.


8
Se qualcuno sta per -1 questa risposta, per favore, almeno abbi la decenza di ammetterlo con una ragione tecnica . Potresti non essere d'accordo ... ma è corretto e funziona.
dano

7
Come fai a sapere se questo codice produrrà risultati corretti in IE12, IE13 e così via?
Evgeny

6
Perché stai usando questo metodo invece di if (document.documentMode === 11) { ... }? A meno che, ovviamente, non si desideri utilizzare la proprietà CSS in un file@supports regola (che non è ancora supportata in IE, tra l'altro).
Rob W

1
Se hai classi esistenti nel tuo tag body, questo le sovrascriverà. Ecco la correzione molto minore: jsfiddle.net/jmjpro/njvr1jq2/1 .
jbustamovej

1
Inoltre, vorrai nascondere l'elemento ieVersion con css: #ieVersion {display: none}
jbustamovej


9

È possibile scrivere il codice IE11 normalmente e quindi utilizzare @supportse verificare una proprietà che non è supportata in IE11, ad esempio grid-area: auto.

Puoi quindi scrivere i tuoi stili di browser moderni all'interno di questo. IE non supporta la @supportsregola e utilizzerà gli stili originali, mentre questi verranno sovrascritti nei browser moderni che supportano @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
Funziona ed è una buona soluzione, ma il ragionamento fornito non è corretto. IE11 non supporta @supportsaffatto, quindi ignora qualsiasi cosa nel @supportsblocco. Quindi puoi mettere qualsiasi cosa nel condizionale @supports (ad esempio @supports (display: block)) e IE11 lo salterà ancora.
CodeBiker

1
Questo è ciò che intendevo con "IE 11 ignorerà" ma hai ragione, non è del tutto chiaro. Ho aggiornato la risposta per essere più chiaro che IE non supporta @supports.
Antfish

9

Ecco una risposta per il 2017 in poi, dove probabilmente ti interessa solo distinguere <= IE11 da> IE11 ("Edge"):

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

Esempio più dimostrativo:

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

Questo funziona perché IE11 in realtà non supporta nemmeno @supports, e tutte le altre combinazioni browser / versione pertinenti lo fanno.


4

Questo ha funzionato per me

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

E poi nel file css le cose con prefisso

body.ie11 #some-other-div

Quando sarà pronto questo browser?


4

Prova questo:

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

3

Dai un'occhiata a questo articolo: CSS: selettori dell'agente utente

Fondamentalmente, quando usi questo script:

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

Ora puoi utilizzare CSS per scegliere come target qualsiasi browser / versione.

Quindi per IE11 potremmo fare questo:

VIOLINO

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

1
Ciò non funzionerebbe in Firefox 11 (anche se ora non è supportato, è importante). Ha anche rv:11.0nella sua stringa agente utente.
PhistucK

3

Usa le seguenti proprietà:

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

2

Dovresti usare Modernizr, aggiungerà una classe al tag body.

anche:

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

Nota che IE11 è ancora in anteprima e l'agente utente potrebbe cambiare prima del rilascio.

La stringa User-agent per IE 11 è attualmente questa:

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

Ciò significa che puoi semplicemente testare, per le versioni 11.xx,

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

Grazie Neo, ma sto già aggiungendo una classe al mio tag body E sto usando Modernizr. Sto cercando un modo per differenziare IE10 da IE11 senza utilizzare l'agente utente che non è affidabile.
dano

Mancano i due punti in rv 11. var isIE11 = !! navigator.userAgent.match (/Trident.*rv:11 \ ./)
T.CK

2

Forse Layout Engine v0.7.0 è una buona soluzione per la tua situazione. Utilizza il rilevamento delle funzionalità del browser e può rilevare non solo IE11 e IE10, ma anche IE9, IE8 e IE7. Rileva anche altri browser popolari, inclusi alcuni browser mobili. Aggiunge una classe al tag html, è facile da usare e viene eseguito bene in alcuni test abbastanza approfonditi.

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


2

Se stai usando Modernizr , puoi facilmente distinguere tra IE10 e IE11.

IE10 non supporta la pointer-eventsproprietà. IE11 lo fa. ( caniuse )

Ora, in base alla classe che Modernizr inserisce, potresti avere il seguente CSS:

.class
{ 
   /* for IE11 */
}

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

2

Puoi usare js e aggiungere una classe in html per mantenere lo standard dei commenti condizionali :

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

Oppure usa una libreria come bowser:

https://github.com/ded/bowser

O modernizr per il rilevamento delle funzionalità:

http://modernizr.com/


2

Rilevare IE e le sue versioni in realtà è estremamente facile, almeno estremamente intuitivo:

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

.

In questo modo, stai anche catturando versioni di IE alte in modalità di compatibilità / visualizzazione. Successivamente, è questione di assegnare classi condizionali:

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

2

Puoi provare questo:

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

2

Ho riscontrato lo stesso problema con un Gravity Form (WordPress) in IE11. Lo stile di colonna del modulo "display: inline-grid" ha interrotto il layout; l'applicazione delle risposte sopra ha risolto la discrepanza!

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

1

Fai un passo indietro: perché stai anche cercando di rilevare "Internet Explorer" anziché "il mio sito web deve fare X, questo browser supporta questa funzione? Se è così, buon browser. In caso contrario, dovrei avvertire l'utente".

Dovresti fare clic su http://modernizr.com/ invece di continuare quello che stai facendo.


Grazie per una soluzione alternativa, ma sto già usando Modernizr e IE10 rappresenta male le sue capacità.
dano

4
Presumo che tu sappia quali e hai presentato un problema con Modernizr in modo che possano aggiungere più controlli Modernizrs per quel particolare browser? (In caso contrario, dovresti. Se trovi qualcosa che ha un impatto su centinaia di migliaia di sviluppatori, presentarlo alle persone responsabili dello shim è l'unica cosa giusta da fare)
Mike 'Pomax' Kamermans

7
Per quelli di noi che scrivono codice rivolto all'utente, spesso è necessaria una risposta ora , non un bug archiviato in una libreria di terze parti e una patch lì. Vale a dire, è bello che tu voglia che migliorino Modernizr, ma qui non va bene.
Dean J

1
Penso che rilevare il browser reale sia un obiettivo ragionevole di per sé.
gwg

@DeanJ certo, e per quelle domande anche qualcun altro fornirà una risposta. Ciò non rende meno importante ottenere risposte come queste che ti dicono di pensare a quello che stai facendo. Inoltre, al momento del repy non c'erano modifiche al post e non c'era alcuna menzione di "Ho bisogno che funzioni adesso", quindi non avevo motivo di presumere che non volessero un controllo della realtà.
Mike 'Pomax' Kamermans
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.