Detección de IE11 mediante detección de funciones / capacidad CSS

90

IE10 + ya no admite etiquetas de detección de navegador para identificar un navegador.

Para detectar IE10, estoy usando JavaScript y msse define una técnica de prueba de capacidad para detectar ciertos estilos con prefijos como msTouchActiony msWrapFlow.

Quiero hacer lo mismo para IE11, pero supongo que todos los estilos de IE10 también serán compatibles con IE11. ¿Alguien puede ayudarme a identificar solo los estilos o capacidades de IE11 que podría usar para diferenciar los dos?

Información extra

  • No quiero usar la detección de tipo de agente de usuario porque es muy irregular y se puede cambiar, y creo que he leído que IE11 está tratando de ocultar intencionalmente el hecho de que es Internet Explorer.
  • Para ver un ejemplo de cómo funciona la prueba de capacidad de IE10, utilicé este JsFiddle (no el mío) como base para mis pruebas.
  • También espero muchas respuestas de "Esto es una mala idea ...". Una de mis necesidades para esto es que IE10 afirma que es compatible con algo, pero está muy mal implementado, y quiero poder diferenciar entre IE10 e IE11 + para poder seguir adelante con un método de detección basado en capacidades en el futuro.
  • Esta prueba se combina con una prueba de Modernizr que simplemente hará que algunas funciones "retrocedan" a un comportamiento menos glamoroso. No estamos hablando de funcionalidad crítica.

TAMBIÉN ya estoy usando Modernizr, pero aquí no ayuda. Necesito ayuda para encontrar una solución a mi pregunta claramente formulada, por favor.

dano
fuente
3
¿Por qué necesita saber qué navegador tiene el usuario? ¿No es suficiente la detección de características / prefijos css / condicionales css?
David-SkyMesh
4
Olvidé mencionar que tenemos nuestras razones para necesitar detectar los navegadores, con las que las pruebas de capacidad no ayudan. Solo uno de nuestros problemas es que IE10 dice que admite algo, pero no lo hace muy bien.
dano
2
@ David-SkyMesh - No. Lamentablemente, no es suficiente. Me gustaría que así fuera, pero no lo es.
dano
1
@Evildonald No respondió por qué necesita saber, específicamente. Bien podría ser que se trate de un problema XY. (es decir, está pidiendo ayuda con X - detectar IE11 - cuando podríamos responder una pregunta diferente Y - cómo ser compatible con más navegadores, incluido IE11 para TASK Z)
David-SkyMesh
1
Tenía un .js que detecta las versiones del navegador y decía que ie11 era un firefox. qué está pasando, es decir, ¡desarrolladores!
Daniel Cheung

Respuestas:

163

A la luz del hilo en evolución, he actualizado lo siguiente:

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 y 7

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

o

.ie67 { *property:value;}

o

