Responsive JS media queries, Bootstrap-compatible

##Responsive?

Tout le monde a un smartphone, ou presque. Et presque tout le monde a une tablette chez les geeks.
Il serait dommage de ne pas soigner ces lecteurs. Une bonne partie d’entre eux consomme du web en situation de mobilité. Et aujourd’hui, nous n’avons plus d’excuse à ne pas faire un site responsive : des frameworks CSS aussi communs que Twitter Bootstrap nous mâchent complètement le travail.

Maintenant, supposons que vous produisiez du contenu par JavaScript. Du genre large le contenu. Par exemple de l’ASCII-art, comme sur la home de Ninja Squad, affiché dans un simili-terminal :

 _____ _     _        _____               _ 
|   | |_|___|_|___   |   __|___ _ _ ___ _| |
| | | | |   | | .'|  |__   | . | | | .'| . |
|_|___|_|_|_| |__,|  |_____|_  |___|__,|___|
          |___|              |_|            

Pourquoi ce contenu n’aurait-il pas droit, lui aussi, a être responsive? Sur un smartphone, sa largeur est trop grande, j’aimerais que les deux mots s’affichent sur deux lignes. Comme ça :

   _____ _     _       
  |   | |_|___|_|___   
  | | | | |   | | .'|  
  |_|___|_|_|_| |__,|  
 _____      |___|    _ 
|   __|___ _ _ ___ _| |
|__   | . | | | .'| . |
|_____|_  |___|__,|___|
        |_|            

Je suis d’accord, ce use-case n’est pas le plus commmun. Mais à quoi bon faire un blog post sur un sujet bateau, sinon?

##CSS3 media queries

CSS3, grâce aux media queries, permet de styler le contenu en fonction de caractéristiques d’affichage : ratio, device, ou dimensions. C’est ce que met en oeuvre Twitter Bootstrap pour assurer le responsive. Ainsi, il adapte sa grille naturellement, transformant les colonnes en lignes quand la largeur ne suffit plus.

Des classes CSS (.visible-desktop, .hidden-phone, etc…) vous permettent même de masquer ou afficher du contenu en fonction d’un type de device visé.

Par exemple :

<span class="visible-desktop">Hello Desktop!</span>
<span class="visible-tablet">Hello Tablet!</span>
<span class="visible-phone">Hello Phone!</span>

affiche :

Hello Desktop! Hello Tablet! Hello Phone!

Essayez de redimensionner la fenêtre de votre navigateur, si vous êtes sur desktop : bim!, le texte affiché dépend de la largeur du navigateur. “Toute technologie suffisamment avancée est indiscernable de la magie” disait Arthur C. Clarke. Et c’est magique!

En fait, Arthur C. Clarke n’avait probablement pas lu le source de Bootstrap : une simple media query testant uniquement la largeur d’ecran affiche ou masquant ces classes en fonction. Par exemple, pour les devices de type phone :

@media (max-width: 767px) {
  .visible-desktop   { display: none !important; }
  // etc.
}

Bootstrap permet donc nativement de rendre responsive notre contenu HTML. C’est déjà énorme. Mais ça ne répond pas encore à notre besoin initial.
Maintenant, comment mettre en oeuvre ces fonctionnalités en JavaScript?

##JS window.matchMedia()

Une fonction JS permet de tester des media queries CSS : window.matchMedia.

Le support de window.matchMedia est encore assez limité. Heureusement, Paul Irish nous fournit un polyfill assurant la compatibilité avec les navigateurs plus anciens.

En réutilisant les queries definies par Bootstrap, on peut donc se définir des fonctions utilitaires JavaScript testant les types de devices conformes à Bootstrap :

window.matchMediaPhone = function() {
    return matchMedia('(max-width: 767px)').matches;
}
window.matchMediaTablet = function() {
    return matchMedia('(min-width: 768px) and (max-width: 979px)').matches;
}
window.matchMediaDesktop = function() {
    return matchMedia('(min-width: 979px)').matches;
}

Cela nous permet d’écrire du code comme : if (matchMediaPhone()) return "Hello Phone!";

Nous avons ainsi tout en main pour produire le ASCII-art qui nous intéresse en fonction du media.

<pre id='ascii'></pre>
<script>
  function draw() {
    var ascii;
    if (matchMediaDesktop()) {
      ascii = "...Desktop ASCII-art...";
    } else if (matchMediaTablet()) {
      ascii = "...Tablet ASCII-art...";
    } else if (matchMediaPhone()) {
      ascii = "...Phone ASCII-art...";
    }
    document.getElementById('ascii').innerHtml = ascii;
  }
  window.setInterval(draw(), 500);
</script>

Nous voilà avec un magnifique ASCII-art responsive :

ASCII

N’hésitez pas à redimensionner la fenêtre de votre navigateur pour maximiser le Wow effect!
Et voilà, commme disent les américains francophones et les francophones américanophiles.

Success!


PS : cet article, ce blog, et le site de Ninja Squad sont évidemment responsive.



blog comments powered by Disqus