Os recursos e técnicas que estão surgindo com HTML5 e CSS3 são fenomenais e estão levando a web para um próximo nível. Mas o que fazer se já for preciso usar alguns destes recursos ? Como lidar com browsers que ainda não suportam todas as features de HTML5 + CSS3? A solução tem nome: Modernizr.

Modernizr logo símbolo

Modernizr é uma biblioteca JavaScript que detecta quais features de HTML5 e CSS3 o navegador de quem visita o site suporta. Isso permite aos desenvolvedores testar algumas das novas tecnologias e, em seguida, fornecer fallbacks para navegadores que ainda não as suportam. Isto é chamado de feature detection (detecção de característica) e é muito mais eficiente do que browser sniffing.

O Modernizr é muito útil para detectar suporte a CSS3, mas este artigo focará em HTML5. Mas não é preciso se preocupar, já que os princípios são, essencialmente, os mesmos.

Também é importante ter em mente que o Modernizr não “preenche as lacunas” (polyfill). Ele só detecta quais características são suportadas. Mas é possível usar usar o Modernizr como parte do processo de polyfilling.

Começando a usar o Modernizr

Primeiramente, vamos precisar de um pouco de HTML (HTML5, claro!):

É possível notar no código acima que o arquivo modernizr.js é necessário. É preciso gerar e baixar o arquivo no site do Modernizr, escolhendo as características que serão precisas serem detectadas. Isso ajuda a ter um arquivo modernizr.js com tamanho adequado às necessidades do projeto, já que não é preciso detectar tudo o que o Modernizr é capaz. Há, também, uma versão “development” no site para começar o desenvolvimento rapidamente. Mas, quando for colocar o site em produção, lembre-se de gerar um arquivo personalizado!

Modernizr: tela de download

Tela de download do Modernizr

Ainda observando o trecho de código acima, veja que na segunda linha há uma classe “no-js” no html. O Modernizr funciona substituindo essa classe pela classe “js”; então, ele adiciona classes para todas as features que o navegador suporta e, também, para os recursos que ele não suporta, pré-fixando estas com “no-“. Por exemplo:

Detecções explícitas com Modernizr

O Modernizr cria um objeto JavaScript global Modernizr que permite consultar diferentes propriedades desse objeto para realizar a detecção de recursos, chamando Modernizr.<feature>. Por exemplo, para testar o suporte a canvas, o código seria:

Como bons desenvolvedores web que somos, nosso objetivo é escrever JavaScript não obstrusivo e progressivo para que todos possam usar o site, portanto, é preciso tomar alguma ação para o caso da feature não ser suportada:

Ou, caso se queira testar somente a “negação”:

Detecção de recursos e Polyfilling com YepNope

Antes de continuar, caso ainda não saiba o que é “Polyfill”, veja este definição do Paul Irish:

Um shim que imita uma API futura, fornecendo funcionalidades de fallback para navegadores mais antigos.

Para maiores informações, leia (em inglês) o artigo “What is a Polyfill?” de Remy Sharp. Voltando ao artigo…

Nos exemplos JavaScript acima, foi mostrada a maneira mais simples de detectar um recurso de browsers usando o Modernizr. Mas e se você quiser detectar um recurso e usar um polyfill para tornar a performance do navegador melhor? É possível, usando YepNope.

YepNope é um carregador condicional, que significa que ele só irá carregar os scripts que são necessários para o browser. E ele já está incluso no Modernizr! Dessa forma, não é preciso se preocupar com downloads e links para outros arquivos JavaScript. Mas como usar o YepNope junto com o Modernizr?

Utilizando canvas como exemplo novamente, geralmente é preciso uma alternativa (fallback) para os navegadores que não o suportam (por exemplo, IE8). A maneira usual de se fazer isso é um link para um polyfill, tal como o FlashCanvas:

O problema dessa abordagem é que todos os navegadores irão baixar este script. Isso é desnecessário, pois impacta a performance do site, e deve ser evitado sempre que possível. É possível envolver o elemento script em comentários condicionais, mas, caso seja possível manter os arquivos condicionais fora da marcação, então isso é preferível. Isso é possível de ser feito usando Modernizr.load(). Já que o Modernizr tem o YepNope embutido, é facilmente possível testar um recurso e, em seguida, fornecer um polyfill:

A função .load(), por padrão, não está inclusa no arquivo de desenvolvimento do Modernizr. É preciso incluí-la ao gerar o arquivo de download apropriado, conforme mostrado no início do artigo.

O uso básico da função .load() permite que testar a presença de uma feature. Veja este exemplo em que o Modernizr testa o suporte para canvas e, caso o browser não a suporte, ele carrega o FlashCanvas:

Usando as developer tools do IE8, na aba “Network” é possível ver o download e inicialização do flashcanvas.js. Legal, hã? ;-)

Modernizr + YepNope: checando downloads condicionais no IE8

Modernizr + YepNope: checando downloads condicionais no IE8

Vamos a um exemplo mais prático que detecta o suporte a <input type="date">. Se não for suportado, haverá o carregamento de 2 arquivos jQuery e um arquivo CSS para gerar um seletor de datas:

Na maioria dos navegadores, o jQuery será carregado, mas, no Opera, não haverá essa necessidade, já que ele já possui um seletor de datas nativo por já suportar <input type="date">.

Seletor de datas no Firefox

Seletor de datas no Opera

E, como você já deve ter imaginado, carregar ou não 2 arquivos JavaScript e uma folha de estilos gera uma grande diferença na performance do site.

Comparação de recursos ao carregar datapicker: Firefox x Opera

Comparação de recursos ao carregar datapicker: Firefox x Opera

Observe como os 2 arquivos jQuery são carregados duas vezes. Isso acontece, mesmo, no YepNope: primeiro ele carrega o recurso e, em seguida, executa-o. Então, não se preocupe, pois isso é normal. E veja, também, todas as propriedades do objeto de teste do YepNope, conhecê-las pode ser bastante útil!

Conclusão

Como pôde ser visto, Modernizr é uma poderosa biblioteca de detecção de features. Ela permite verificar se o navegador suporta vários recursos e, dependendo do resultado, permite que sejam usados polyfills. Este artigo analisou como gerar um arquivo Modernizr e suas 2 maneiras de uso: usando diretamente o objeto Modernizr (Modernizr.<feature>) e, em seguida, usando YepNope.

Com isso, damos mais um passo rumo ao desenvolvimento de uma web melhor, mais profissional e com desenvolvedores mais conscientes das limitações intrínsecas aos diversos dispositivos que podem ser usados para se acessar um site. Sabíamos do “mal”, agora conhecemos a cura.