.ie67 { #property:value;}

IE 6, 7 y 8

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

IE 8

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

o

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

Solo modo estándar IE 8

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

IE 8,9 y 10

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

IE 9 solamente

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

IE 9 y superior

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

IE 9 y 10

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

IE 10 solamente

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

IE 10 y superior

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

o

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

El uso de -ms-high-contrastmedios que MS Edge no será el objetivo, ya que Edge no es compatible-ms-high-contrast .

IE 11

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

Alternativas de JavaScript

Modernizr

Modernizr se ejecuta rápidamente al cargar la página para detectar funciones; luego crea un objeto JavaScript con los resultados y agrega clases al elemento html

Selección de agente de usuario

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

Agrega (por ejemplo) lo siguiente al htmlelemento:

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'

Permitir selectores de CSS muy específicos, por ejemplo:

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

Nota

Si es posible, identifique y solucione cualquier problema sin hacks. Apoye la mejora progresiva y la degradación elegante . Sin embargo, este es un escenario de 'mundo ideal' que no siempre se puede obtener, como tal, lo anterior debería ayudar a proporcionar algunas buenas opciones.


Atribución / Lectura esencial

SW4
fuente
3
Esta debería ser realmente la respuesta. ¡Gran detalle!
egr103
El IE10 solo no me funciona. La barra invertida-9 no elimina IE11. Estoy tratando de mostrar un div para IE 10 pero no para IE11 ... Todavía aparece en IE 11 ...
Merc
Ah, raro. Funciona en la mayoría de las propiedades, pero clip: auto\9;aún se interpreta como clip: auto;en IE 11. De alguna manera esto no se ignora ...
Merc
2
Para mí, la segunda opción de IE10 funcionó para IE11: la @media all and (-ms-high-contrast: none), (-ms-high-contrast: active) { .relevant_selectors_for_situation {property:value;} }encontré en mediacurrent.com/blog/…
cedricdlb
1
Después de leer todo esto, creo que -ms-high-contrast: activepodría ser algo para evitar porque, de acuerdo con las especificaciones de MS, en realidad apuntará a los usuarios de temas de alto contraste en Edge con sus reglas de IE 10/11. En la página a la que se vincula esta respuesta, -ms-high-contrasten realidad dice que solo el -ms-high-contrast: nonevalor ya no es compatible. Creo que nadie menciona esto porque la mayoría de la gente no tiene habilitado el modo de alto contraste y la mayoría de la gente no usa Edge. Pero aún así, hay alguien que tiene esa configuración y esto probablemente no sea bueno para ellos.
dmatamales
40

Para apuntar solo a IE10 e IE11 (y no a Edge):

@media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {  
   /* add your IE10-IE11 css here */   
}
Aplicaciones Tawale
fuente
1
¡Algo así también podría ser una mezcla descarada!
dano
2
¿Eso apunta solo a IE11 o también a Edge?
Matthew Felgate
2
Se dirige a IE10 e IE11 pero no al borde.
Jeff Clayton
23

Así que al final encontré mi propia solución a este problema.

Después de buscar en la documentación de Microsoft , logré encontrar un nuevo estilo único de IE11msTextCombineHorizontal

En mi prueba, verifico los estilos IE10 y si coinciden positivamente, verifico el estilo solo IE11. Si lo encuentro, entonces es IE11 +, si no lo encuentro, entonces es IE10.

Ejemplo de código: detectar IE10 e IE11 mediante pruebas de capacidad CSS (JSFiddle)

Actualizaré el ejemplo de código con más estilos cuando los descubra.

NOTA: Es casi seguro que esto identificará a IE12 e IE13 como "IE11", ya que esos estilos probablemente seguirán adelante. Agregaré más pruebas a medida que se implementen nuevas versiones y, con suerte, podré confiar nuevamente en Modernizr.

Estoy usando esta prueba para el comportamiento alternativo. El comportamiento alternativo es simplemente un estilo menos glamoroso, no tiene una funcionalidad reducida.

dano
fuente
8
Si alguien va a -1 en esta respuesta, al menos tenga la decencia de admitirlo con una razón técnica . Puede que no esté de acuerdo con él ... pero es correcto y funciona.
dano
7
¿Cómo sabe si este código producirá resultados correctos en IE12, IE13, etc.?
Evgeny
6
¿Por qué estás usando este método en lugar de if (document.documentMode === 11) { ... }? A menos, por supuesto, que desee utilizar la propiedad CSS en una @supportsregla at (que aún no es compatible con IE, por cierto).
Rob W
1
Si tiene clases existentes en su etiqueta corporal, esto las sobrescribirá. Aquí está la solución menor: jsfiddle.net/jmjpro/njvr1jq2/1 .
jbustamovej
1
Además, querrá ocultar el elemento ieVersion con css: #ieVersion {display: none}
jbustamovej
9

Puede escribir su código IE11 normalmente y luego usar @supportsy verificar una propiedad que no sea compatible con IE11, por ejemplo grid-area: auto.

A continuación, puede escribir los estilos de su navegador moderno dentro de este. IE no admite la @supportsregla y usará los estilos originales, mientras que estos se anularán en los navegadores modernos que lo admitan @supports.

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

   // Modern browsers the background will be blue
    @supports (grid-area: auto) {
      background: blue;
    }
}
Antfish
fuente
2
Esto funciona y es una buena solución, pero el razonamiento dado no es correcto. IE11 no es compatible @supportsen absoluto, por lo que ignora cualquier cosa en el @supportsbloque. Por lo tanto, puede poner cualquier cosa en el condicional @supports (por ejemplo @supports (display: block)) e IE11 aún lo omitirá.
CodeBiker
1
Esto es lo que quise decir con "IE 11 ignorará" pero tienes razón, eso no está del todo claro. Actualicé la respuesta para que quede más claro que IE no es compatible con @supports.
Antfish
9

Aquí hay una respuesta para 2017 en adelante, donde probablemente solo le interese distinguir <= IE11 de> IE11 ("Edge"):

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

Ejemplo más demostrativo:

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

Esto funciona porque IE11 ni siquiera es compatible @supports, y todas las demás combinaciones de navegador / versión relevantes sí lo hacen.

Jan Kyu Peblik
fuente
4

Esto funcionó para mi

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

Y luego, en el archivo css, las cosas con el prefijo

body.ie11 #some-other-div

¿Cuándo estará listo este navegador para morir?

Bert Oost
fuente
4

Prueba esto:

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

Eche un vistazo a este artículo: CSS: Selectores de agentes de usuario

Básicamente, cuando usa este 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':'');

Ahora puede usar CSS para apuntar a cualquier navegador / versión.

