wandres.dev
DEPURAR EN MÓVIL · Dispositivo real y emulación

La emulación de dispositivo: qué cambia realmente

Las cinco cosas que la emulación modifica, los dispositivos personalizados, la regla de las consultas de medios, y por qué el ancho no es lo único que importa.

⏱ 16 min

El modo de dispositivo es probablemente la función más usada de todas las DevTools y también la que más falsa confianza produce. Cambia el tamaño de la ventana, el identificador del navegador, la relación de píxeles y el modelo de entrada, y con eso reproduce fielmente los problemas de disposición. Lo que no cambia es todo lo demás, y ese “todo lo demás” incluye precisamente aquello que hace que la web móvil sea difícil.

🎯 Al terminar esta lección sabrás
  • Enumerar exactamente qué modifica la emulación de dispositivo.
  • Configurar dispositivos personalizados con los valores de tu público real.
  • Usar la regla de consultas de medios para encontrar los puntos de ruptura.
  • Reproducir los tres modos de entrada y sus diferencias.

Las cinco cosas que cambia

El tamaño del área visible. Con las dimensiones en unidades CSS del dispositivo elegido. Es lo que dispara las consultas de medios y lo que reproduce los problemas de disposición.

La relación de píxeles. Cuántos píxeles físicos corresponden a un píxel CSS. Afecta a qué imagen se elige de un conjunto responsivo y a cómo se renderiza el texto.

El identificador del navegador y las pistas de cliente. Lo que el servidor ve, y por tanto qué contenido sirve si hace detección por servidor.

El modelo de entrada. Genera eventos táctiles en lugar de eventos de ratón, y hace que las consultas de capacidad de puntero devuelvan valores de dispositivo táctil.

La orientación. Vertical u horizontal, con el cambio de dimensiones y el evento correspondiente.

Con esas cinco, la emulación reproduce fielmente: los problemas de disposición, los puntos de ruptura mal puestos, las imágenes que no tienen versión adecuada, el contenido que se desborda, los elementos táctiles demasiado pequeños, y el contenido que se sirve distinto a móviles.

ℹ️
Nota

El modo con dimensiones libres es más útil que los preajustes de dispositivo para la mayor parte del trabajo. Arrastrar el borde y observar dónde se rompe la disposición encuentra problemas en anchos intermedios que ningún dispositivo concreto tiene y que existen en tabletas, ventanas redimensionadas y pantallas divididas. Los preajustes sirven para verificar un caso concreto; el arrastre sirve para encontrar problemas.

Dispositivos personalizados

La lista de preajustes es una selección arbitraria que no corresponde a tu público. Añadir dispositivos propios con los valores reales de tus usuarios es media hora bien invertida.

Los datos salen de tu analítica: los cinco tamaños de área visible más frecuentes, con sus relaciones de píxeles. Y conviene añadir dos casos límite que casi nunca están en las listas: el más estrecho que recibas y una tableta en horizontal, que es donde más problemas de disposición aparecen porque cae entre dos mundos.

Para saber qué está viendo realmente el usuario, este fragmento reporta todo lo relevante:

// Todo lo que define el contexto de visualizacion actual
(() => {
  const datos = {
    areaVisibleCSS: innerWidth + ' x ' + innerHeight,
    pantallaCSS: screen.width + ' x ' + screen.height,
    relacionPixeles: devicePixelRatio,
    pixelesFisicos: Math.round(innerWidth * devicePixelRatio) + ' x ' +
                    Math.round(innerHeight * devicePixelRatio),
    orientacion: screen.orientation?.type ?? (innerWidth > innerHeight ? 'horizontal' : 'vertical'),
    puntero: matchMedia('(pointer: coarse)').matches ? 'grueso' : 'fino',
    hover: matchMedia('(hover: hover)').matches ? 'si' : 'no',
    puntosDeContacto: navigator.maxTouchPoints,
    nucleos: navigator.hardwareConcurrency ?? 'no expuesto',
    memoriaGB: navigator.deviceMemory ?? 'no expuesta',
    conexion: navigator.connection?.effectiveType ?? 'no expuesta',
    ahorroDatos: navigator.connection?.saveData ?? 'no expuesto',
    // El area visible real descontando barras del navegador
    unidadVH: getComputedStyle(document.documentElement).getPropertyValue('--vh') || 'no definida'
  };
  console.table([datos]);

  // Encuentra los puntos de ruptura declarados en el CSS del sitio
  const puntos = new Set();
  for (const hoja of document.styleSheets) {
    let reglas; try { reglas = hoja.cssRules; } catch { continue; }
    const buscar = (lista) => {
      for (const r of lista) {
        if (r.media?.mediaText) {
          for (const m of r.media.mediaText.match(/\d+(\.\d+)?(px|em|rem)/g) ?? []) puntos.add(m);
        }
        if (r.cssRules) buscar(r.cssRules);
      }
    };
    buscar(reglas);
  }
  console.log('Puntos de ruptura declarados en el CSS:',
    [...puntos].sort((a, b) => parseFloat(a) - parseFloat(b)).join(', '));
  console.log('Comprueba la disposicion justo por encima y por debajo de cada uno.');
})();

