Detectando o IE11 usando o recurso CSS / detecção de recursos

88

O IE10 + não oferece mais suporte a tags de detecção de navegador para identificar um navegador.

Para detectar o IE10, estou usando JavaScript e uma técnica de teste de capacidade para detectar certos msestilos prefixados são definidos como msTouchActione msWrapFlow.

Desejo fazer o mesmo para o IE11, mas presumo que todos os estilos do IE10 também terão suporte no IE11. Alguém pode me ajudar a identificar apenas os estilos ou recursos do IE11 que eu possa usar para diferenciá-los?

Informação extra

  • Não quero usar a detecção de tipo de agente do usuário porque é muito irregular e pode ser alterada, também acho que li que o IE11 está intencionalmente tentando esconder o fato de que é o Internet Explorer.
  • Para obter um exemplo de como funciona o teste de capacidade do IE10, usei este JsFiddle (não o meu) como base para meu teste.
  • Também estou esperando muitas respostas de "Esta é uma má ideia ...". Uma das minhas necessidades para isso é que o IE10 afirma que oferece suporte a algo, mas está muito mal implementado, e quero ser capaz de diferenciar entre o IE10 e o IE11 + para poder prosseguir com um método de detecção baseado em capacidade no futuro.
  • Este teste é acoplado a um teste Modernizr que simplesmente tornará algumas funcionalidades "alternativas" para um comportamento menos glamoroso. Não estamos falando sobre funcionalidade crítica.

TAMBÉM já estou usando o Modernizr, mas não ajuda aqui. Preciso de ajuda para uma solução para minha pergunta claramente feita, por favor.

dano
fonte
3
Por que você precisa saber qual navegador o usuário possui? A detecção de recursos / prefixos css / condicionais css não são suficientes?
David-SkyMesh de
4
Esqueci de mencionar que temos nossos motivos para precisar detectar os navegadores, para os quais o teste de capacidade não ajuda. Apenas um dos nossos problemas é que o IE10 diz que suporta algo, mas não o faz muito bem.
dano de
2
@ David-SkyMesh - Não. Infelizmente, não é o suficiente. Eu gostaria que fosse, mas não é.
dano de
1
@Evildonald Você não respondeu por que precisa saber - especificamente. Pode ser que este seja um problema XY. (ou seja: você está pedindo para ajudar com o X - detecção do IE11 - quando poderíamos responder a uma pergunta diferente Y - como ser compatível com mais navegadores, incluindo o IE11 para a TAREFA Z)
David-SkyMesh
1
Eu tinha um .js que detecta as versões do navegador e dizia que o ie11 era um firefox. o que está acontecendo, ou seja, desenvolvedores!
Daniel Cheung

Respostas:

163

À luz do segmento em evolução, atualizei o seguinte:

IE 6

* html .ie6 {property:value;}

ou

.ie6 { _property:value;}

IE 7

*+html .ie7 {property:value;}

ou

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

IE 6 e 7

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

ou

.ie67 { *property:value;}

ou

