Detectar si las CSS media queries se cumplen o no, usando programación Javascript.
Son de sobra conocidas las CSS Media queries, que nos permiten detectar distintas características de los dispositivos para aplicar unos estilos u otros en función de ellas.
Seguramente las usamos intensivamente en nuestros desarrollos, pero desde CSS. En este artículo veremos cómo podemos hacerlo desde Javascript. Se trata de una práctica muy fácil, que usa un API de Javascript que tiene total soporte en los navegadores, como podemos ver en la siguiente imagen:
¿Por qué detectar las media queries desde Javascript?
Es menos habitual que desde Javascript necesitemos detectar si ciertas media queries se están evaluando positivamente, pero también nos podemos ver en necesidad de ello. Hay veces que ciertos mecanismos es solo necesario realizarlos cuando estamos viendo la página en un ordenador con pantalla grande, pero no en un móvil o un tablet
Pongamos por ejemplo que tenemos un código de un banner que solamente queremos que se vea en ordenadores de escritorio. Este código hace llamadas asíncronas para solicitar la creatividad al servidor de banners, pero si el banner no se va a visualizar, ¿Qué sentido tiene hacer esas llamadas al servidor de banners?
Si el banner siempre aparece en la página y simplemente lo ocultamos y mostramos con CSS, entonces, por mucho que no se vea en las pantallas de los móviles, se estaría haciendo la solicitud del banner y gastando un ancho de banda innecesario. En lugar de eso, podemos simplemente detectar con Javascript cuándo estamos en un ordenador de escritorio, para colocar dinámicamente el código del banner solamente en ese caso.
Es un ejemplo entre muchos que se nos pueden ocurrir. Por unas o por otras, las necesidades de detectar mediaqueries llegarán. No me voy a enrollar más para poder pasar a la práctica.
Método matchMedia para testar media queries
El método que vamos a usar para poder comprobar si una media query se cumple se llama matchMedia(). Está dentro del objeto "window".
var mediaqueryList = window.matchMedia("(min-width: 500px)");
El método matchMedia() te devuelve un objeto "mediaquery list". Básicamente te informa sobre la mediaquery que se ha comprobado y su valor.
Si queremos ver si esta media query se cumple en un momento dado, simplemente tenemos que evaluar la propiedad "matches" de este objeto.
if(mediaqueryList.matches) {
alert('La media query se cumple');
}
Ese objeto "mediaqueryList" es dinámico, en el sentido que, si las condiciones del navegador cambian a lo largo del tiempo, también cambiará la propiedad "matches". Por tanto, podría ocurrir que esa evaluación tenga resultados distintos en momentos distintos, si por ejemplo el usuario redimensiona la ventana del navegador.
Definir un manejador de evento para atender cambios en la evaluación de las media queries
Lo más seguro es que en tu aplicación quieras estar pendiente de los cambios en las media queries que estés evaluando con Javascript, para realizar acciones cuando esto ocurra.
Claro que podrías preguntar constantemente por el valor de la propiedad "matches", pero lo más eficiente es asociar un manejador de eventos para realizar acciones justamente cuando esa media query cambie de valor.
Esto lo conseguimos con el método "addListener" del objeto mediaqueryList, tal como se puede ver a continuación.
var mediaqueryList = window.matchMedia("(max-width: 920px)");
mediaqueryList.addListener( function(EventoMediaQueryList) {
console.log('Ejecutado el listener', EventoMediaQueryList);
});
En este caso hemos asociado una función anónima como manejador de eventos. En esa función recibimos un objeto de tipo "MediaQueryListEvent", que nos ofrece información detallada sobre el evento que se ha producido.
Comprobar si después de ese evento se cumple o no la media query es tan sencillo como volver a evaluar su propiedad "matches", usando en este caso el propio objeto evento que estamos recibiendo por parámetro en el navegador.
var mediaqueryList = window.matchMedia("(orientation: portrait)");
mediaqueryList.addListener( function(EventoMediaQueryList) {
if(EventoMediaQueryList.matches) {
// Realizamos las acciones cuando cambia el estado de la mediaquery y ahora cumple su valor
alert('Ahora has pasado a modo portrait, con tu pantalla orientada en vertical');
} else {
alert('Ahora has pasado a modo landscape, con tu pantalla orientada en horizontal');
}
});
Puedes eliminar el manejador de eventos en cualquier momento, con el método removeListener(). Solo que para usarlo no puedes haber asociado el manejador con una función anónima como hemos hecho antes.
El código nos quedaría más o menos como el que sigue:
var mediaqueryList = window.matchMedia("(orientation: portrait)");
function manejador(EventoMediaQueryList) {
if(EventoMediaQueryList.matches) {
alert('La media query ahora se cumple');
} else {
alert('La media query ya no se cumple');
}
}
// asociamos el manejador de evento
mediaqueryList.addListener(manejador);
// quitamos el manejador de evento para dejar de recibir notificación de cambios
mediaqueryList.removeListener(manejador);
Conclusión
Con esto hemos aprendido a manejar el estado de las media queries de manera programática, es decir, mediante código que se ejecutará mediante Javascript en el navegador.
No es una práctica que se necesite todos los días ni en todos los proyectos, pero llegará un día que te resulte de utilidad. Dado a su amplio soporte generalizado, puedes hacer uso de lo que has aprendido en cualquier sitio web donde necesites estar atento a los cambios de una media query y realizar acciones Javascript cuando se produzca.
Recuerda que puedes ver muchas otras prácticas para hacer diseños adaptables a las condiciones del navegador en el Manual de Responsive Web Design
Miguel Angel Alvarez
Fundador de DesarrolloWeb.com y la plataforma de formación online EscuelaIT. Com...