Bootstrap 3, sistema de grade e telas pequenas de alta densidade detectadas como XS

Recentemente, tenho desenvolvido um site usando bootstrap 3 e me deparei com um problema bobo. Eu queria usar o sistema de grade responsivo do bootstrap bonito. No design, havia uma coluna no telefone celular no modo retrato e 2 colunas no modo paisagem. Tudo estava indo bem até que tentei visualizá-lo no iPhone 5 e no Nexus 7 2. As consultas de mídia do Bootstrap detectaram o iPhone 5 (em paisagem) e o Nexus 7 como dispositivos XS, portanto, eu poderia ter visto apenas uma coluna.

O problema é que esses dispositivos têm telas de alta densidade, portanto, dispositivos com largura de tela de 1200px estão sendo detectados como 600px. As consultas de mídia do Bootstrap verificam apenas a largura.

Mas ei !, eu disse, a tela é grande o suficiente, quero 2 colunas.

Então eu vim com aquela solução quase não-hacky ( 568pxé a largura da tela do iPhone5 no modo paisagem):

@media only screen and (-webkit-min-device-pixel-ratio: 2) and (min-width: 568px) {
.col-sm-6 {
float: left;
width
: 50%;
}
}

É assim que parece em LESS:

@media 
only screen
and
(-webkit-min-device-pixel-ratio: 2) and (min-width: 568px) {
.col-sm-6 {
float: left;
width
: percentage((6 / @grid-columns));
}
}

Claro – se menos estiver disponível – você poderia criar outro conjunto de classes col- * e mixins relacionados dedicados a pequenos displays de retina baseados em mixins de bootstrap originais (como por exemplo .make-xs-column), mas para minha solução você precisa apenas de css puro.

Como alternativa, você pode resolver o problema usando JS.

Em seu html, você deve ter uma linha semelhante a esta:

<meta name="viewport" content="width=device-width, initial-scale=1.0">

A ideia é alterar isso initial-scaleusando JS para que seja adequado para a proporção de pixel atual.

var scale = 1 / (window.devicePixelRatio || 1);
var content = 'width=device-width, initial-scale=' + scale + ', minimum-scale=' + scale;

document
.querySelector('meta[name="viewport"]').setAttribute('content', content);

Sinta-se à vontade para comentar e sugerir a melhor solução 🙂