.ie67 { #property:value;}

IE 6, 7 e 8

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

IE 8

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

ou

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

Modo padrão do IE 8 apenas

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

IE 8,9 e 10

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

Apenas IE 9

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

IE 9 e superior

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

Apenas IE 10

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

IE 10 e superior

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

ou

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

O uso de -ms-high-contrastsignifica que o MS Edge não será o alvo, pois o Edge não oferece suporte-ms-high-contrast .

IE 11

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

Alternativas de Javascript

Modernizr

Modernizr é executado rapidamente no carregamento da página para detectar recursos; em seguida, ele cria um objeto JavaScript com os resultados e adiciona classes ao elemento html

Seleção de agente de usuário

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

Adiciona (por exemplo) o seguinte ao 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'

Permitindo seletores CSS muito direcionados, por exemplo:

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

Nota de rodapé

Se possível, identifique e corrija quaisquer problemas sem hacks. Suporta aprimoramento progressivo e degradação elegante . No entanto, este é um cenário de 'mundo ideal' nem sempre possível, como tal - o acima deve ajudar a fornecer algumas boas opções.


Atribuição / leitura essencial

SW4
fonte
3
Esta realmente deveria ser a resposta. Grande detalhe!
egr103 de
O IE10 só não funciona para mim. A barra invertida-9 não remove o IE11. Estou tentando mostrar um div para o IE 10, mas não para o IE11 ... Ele ainda aparece no IE 11 ...
Merc
Ah estranho. Ele funciona na maioria das propriedades, mas clip: auto\9;ainda é interpretado como clip: auto;no IE 11. De alguma forma, isso não é ignorado ...
Merc
2
Para mim, a segunda opção do IE10 funcionou para o IE11: @media all and (-ms-high-contrast: none), (-ms-high-contrast: active) { .relevant_selectors_for_situation {property:value;} }eu a encontrei em mediacurrent.com/blog/…
cedricdlb
1
Depois de ler tudo isso, acho que -ms-high-contrast: activepode ser algo a evitar, porque de acordo com as especificações da MS, você realmente terá como alvo os usuários de tema de alto contraste no Edge com as regras do IE 10/11. Na página esta resposta está vinculada a sobre -ms-high-contrast, na verdade, diz que apenas o -ms-high-contrast: nonevalor não é mais compatível. Acho que ninguém menciona isso porque a maioria das pessoas não tem o modo de alto contraste habilitado e a maioria das pessoas não usa o Edge. Mas ainda assim, há alguém por aí que tem essa configuração e isso provavelmente não é legal para eles.
dmatamales
37

Para direcionar apenas o IE10 e o IE11 (e não o Edge):

@media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {  
   /* add your IE10-IE11 css here */   
}
Apps Tawale
fonte
1
Algo assim também pode ser um mixin atrevido!
dano de
2
Isso é direcionado apenas ao IE11 ou ao Edge também?
Matthew Felgate
2
Destina-se ao IE10 e ao IE11, mas não à borda.
Jeff Clayton de
23

Então, no final, encontrei minha própria solução para esse problema.

Depois de pesquisar na documentação da Microsoft consegui encontrar um novo estilo apenas do IE11msTextCombineHorizontal

Em meu teste, eu verifico se há estilos do IE10 e, se eles forem uma correspondência positiva, verifico apenas o estilo IE11. Se eu encontrar, é o IE11 +; se não, é o IE10.

Exemplo de código: detectar IE10 e IE11 por teste de capacidade CSS (JSFiddle)

Vou atualizar o exemplo de código com mais estilos quando os descobrir.

NOTA: Isso quase certamente identificará o IE12 e o IE13 como "IE11", pois esses estilos provavelmente continuarão. Adicionarei mais testes à medida que novas versões forem lançadas e, com sorte, poderei confiar novamente na Modernizr.

Estou usando este teste para comportamento de fallback. O comportamento substituto é apenas um estilo menos glamoroso, não tem funcionalidade reduzida.

dano
fonte
8
Se alguém vai -1 esta resposta, por favor, pelo menos tenha a decência de confessá-la com um motivo técnico . Você pode discordar disso .. mas está correto e funciona.
dano de
7
Como você sabe se este código produzirá resultados corretos no IE12, IE13 e assim por diante?
Evgeny
6
Por que você está usando este método em vez de if (document.documentMode === 11) { ... }? A menos, é claro, que você queira usar a propriedade CSS em uma @supportsregra at (que ainda não é compatível com o IE, a propósito).
Rob W
1
Se você tiver classes existentes em sua tag body, isso as substituirá. Aqui está a correção mínima: jsfiddle.net/jmjpro/njvr1jq2/1 .
jbustamovej
1
Além disso, você deseja ocultar o elemento ieVersion com css: #ieVersion {display: none}
jbustamovej
19

Isso parece funcionar:

@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
fonte
Este não diferencia entre ie10 e ie11, mas se você não se importa em detectar também ie10, então você está bem com este.
Jeff Clayton
9

Aqui está uma resposta para 2017 em, onde provavelmente você só se preocupa em distinguir <= IE11 de> IE11 ("Edge"):

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

Exemplo mais demonstrativo:

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

Isso funciona porque o IE11 nem mesmo oferece suporte @supports, e todas as outras combinações de navegador / versão relevantes o fazem.

Jan Kyu Peblik
fonte
8

Você pode escrever seu código do IE11 normalmente e, em seguida, usar @supportse verificar se há uma propriedade que não é compatível com o IE11, por exemplogrid-area: auto .

Você pode então escrever seus estilos modernos de navegador dentro dele. O IE não suporta a @supportsregra e usará os estilos originais, ao passo que estes serão substituídos nos navegadores modernos que suportam @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
fonte
1
Isso funciona e é uma boa solução, mas o raciocínio dado não está correto. O IE11 não tem suporte @supportsnenhum, portanto, ignora tudo no @supportsbloco. Portanto, você pode colocar qualquer coisa na condição @supports (por exemplo @supports (display: block)) e o IE11 ainda irá ignorá-la.
CodeBiker
Isso é o que eu quis dizer com "O IE 11 irá ignorar", mas você está certo, isso não está totalmente claro. Atualizei a resposta para deixar mais claro que o IE não oferece suporte a @supports.
Antfish
4

Isso funcionou para mim

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

E então, no arquivo css, as coisas prefixadas com

body.ie11 #some-other-div

Quando este navegador está pronto para morrer?

Bert Oost
fonte
4

Experimente isto:

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

Dê uma olhada neste artigo: CSS: Seletores de agente de usuário

Basicamente, quando você 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':'');

Agora você pode usar CSS para direcionar qualquer navegador / versão.

Portanto, para o IE11, podemos fazer isso:

FIDDLE

html[data-useragent*='rv:11.0']
{
    color: green;
}
Danield
fonte
1
Isso iria quebrar no Firefox 11 (embora não seja compatível agora, isso importa). Ele também tem rv:11.0em sua string de agente do usuário.
PhistucK
3

Use as seguintes propriedades:

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

Você deve usar o Modernizr, ele adicionará uma classe à tag do corpo.

Além disso:

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

Observe que o IE11 ainda está em visualização e o agente do usuário pode mudar antes do lançamento.

A string do agente do usuário para o IE 11 atualmente é esta:

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

O que significa que você pode simplesmente testar, para as versões 11.xx,

var isIE11 = !!navigator.userAgent.match(/Trident.*rv 11\./)
Neo
fonte
Obrigado Neo, mas já estou adicionando uma classe ao meu body tag E usando o Modernizr. Estou procurando uma maneira de diferenciar o IE10 do IE11 sem usar o User Agent, que não é confiável.
dano de
Faltando dois pontos no rv 11. var isIE11 = !! navigator.userAgent.match (/Trident.*rv:11 \ ./)
T.CK
2

Talvez o Layout Engine v0.7.0 seja uma boa solução para sua situação. Ele usa a detecção de recursos do navegador e pode detectar não apenas IE11 e IE10, mas também IE9, IE8 e IE7. Ele também detecta outros navegadores populares, incluindo alguns navegadores móveis. Ele adiciona uma classe à tag html, é fácil de usar e tem um bom desempenho em alguns testes bastante profundos.

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

Talkingrock
fonte
2

Se você estiver usando o Modernizr , você poderá diferenciar facilmente entre o IE10 e o IE11.

O IE10 não oferece suporte à pointer-eventspropriedade. IE11 sim. ( caniuse )

Agora, com base na classe que o Modernizr insere, você pode ter o seguinte CSS:

.class
{ 
   /* for IE11 */
}

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

Você pode usar js e adicionar uma classe em html para manter o padrão de comentários condicionais :

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

Ou use uma biblioteca como o bowser:

https://github.com/ded/bowser

Ou modernizr para detecção de recursos:

http://modernizr.com/

Liko
fonte
2

Detectar o IE e suas versões é extremamente fácil, pelo menos extremamente 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;
}

