Una guía completa para el uso de consultas de medios en JavaScript
La mayoría de los sitios web modernos utilizan técnicas de diseño web receptivo para garantizar que se vean bien, sean legibles y sigan siendo utilizables en dispositivos con cualquier tamaño de pantalla, es decir, teléfonos móviles, tabletas, computadoras portátiles, monitores de PC de escritorio, televisores, proyectores y más.
Los sitios que utilizan estas técnicas tienen una sola plantilla, que modifica el diseño en respuesta a las dimensiones de la pantalla:
- Las pantallas más pequeñas suelen mostrar una vista lineal de una sola columna donde los controles de la interfaz de usuario, como los menús, se activan al hacer clic en los iconos (hamburguesa).
- Las pantallas más grandes muestran más información, quizás con barras laterales alineadas horizontalmente. Los controles de la interfaz de usuario, como los elementos del menú, siempre pueden estar visibles para facilitar el acceso.
Una gran parte del diseño web receptivo es la implementación de una consulta de medios CSS o JavaScript para detectar el tamaño del dispositivo y ofrecer automáticamente el diseño apropiado para ese tamaño. Vamos a discutir por qué estas consultas son importantes y cómo trabajar con ellas, pero primero, analicemos el diseño receptivo en general.
¿Por qué es importante el diseño receptivo?
Es imposible proporcionar un diseño de página único y esperar que funcione en todas partes.
Cuando los teléfonos móviles obtuvieron por primera vez acceso a la web rudimentario a principios de la década de 2000, los propietarios de sitios a menudo creaban dos o tres plantillas de página independientes basadas libremente en las vistas de dispositivos móviles y de escritorio. Eso se volvió cada vez más impráctico a medida que la variedad de dispositivos crecía exponencialmente.
Hoy en día, existen numerosos tamaños de pantalla que van desde pequeñas pantallas de reloj de pulsera hasta enormes monitores de 8 K y más. Incluso si solo considera los teléfonos móviles, los dispositivos recientes pueden tener una resolución más alta que muchas computadoras portátiles de gama baja.
El uso de dispositivos móviles también ha crecido más allá del de las computadoras de escritorio. A menos que su sitio tenga un conjunto específico de usuarios, puede esperar que la mayoría de las personas accedan a él desde un teléfono inteligente. Los dispositivos de pantalla pequeña ya no son una ocurrencia tardía y deben considerarse desde el principio, a pesar de que la mayoría de los diseñadores web, desarrolladores y clientes continúan usando una PC estándar.
Google ha reconocido la importancia de los dispositivos móviles. Los sitios se clasifican mejor en la búsqueda de Google cuando se pueden usar y funcionan bien en un teléfono inteligente. El buen contenido sigue siendo vital, pero un sitio de carga lenta que no se adapta a las dimensiones de la pantalla de su base de usuarios podría dañar su negocio.
Finalmente, considere la accesibilidad. Un sitio que funcione para todos, sin importar qué dispositivo estén usando, llegará a una audiencia más amplia. La accesibilidad es un requisito legal en muchos países, pero incluso si no es donde se encuentra, tenga en cuenta que más espectadores generarán más conversiones y una mayor rentabilidad.
¿Cómo funciona el diseño receptivo?
La base del diseño receptivo son las consultas de medios: una tecnología CSS que puede aplicar estilos de acuerdo con métricas como el tipo de salida (pantalla, impresora o incluso voz), las dimensiones de la pantalla, la relación de aspecto de la pantalla, la orientación del dispositivo, la profundidad del color y la precisión del puntero. . Las consultas de medios también pueden tener en cuenta las preferencias del usuario, incluidas las animaciones reducidas, el modo claro / oscuro y un mayor contraste.
Los ejemplos que hemos mostrado demuestran las consultas de medios utilizando solo el ancho de la pantalla, pero los sitios pueden ser considerablemente más flexibles. Consulte el conjunto completo de opciones en MDN para obtener más detalles.
El soporte de consultas de medios es excelente y ha estado en los navegadores durante más de una década. Solo IE8 y versiones inferiores no tienen soporte. Ignoran los estilos aplicados por las consultas de medios, pero esto a veces puede ser un beneficio (lea más en el Mejores prácticas sección siguiente).
Hay tres formas estándar de aplicar estilos mediante consultas de medios. El primero carga hojas de estilo específicas en código HTML. Por ejemplo, la siguiente etiqueta carga el wide.css hoja de estilo cuando un dispositivo tiene una pantalla de al menos 800 píxeles de ancho:
<link rel="stylesheet" media="screen and (min-width: 800px)" href="https://kinsta.com/blog/javascript-media-query/wide.css" />
En segundo lugar, las hojas de estilo se pueden cargar condicionalmente en archivos CSS mediante un @import en regla:
/* main.css */
@import url("https://kinsta.com/blog/javascript-media-query/wide.css") screen and (min-width: 800px);
Por lo general, aplicará consultas de medios en hojas de estilo utilizando un bloque de regla de @media CSS que modifica estilos específicos. Por ejemplo:
/* default styles */
main {
width: 400px;
}
/* styles applied when screen has a width of at least 800px */
@media screen and (min-width: 800px) {
main {
width: 760px;
}
}
Los desarrolladores pueden aplicar las reglas de consulta de medios que sean necesarias para adaptar el diseño de un sitio.
Prácticas recomendadas de Media Query
Cuando se idearon las consultas de medios por primera vez, muchos sitios optaron por un conjunto de diseños rígidamente fijos. Esto es conceptualmente más fácil de diseñar y codificar porque replica de manera efectiva un conjunto limitado de plantillas de página. Por ejemplo:
- Los anchos de pantalla inferiores a 600 píxeles utilizan un diseño similar al de un dispositivo móvil de 400 píxeles de ancho.
- Los anchos de pantalla entre 600px y 999px usan un diseño similar a una tableta de 600px de ancho.
- Los anchos de pantalla superiores a 1000 píxeles utilizan un diseño similar al de un escritorio de 1000 píxeles de ancho.
La técnica es defectuosa. Los resultados en pantallas muy pequeñas y muy grandes pueden parecer deficientes, y es posible que se requiera el mantenimiento de CSS a medida que los dispositivos y los tamaños de pantalla cambian con el tiempo.
Una mejor opción es utilizar un diseño fluido que priorice los dispositivos móviles con puntos de interrupción que adapten el diseño a ciertos tamaños. En esencia, el diseño predeterminado utiliza los estilos de pantalla pequeña más simples que colocan elementos en bloques verticales lineales.
Por ejemplo, <article> y <aside> dentro de una <main> envase:
/* default small-screen device */
main {
width: 100%;
}
article, aside {
width: 100%;
padding: 2em;
}
Este es el resultado en todos los navegadores, incluso en los más antiguos que no admiten consultas de medios:
Captura de pantalla de ejemplo sin soporte de consulta de medios.
Cuando se admiten consultas de medios y la pantalla excede un ancho específico, digamos 500 px, el <article> y <aside> los elementos se pueden colocar horizontalmente. Este ejemplo usa una cuadrícula CSS, donde el contenido principal usa aproximadamente dos tercios del ancho y el contenido secundario usa el tercio restante:
/* larger device */
@media (min-width: 500px) {
main {
display: grid;
grid-template-columns: 2fr 1fr;
gap: 2em;
}
article, aside {
width: auto;
padding: 0;
}
}
Aquí está el resultado en pantallas más grandes:
Captura de pantalla de ejemplo con soporte para consultas de medios.
Alternativas de consulta de medios
Los diseños receptivos también se pueden implementar en CSS moderno utilizando propiedades más nuevas que adaptan intrínsecamente el diseño sin examinar las dimensiones de la ventana gráfica. Las opciones incluyen:
calc,min-width,max-width,min-height,max-heighty el mas nuevoclampLa propiedad puede definir dimensiones que dimensionen los elementos de acuerdo con límites conocidos y el espacio disponible.- Las unidades de ventana gráfica
vw,vh,vmin, yvmaxPuede dimensionar elementos de acuerdo con las fracciones de dimensión de la pantalla. - El texto se puede mostrar en columnas CSS que aparecen o desaparecen según lo permita el espacio.
- Los elementos se pueden dimensionar de acuerdo con los tamaños de sus elementos secundarios usando
min-content,fit-content, ymax-contentdimensiones. - CSS flexbox puede envolver – o no wrap – elementos que comienzan a exceder el espacio disponible.
- Los elementos de la cuadrícula CSS se pueden dimensionar con una fracción proporcional
frunidades. La función de repetición de CSS se puede utilizar junto conminmax,auto-fit, yauto-fillpara asignar espacio disponible. - Las consultas de contenedor CSS nuevas y (actualmente) experimentales pueden reaccionar al espacio parcial disponible para un componente dentro de un diseño.
Estas opciones están más allá del alcance de este artículo, pero a menudo son más prácticas que las consultas de medios más crudas, que solo pueden responder a las dimensiones de la pantalla. Si puede lograr un diseño sin consultas de medios, probablemente usará menos código, será más eficiente y requerirá menos mantenimiento con el tiempo.
Dicho esto, hay situaciones en las que las consultas de medios siguen siendo la única opción de diseño viable. Siguen siendo esenciales cuando necesita considerar otros factores de la pantalla, como las relaciones de aspecto, la orientación del dispositivo, la profundidad del color, la precisión del puntero o las preferencias del usuario, como las animaciones reducidas y el modo claro / oscuro.
¿Necesita consultas de medios en JavaScript?
Sobre todo hemos hablado de CSS hasta ahora. Esto se debe a que la mayoría de los problemas de diseño pueden, y deberían – resolverse solo en CSS.
Sin embargo, hay situaciones en las que es práctico utilizar una consulta de medios de JavaScript en lugar de CSS, como cuando:
- Un componente, como un menú, tiene una funcionalidad diferente en pantallas grandes y pequeñas.
- El cambio hacia y desde el retrato / paisaje afecta la funcionalidad de una aplicación web.
- Un juego táctil tiene que cambiar el
<canvas>diseño o adaptación de botones de control. - Una aplicación web se adhiere a las preferencias del usuario, como el modo oscuro / claro, animación reducida, tosquedad táctil, etc.
Las siguientes secciones muestran tres métodos que utilizan consultas de medios, u opciones similares a consultas de medios, en JavaScript. Todos los ejemplos devuelven una cadena de estado donde:
- pequeña vista = una pantalla con un ancho por debajo de 400 píxeles;
- medio vista = una pantalla con un ancho entre 400 y 799 píxeles; y
- grande vista = una pantalla con un ancho de 800 píxeles o más.
Opción 1: supervisar las dimensiones de la ventana gráfica
Esta fue la única opción en los días oscuros antes de que se implementaran las consultas de medios. JavaScript escucharía eventos de «cambio de tamaño» del navegador, analizaría las dimensiones de la ventana gráfica usando window.innerWidth y window.innerHeight (o document.body.clientWidth y document.body.clientHeight en IE antiguos) y reaccionar en consecuencia.
Este código genera el calculado pequeña, medio, o grande cadena a la consola:
const
screen = {
small: 0,
medium: 400,
large: 800
};
// observe window resize
window.addEventListener('resize', resizeHandler);
// initial call
resizeHandler();
// calculate size
function resizeHandler() {
// get window width
const iw = window.innerWidth;
// determine named size
let size = null;
for (let s in screen) {
if (iw >= screen[s]) size = s;
}
console.log(size);
}
Puede ver una demostración de trabajo aquí. (Si usa un navegador de escritorio, abra este enlace en una nueva ventana para facilitar el cambio de tamaño. Los usuarios de dispositivos móviles pueden rotar el dispositivo).
El ejemplo anterior examina el tamaño de la ventana gráfica a medida que se cambia el tamaño del navegador; determina si es pequeño, mediano o grande; y lo establece como una clase en el elemento del cuerpo, que cambia el color de fondo.
Las ventajas de este método incluyen:
- Funciona en todos los navegadores que pueden ejecutar JavaScript, incluso en aplicaciones antiguas.
- Está capturando las dimensiones exactas y puede reaccionar en consecuencia.
Las desventajas:
- Es una técnica antigua que requiere un código considerable.
- ¿Es demasiado exacto? ¿Realmente necesitas saber cuándo el ancho es de 966 px frente a 967 px?
- Es posible que deba hacer coincidir manualmente las dimensiones con una consulta de medios CSS correspondiente.
- Los usuarios pueden cambiar el tamaño del navegador rápidamente, lo que hace que la función del controlador se ejecute nuevamente cada vez. Esto puede sobrecargar los navegadores más antiguos y lentos al limitar el evento. Solo se puede activar una vez cada 500 milisegundos.
En resumen, no supervise las dimensiones de la ventana gráfica a menos que tenga requisitos de tamaño muy específicos y complejos.
Opción 2: definir y supervisar una propiedad personalizada de CSS (variable)
Esta es una técnica un poco inusual que cambia el valor de una cadena de propiedad personalizada en CSS cuando se activa una consulta de medios. Las propiedades personalizadas son compatibles con todos los navegadores modernos (pero no IE).
En el siguiente ejemplo, el --screen custom property se establece en «pequeño», «mediano» o «grande» dentro de un bloque de código @media:
body {
--screen: "small";
background-color: #cff;
text-align: center;
}
@media (min-width: 400px) {
body {
--screen: "medium";
background-color: #fcf;
}
}
@media (min-width: 800px) {
body {
--screen: "large";
background-color: #ffc;
}
}
El valor se puede generar solo en CSS usando un pseudoelemento (pero tenga en cuenta que debe estar contenido entre comillas simples o dobles):
p::before {
content: var(--screen);
}
Puede obtener el valor de la propiedad personalizada utilizando JavaScript:
const screen = getComputedStyle(window.body)
.getPropertyValue('--screen');
Sin embargo, esta no es toda la historia, porque el valor devuelto contiene todos los espacios en blanco y los caracteres de comillas definidos después de los dos puntos en el CSS. La cadena será ‘»grande»‘, por lo que es necesario un poco de orden:
// returns small, medium, or large in a string
const screen = getComputedStyle(window.body)
.getPropertyValue('--screen')
.replace(/W/g, '');
Puede ver una demostración de trabajo aquí. (Si usa un navegador de escritorio, abra este enlace en una nueva ventana para facilitar el cambio de tamaño. Los usuarios de dispositivos móviles pueden rotar el dispositivo).
El ejemplo examina el valor de CSS cada dos segundos. Requiere un poco de código JavaScript, pero es necesario sondear los cambios; no puede detectar automáticamente que el valor de la propiedad personalizada ha cambiado usando CSS.
Tampoco es posible escribir el valor en un pseudoelemento y detectar el cambio usando un Observador de Mutación DOM. ¡Los pseudo-elementos no son una parte «real» del DOM!
Las ventajas:
- Es una técnica simple que utiliza principalmente CSS y coincide con consultas de medios reales.
- Cualquier otra propiedad CSS se puede modificar al mismo tiempo.
- No es necesario duplicar o analizar cadenas de consulta de medios de JavaScript.
La principal desventaja es que no puede reaccionar automáticamente a un cambio en la dimensión de la ventana gráfica del navegador. Si el usuario gira su teléfono de orientación vertical a horizontal, JavaScript nunca lo sabría. Puede sondear con frecuencia los cambios, pero eso es ineficiente y da como resultado el retraso que ve en nuestra demostración.
Monitorear las propiedades personalizadas de CSS es una técnica novedosa, pero solo es práctica cuando:
- El diseño se puede fijar en el punto en el que se representa inicialmente una página. Un quiosco o terminal de punto de venta es una posibilidad, pero es probable que tengan resoluciones fijas y un diseño único, por lo que las consultas de medios de JavaScript se vuelven irrelevantes.
- El sitio o la aplicación ya ejecuta funciones frecuentes basadas en el tiempo, como la animación de un juego. La propiedad personalizada se puede verificar al mismo tiempo para determinar si se requieren cambios en el diseño.
Opción 3: utilizar la API de matchMedia
La API de matchMedia es un poco inusual, pero le permite implementar una consulta de medios de JavaScript. Es compatible con la mayoría de los navegadores desde IE10 en adelante. El constructor devuelve un objeto MediaQueryList que tiene una propiedad de coincidencias que se evalúa como verdadero o falso para su consulta de medios específica.
El siguiente código da como resultado verdadero cuando el ancho de la ventana gráfica del navegador es de 800 px o más:
const mqLarge = window.matchMedia( '(min-width: 800px)' );
console.log( mqLarge.matches );
Se puede aplicar un evento de «cambio» al objeto MediaQueryList. Esto se activa cada vez que cambia el estado de la propiedad de coincidencias: se vuelve verdadero (más de 800 px) después de haber sido previamente falso (menos de 800 px) o viceversa.
A la función del controlador de recepción se le pasa el objeto MediaQueryList como primer parámetro:
const mqLarge = window.matchMedia( '(min-width: 800px)' );
mqLarge.addEventListener('change', mqHandler);
// media query handler function
function mqHandler(e) {
console.log(
e.matches ? 'large' : 'not large'
);
}
El controlador solo se ejecuta cuando cambia la propiedad de coincidencias. No se ejecutará cuando la página se cargue inicialmente, por lo que puede llamar a la función directamente para determinar el estado inicial:
// initial state
mqHandler(mqLarge);
La API funciona bien cuando se mueve entre dos estados distintos. Para analizar tres o más estados, como pequeña, medio, y grande, requerirá más código.
Comience por definir un objeto de estado de pantalla con objetos matchMedia asociados:
const
screen = {
small : null,
medium: window.matchMedia( '(min-width: 400px)' ),
large : window.matchMedia( '(min-width: 800px)' )
};
No es necesario definir un objeto matchMedia en el pequeña estado porque el controlador de eventos medio se activará cuando se mueva entre pequeña y medio.
Los detectores de eventos se pueden configurar para medio y grande eventos. Estos llaman a la misma función de controlador mqHandler ():
// media query change events
for (let [scr, mq] of Object.entries(screen)) {
if (mq) mq.addEventListener('change', mqHandler);
}
La función del controlador debe verificar todos los objetos MediaQueryList para determinar si pequeña, medio, o grande está actualmente activo. Las coincidencias deben ejecutarse en orden de tamaño, ya que un ancho de 999 px coincidiría con ambas medio y grande – solo el más grande debería «ganar»:
// media query handler function
function mqHandler() {
let size = null;
for (let [scr, mq] of Object.entries(screen)) {
if (!mq || mq.matches) size = scr;
}
console.log(size);
}
Puede ver una demostración de trabajo aquí. (Si usa un navegador de escritorio, abra este enlace en una nueva ventana para facilitar el cambio de tamaño. Los usuarios de dispositivos móviles pueden rotar el dispositivo).
Los ejemplos de usos son:
- Consultas de medios en CSS para establecer y mostrar una propiedad personalizada (como se muestra en opcion 2 encima).
- Consultas de medios idénticas en objetos matchMedia para monitorear cambios de dimensión en JavaScript. La salida de JavaScript cambiará exactamente al mismo tiempo.
Las principales ventajas de utilizar la API matchMedia son:
- Está impulsado por eventos y es eficiente en el procesamiento de cambios de consultas de medios.
- Utiliza cadenas de consulta de medios idénticas a las de CSS.
Las desventajas:
- Manejar dos o más consultas de medios requiere más pensamiento y lógica de código.
- Probablemente necesite duplicar cadenas de consulta de medios en código CSS y JavaScript. Esto podría generar errores si no los mantiene sincronizados.
Para evitar discrepancias en las consultas de medios, podría considerar el uso de tokens de diseño en su sistema de compilación. Las cadenas de consulta de medios se definen en un archivo JSON (o similar) y los valores se colocan en el código CSS y JavaScript en el momento de la compilación.
En resumen, es probable que la API de matchMedia sea la forma más eficiente y práctica de implementar una consulta de medios de JavaScript. Tiene algunas peculiaridades, pero es la mejor opción en la mayoría de situaciones.
Resumen
Las opciones intrínsecas de tamaño de CSS son cada vez más viables, pero las consultas de medios siguen siendo la base del diseño web receptivo para la mayoría de los sitios. Siempre serán necesarios para manejar diseños y preferencias de usuario más complejos, como el modo claro / oscuro.
Intente mantener las consultas de medios solo en CSS siempre que sea posible. Cuando no tiene más remedio que aventurarse en el ámbito de JavaScript, la API matchMedia proporciona un control adicional para los componentes de consulta de medios de JavaScript, que requieren una funcionalidad adicional basada en dimensiones.
¿Tiene otros consejos para implementar una consulta de medios de JavaScript? Compártelos en la sección de comentarios!
Ahorre tiempo, costos y maximice el rendimiento del sitio con:
- Ayuda instantánea de expertos en alojamiento de WordPress, 24 horas al día, 7 días a la semana.
- Cloudflare Enterprise integración.
- Alcance de audiencia global con 28 centros de datos en todo el mundo.
- Optimización con nuestro monitoreo de rendimiento de aplicaciones integrado.
Todo eso y mucho más, en un plan sin contratos a largo plazo, migraciones asistidas y una garantía de devolución de dinero de 30 días. Consulte nuestros planes o hable con ventas para encontrar el plan adecuado para usted.