La lista de puntos de ruptura extraída del propio CSS es el guion de la prueba: en lugar de probar anchos al azar, se prueba un píxel por encima y otro por debajo de cada punto declarado, que es donde están todos los bugs de disposición responsiva.

Las tres modalidades de entrada

La emulación táctil se suele activar sin pensar, y merece precisión porque hay tres situaciones distintas.

Ratón con hover. Escritorio. Hay estados intermedios: el usuario puede señalar sin activar.

Táctil sin hover. Móvil y tableta. No hay estado intermedio. Cualquier interfaz que dependa de hover para mostrar algo —un menú que se despliega al pasar por encima, un botón que solo aparece al señalar una fila— es inaccesible en táctil, o se comporta de forma extraña porque el navegador simula un hover con el primer toque.

Ambos. Portátiles con pantalla táctil, tabletas con ratón. La consulta de capacidad primaria dice una cosa y la de cualquier puntero disponible dice otra, y esa distinción es la que permite escribir interfaces que funcionan en los dos modos.

/* Adaptarse al puntero disponible sin suponer que movil equivale a tactil */
.acciones-de-fila {
  opacity: 0;
  transition: opacity 120ms;
}

/* Solo ocultar acciones si de verdad existe hover como mecanismo primario */
@media (hover: hover) and (pointer: fine) {
  .fila:hover .acciones-de-fila,
  .fila:focus-within .acciones-de-fila { opacity: 1; }
}

/* Con puntero grueso, siempre visibles y con area de toque suficiente */
@media (pointer: coarse) {
  .acciones-de-fila { opacity: 1; }
  .acciones-de-fila button { min-block-size: 44px; min-inline-size: 44px; }
}

El detalle del focus-within en la primera consulta es el que hace que la interfaz funcione también por teclado, que es un caso que la emulación de dispositivo no cubre en absoluto y que hay que probar aparte.

Lo que la emulación reproduce bien

Merece la pena cerrar con la lista positiva, porque para estas cosas la emulación es excelente y no hace falta un dispositivo real.

Los problemas de disposición en anchos pequeños. El desbordamiento horizontal, que es el defecto más común y más molesto de la web móvil. Los puntos de ruptura mal colocados. Las imágenes sin versión adecuada para la densidad. El contenido que el servidor sirve distinto según el identificador. Los elementos táctiles demasiado pequeños o demasiado juntos. El comportamiento en horizontal, que casi nadie prueba.

Todo eso se encuentra en diez minutos con el modo de dispositivo, y son problemas reales que afectan a usuarios reales. La lección siguiente trata de lo que no encuentra.

El área visible en móvil no es lo que dice la ventana, y esa es la causa del bug de disposición más persistente de la web

Hay un detalle de la emulación que conviene conocer porque afecta a un bug que casi todos los sitios han tenido y muchos siguen teniendo: el área visible de un navegador móvil cambia de tamaño mientras el usuario se desplaza. La barra de direcciones se retrae al bajar y vuelve a aparecer al subir, y con ella el alto disponible varía en decenas de píxeles. Durante años, la unidad de altura de ventana se resolvía en móvil contra el tamaño máximo posible, es decir, el que hay cuando la barra está oculta, lo que producía el defecto clásico de un elemento a altura completa cuya parte inferior queda tapada por la barra en cuanto esta aparece. La emulación de dispositivo no reproduce ese comportamiento: en la emulación no hay barra que se retraiga, el alto es constante, y el bug es literalmente imposible de observar. Es el ejemplo más limpio de un problema que solo existe en el aparato real. La corrección moderna es un conjunto de unidades que expresan explícitamente cuál de las tres alturas quieres: la pequeña, correspondiente al área visible cuando todas las barras están presentes; la grande, cuando están retraídas; y la dinámica, que sigue el valor actual en cada momento. La elección entre las tres no es indiferente y tiene una regla clara: usa la pequeña para cualquier cosa que tenga que verse entera siempre, porque garantiza que cabe en el peor caso; usa la dinámica solo para elementos decorativos, porque su valor cambia continuamente durante el desplazamiento y cualquier cosa que dependa de él se recalcula sin parar, con el coste de disposición que eso implica; y evita la grande salvo que sepas exactamente por qué la quieres. El caso general —un panel a pantalla completa, un diálogo, una pantalla de bienvenida— se resuelve con la pequeña y se acabó el problema. Y la comprobación de que está bien no se puede hacer en la emulación: hay que abrirlo en un teléfono, desplazarse hacia abajo y hacia arriba, y ver si algo queda tapado.