.

Dessa forma, você também pegará versões altas do IE no Modo / Visualização de Compatibilidade. Em seguida, é uma questão de atribuir classes condicionais:

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

Você pode tentar isto:

if(document.documentMode) {
  document.documentElement.className+=' ie'+document.documentMode;
}
Adrian Miranda
fonte
2

Encontrei o mesmo problema com um Gravity Form (WordPress) no IE11. O estilo de coluna do formulário "display: inline-grid" quebrou o layout; aplicar as respostas acima resolveu a discrepância!

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

Dê um passo para trás: por que você está tentando detectar "internet explorer" em vez de "meu site precisa fazer X, este navegador oferece suporte a esse recurso? Se sim, bom navegador. Se não, devo alertar o usuário".

Você deve acessar http://modernizr.com/ em vez de continuar o que está fazendo.

Mike 'Pomax' Kamermans
fonte
Obrigado por uma solução alternativa, mas já estou usando o Modernizr e o IE10 representa mal seus recursos para ele.
dano de
4
Presumo que você saiba quais e tenha registrado um problema com o Modernizr para que eles possam adicionar mais verificações do Modernizrs para aquele navegador específico. (Se não, você deveria. Se você encontrar algo que afeta centenas de milhares de desenvolvedores, arquivar isso com as pessoas responsáveis ​​pelo shim é a única coisa certa a fazer)
Mike 'Pomax' Kamermans
7
Para aqueles de nós que escrevem código voltado para o usuário, muitas vezes você precisa de uma resposta agora , não um bug arquivado em uma biblioteca de terceiros e um patch lá. Ou seja, é bom que você queira que eles aprimorem a Modernizr, mas não cabe aqui.
Dean J
1
Acho que detectar o navegador real é uma meta razoável por si só.
gwg
@DeanJ com certeza, e para essas perguntas outra pessoa fornecerá uma resposta também. Isso não torna menos importante obter respostas como essas que dizem a você para pensar sobre o que está fazendo. Além disso, na época do repy não havia edições no post, e não havia menção de "Eu preciso que funcione agora", então eu não tinha motivos para supor que eles não queriam uma verificação da realidade.
Mike 'Pomax' Kamermans