Entonces, para IE11 podríamos hacer esto:

VIOLÍN

html[data-useragent*='rv:11.0']
{
    color: green;
}
Danield
fuente
1
Eso se rompería en Firefox 11 (aunque ahora no es compatible, es importante). También tiene rv:11.0en su cadena de agente de usuario.
PhistucK
3

Utilice las siguientes propiedades:

  • !! window.MSInputMethodContext
  • !! document.msFullscreenEnabled
Paul Sweatte
fuente
2

Debe usar Modernizr, agregará una clase a la etiqueta del cuerpo.

además:

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

Tenga en cuenta que IE11 todavía está en versión preliminar y el agente de usuario puede cambiar antes del lanzamiento.

La cadena de agente de usuario para IE 11 es actualmente esta:

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

Lo que significa que puede simplemente probar, para las versiones 11.xx,

var isIE11 = !!navigator.userAgent.match(/Trident.*rv 11\./)
Neo
fuente
Gracias Neo, pero ya estoy agregando una clase a mi etiqueta corporal Y usando Modernizr. Estoy buscando una forma de diferenciar IE10 de IE11 sin usar el agente de usuario, que no es confiable.
dano
Faltan los dos puntos en rv 11. var isIE11 = !! navigator.userAgent.match (/Trident.*rv:11 \ ./)
T.CK
2

Quizás Layout Engine v0.7.0 sea una buena solución para su situación. Utiliza la detección de funciones del navegador y puede detectar no solo IE11 e IE10, sino también IE9, IE8 e IE7. También detecta otros navegadores populares, incluidos algunos navegadores móviles. Agrega una clase a la etiqueta html, es fácil de usar y funciona bien en algunas pruebas bastante profundas.

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

Talkingrock
fuente
2

Si está utilizando Modernizr , puede diferenciar fácilmente entre IE10 e IE11.

IE10 no admite la pointer-eventspropiedad. IE11 lo hace. ( caniuse )

Ahora, según la clase que inserta Modernizr, podría tener el siguiente CSS:

.class
{ 
   /* for IE11 */
}

.no-pointerevents .class
{ 
   /* for IE10 */
}
Danield
fuente
2

Puede usar js y agregar una clase en html para mantener el estándar de comentarios condicionales :

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

O use una biblioteca como bowser:

https://github.com/ded/bowser

O modernizr para la detección de características:

http://modernizr.com/

Liko
fuente
2

Detectar IE y sus versiones en realidad es extremadamente fácil, al menos extremadamente 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;
}

.

De esta manera, también está obteniendo versiones altas de IE en Modo / Vista de compatibilidad. A continuación, es cuestión de asignar clases condicionales:

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

Puedes probar esto:

if(document.documentMode) {
  document.documentElement.className+=' ie'+document.documentMode;
}
Adrián Miranda
fuente
2

Me encontré con el mismo problema con un formulario de gravedad (WordPress) en IE11. El estilo de columna del formulario "display: inline-grid" rompió el diseño; la aplicación de las respuestas anteriores resolvió la discrepancia.

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

Da un paso atrás: ¿por qué estás intentando detectar "Internet Explorer" en lugar de "Mi sitio web necesita hacer X? ¿Este navegador es compatible con esa función? Si es así, buen navegador. Si no, debo advertir al usuario".

Debería acceder a http://modernizr.com/ en lugar de continuar con lo que está haciendo.

Mike 'Pomax' Kamermans
fuente
Gracias por una solución alternativa, pero ya estoy usando Modernizr e IE10 representa erróneamente sus capacidades.
dano
4
Supongo que sabe cuáles y ha presentado un problema con Modernizr para que puedan agregar más controles de Modernizrs para ese navegador en particular. (Si no es así, debería hacerlo. Si encuentra algo que afecta a cientos de miles de desarrolladores, lo único correcto es presentarlo a las personas responsables de la corrección)
Mike 'Pomax' Kamermans
7
Para aquellos de nosotros que escribimos código de cara al usuario, a menudo necesita una respuesta ahora , no un error archivado en una biblioteca de terceros y un parche allí. Es decir, es bueno que quieras que mejoren Modernizr, pero aquí no encaja.
Dean J
1
Creo que detectar el navegador real es un objetivo razonable en sí mismo.
gwg
@DeanJ seguro, y para esas preguntas, alguien más proporcionará una respuesta también. Eso no hace que sea menos importante obtener respuestas como estas que le indiquen que piense en lo que está haciendo. Además, en el momento de la repetición no había modificaciones en la publicación y no se mencionaba "Lo necesito para que funcione ahora", así que no tenía ninguna razón para asumir que no querían una verificación de la realidad.
Mike 'Pomax' Kamermans