Vous connaissez certainement les Media Queries CSS. Celles-ci permettent d'adapter les instructions de style appliquées à un document HTML, en fonction de nombreux critères (résolution de l'écran, dimensions, périphérique de sortie). C'est la technique la plus souple et la plus utilisée actuellement pour ajuster dynamiquement l'affichage et obtenir un rendu graphique différent sur écrans classiques, mobiles, tablettes, et autres moyens d'accéder au web.
Avec matchMedia(), les mêmes capacités de détection sont rendues disponibles en JavaScript. La syntaxe de la requête média reste la même, ce qui est bien agréable. Ainsi, il sera possible de déclencher des actions complémentaires à ce que l'on peut déjà construire en CSS, que ce soit au chargement du document ou bien à n'importe quel moment à la demande en exécutant matchMedia().
C'est une méthode qui dépend de l'objet window
(la fenêtre du navigateur) et qui prend en argument une chaîne de texte contenant l'expression à tester, pour retourner true
ou false
via sa propriété matches
.
<script>
if (window.matchMedia("(min-width: 600px)").matches) {
/* La largeur minimum de l'affichage est 600 px inclus */
} else {
/* L'affichage est inférieur à 600px de large */
}
</script>
Si l'on examine de plus près l'objet retourné dans une console JavaScript...
Celui-ci est de type MediaQueryList
, et équipé de deux propriétés de base :
-
matches
(booléentrue
/false
qui permet de faire le test) -
media
(la requête elle-même)
Bien sûr, cette méthode vient en complément de CSS et n'est pas vouée à remplacer les Media Queries là où elles sont déjà efficaces. Le but est de se brancher sur la gestion de la détection pour aller plus loin qu'une conséquence sur l'affichage des éléments.
// Fonction exécutée au redimensionnement
function redimensionnement() {
var result = document.getElementById('result');
if("matchMedia" in window) { // Détection
if(window.matchMedia("(min-width:600px)").matches) {
// Il y a de la place
} else {
// Il y en a moins...
}
}
}
// On lie l'événement resize à la fonction
window.addEventListener('resize', redimensionnement, false);
L'événement resize
est tout indiqué pour déclencher une vérification avec matchMedia()
. Consultez l'exemple suivant pour le voir en action.
Le dernier exemple va plus loin en chargeant des fichiers JavaScript selon le résultat renvoyé par matchMedia()
.
if(window.matchMedia("(min-width:800px)").matches) {
// Chargement de jQuery dans un nouvel élément <script> ajouté à la section <head>
var script1 = document.createElement('script');
script1.type='text/javascript';
script1.src = '//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js';
script1.onload = function() {
// Lorsque jQuery est chargé...
// On fait la même chose : chargement dynamique // mais cette fois-ci avec jQuery (c'est plus simple)
$.getScript('slideshow.js');
}
// Insertion dans le DOM de la balise script initiale
document.getElementsByTagName('head')[0].appendChild(script1);
}
Il s'agit de faire appel à jQuery et un autre fichier de script conçu sur mesure pour lancer un slideshow si la largeur de l'affichage le permet.
Cette technique ici sert uniquement à la démonstration et exploite un script minimaliste pour sa compréhension. L'intérêt majeur serait de pouvoir détecter ce que l'on ne peut pas faire avec du JavaScript conventionnel, par exemple l'orientation (mentionnée précédemment) ou la densité de pixels pour charger des images appropriées : une démonstration est disponible sur Thinkmobilefirst : Conditional retina pictures loading.
Tableau des compatibilités
Navigateurs | Versions |
---|---|
Internet Explorer 10 | |
Firefox 6 Firefox Android 15 |
|
Chrome 9 Chrome Mobile 18 (Android 4+) |
|
Opera 12.1 Opera Mobile 12.1 |
|
Safari 5.1 Safari Mobile 5.0 |
|
Android Browser 3.0 | |
Blackberry Browser 10 |
Pour les anciens moteurs qui ne supporteraient pas nativement matchMedia, il existe des bibliothèques JavaScript, détectant (du mieux qu'elles peuvent) les changements d'état, notamment matchMedia.js développée par Paul Irish.
Commentaires
Merci pour l'article !
Tu as déjà testé enquire.js (http://wickynilliams.github.com/enquire.js/) ?
tm
Super article,
Merci j'étais en plein dedans!! :)
Avec cette solution on peut commencer à prévoir des trucs pas mal. Par exemple, en lien avec un script jQuery comme ça pour la nav sur mobile :
http://css-tricks.com/examples/ConvertMenuToD...
Ce qui évite d'avoir des menus dupliqués, lié à un display:none sur l'un des deux menus en fonction de la résolution... comme on peut voir sur beaucoup de sites (pas très gracieux je trouve).
hello,
J'ai appliqué les media queries sur mon site.
Ce que j'ai fais, c'est vraiment une version différente du site lorsque l'écran est a moins de 800px. Du coup je me retrouve dans le HTML à avoir parfois 2 fois mon contenu. Au niveau de l'utilisateur ça ne change rien, mais est ce que c'est pas un problème pour le référencement ? Est ce que google peut sanctionner le fait d'avoir du contenu similaire non visible ? Merci
( http://www.geoffrey-menissier.fr )
@geoffreym tu devrais essayer de voir pour les max 1024 aussi.
Super article. Ça va bien m'aider dans mes projets. Merci.