Mentiras, mentiras e o navegador padrão do Android

Enquanto trabalhava em um site responsivo que apresentava algumas CSS 3D Transforms, descobri que, por algum motivo, clicar em uma entrada de texto para digitar no Android 2.3 e versões anteriores fazia com que a rolagem automática para a entrada exibisse um comportamento estranho de yoyo. Ele iria pular cerca de 300 px longe demais, pular um pouco para cima, pular para baixo novamente, para cima mais uma vez e se estacionar algumas centenas de pixels ao sul do local de entrada real.

Depois de muita confusão, percebi que estava relacionado a outro bug: o suporte incompleto do navegador Android padrão para transformações e transições CSS 3D.

Apesar de a Modernizr relatar que é compatível, o Android 2.3 e versões anteriores não conseguirão realizar uma transformação rotateY de maneira adequada, em vez de realizar uma rotação regular. Além disso, a própria presença de um elemento com propriedades de transição 3D parece causar o comportamento de saltos no foco de entrada.

Como a detecção de recurso produz um falso positivo, tive que detectar a versão do Android que está sendo executada por meio da string do agente do usuário e adicionar uma classe ao corpo conforme necessário, para que pudesse direcioná-la separadamente e forçar a animação de fallback que escrevi para começar no Gingerbread, FroYo e abaixo (para ser seguro, eu também adicionei Honeycomb, já que não tinha um tablet Android 3 para ver se funcionava nele).

var ua = navigator.userAgent.toLowerCase();
var isOldAndroid = /android [1-3]/i.test( ua );