Menu

Media queries en CSS: breakpoints, min-width y max-width

Una media query aplica CSS solo cuando una condición es verdadera, como un ancho mínimo de pantalla, un esquema de color oscuro o un puntero de mouse. Aprende la sintaxis @media, los breakpoints mobile first, la sintaxis de rangos, prefers-color-scheme, matchMedia en JavaScript y las container queries.

Esta página incluye editores ejecutables: edita, ejecuta y ve el resultado al instante.

Una media query en un ejemplo

Una media query envuelve CSS en una condición. Las reglas dentro de @media (min-width: 600px) solo se aplican mientras el viewport mide al menos 600px de ancho:

La vista previa es un marco, y una media query dentro de él mide el marco, no tu pantalla. En un escritorio mide más o menos lo mismo que esta columna del artículo, normalmente más de 600px, así que la caja es azul. Haz tu ventana del navegador lo bastante angosta como para que el marco baje de 600px y se vuelve ámbar; la línea debajo de la caja informa el ancho del marco en vivo. En un teléfono el marco ya es angosto, así que ves la versión ámbar.

La sintaxis @media

@media (min-width: 600px) { ... }                        /* one condition */
@media (min-width: 600px) and (max-width: 899px) { ... } /* both must be true */
@media (max-width: 599px), print { ... }                 /* either one (comma = or) */
@media not print { ... }                                 /* negation */
@media screen and (orientation: landscape) { ... }       /* media type plus a feature */
@media (width >= 600px) { ... }                          /* range syntax */
@media (600px <= width < 900px) { ... }                  /* a range with both ends */

and necesita un espacio a cada lado: (min-width: 600px)and(max-width: 900px) es inválido y se ignora toda la consulta. La sintaxis de rangos (width >= 600px) es compatible con las versiones actuales de Chrome, Firefox y Safari y se lee con más claridad que min-width, sobre todo para "hasta, sin incluir".

Las características que más vas a usar:

CaracterísticaCoincide cuandoEjemplo
min-width / width >=el viewport mide al menos este ancho(min-width: 768px)
max-width / width <=el viewport mide como máximo este ancho(max-width: 767px)
orientationportrait (más alto que ancho) o landscape(orientation: landscape)
hoverel puntero principal puede hacer hover (hover) o no (none, la mayoría de las pantallas táctiles)(hover: hover)
pointerel puntero principal es fine (mouse) o coarse (dedo)(pointer: coarse)
prefers-color-schemeel usuario eligió un tema dark o light(prefers-color-scheme: dark)
prefers-reduced-motionel usuario pidió al sistema menos movimiento(prefers-reduced-motion: reduce)
print (un tipo de medio)la página se imprime o se guarda como PDF@media print

Mobile first: breakpoints con min-width

Escribe el layout del teléfono como CSS base y luego agrega consultas min-width que cambian el layout a medida que crece el espacio. Cada consulta solo tiene que describir lo que cambia:

En una ventana de escritorio ancha la vista previa pasa de 720px, así que ves tres columnas; la línea debajo del grid informa el ancho y la cantidad de columnas. Achica la ventana y baja a dos por debajo de 720px y a una por debajo de 480px. El orden de las dos consultas importa: en una pantalla ancha las dos son verdaderas y gana la posterior, así que las consultas min-width van de la más pequeña a la más grande. (Con consultas max-width es al revés: la más grande primero.)

Elegir los breakpoints

No hay una lista oficial. Estos son valores habituales y lo que suelen separar:

BreakpointNormalmente
min-width: 640pxteléfonos grandes en horizontal, tablets pequeñas
min-width: 768pxtablets en vertical
min-width: 1024pxtablets en horizontal, laptops pequeñas
min-width: 1280pxescritorios

Un método mejor: empieza con el layout angosto, ensancha la ventana hasta que algo se vea mal (líneas demasiado largas, tarjetas demasiado anchas) y pon un breakpoint ahí. Dos o tres breakpoints bastan para la mayoría de las páginas. A menudo no necesitas ninguno: repeat(auto-fit, minmax(200px, 1fr)) en grid, flex-wrap y clamp() se adaptan de forma continua.

Toda página necesita la etiqueta meta viewport

Sin esta etiqueta en el <head>, los navegadores de los teléfonos acomodan la página como si la pantalla midiera unos 980px de ancho y luego alejan el zoom, así que tu consulta min-width: 480px siempre es verdadera y tu layout de teléfono nunca se ve:

<meta name="viewport" content="width=device-width, initial-scale=1">

La página de meta viewport explica todos sus valores.

Modo oscuro con prefers-color-scheme

prefers-color-scheme sigue la configuración clara u oscura del sistema operativo. La forma más limpia de usarla es guardar los colores en variables CSS y cambiar solo las variables dentro de la consulta:

En esta vista previa, la consulta puede mostrar false aunque tu sistema esté en modo oscuro: Chrome no pasa la preferencia del sistema a un marco con sandbox como este. El botón cambia las mismas variables a mano, que es como funciona el selector de tema de un sitio. :root[data-theme] es más específico que el :root simple de la consulta, así que la elección del lector gana sobre la del sistema. Guarda el ejemplo como archivo y ábrelo para ver cómo la consulta sigue a tu sistema.

El script muestra la segunda mitad de las media queries: matchMedia() ejecuta la misma consulta desde JavaScript, devuelve si coincide en ese momento y dispara un evento change cuando la respuesta cambia. Úsalo cuando el comportamiento (no solo el estilo) depende de la pantalla, como abrir un menú de otra forma en dispositivos táctiles.

El movimiento funciona igual. Envuelve las animaciones grandes o en bucle en una comprobación de prefers-reduced-motion, como se muestra en la página de animaciones.

Container queries: cuando el componente debe decidir

Una media query solo conoce el viewport. Una tarjeta que aparece en una columna principal ancha y en una barra lateral angosta de la misma página necesita conocer su propio espacio. Eso es una container query: marca el padre con container-type: inline-size y usa @container con las mismas condiciones.

Arrastra la esquina de la caja gris para cambiar su tamaño. La tarjeta cambia de layout a los 360px de ancho de la caja, sea cual sea el tamaño de la ventana:

Con sus 480px iniciales, la imagen queda al lado del texto. Arrastra la caja por debajo de 376px (360px de contenido más 8px de padding a cada lado) y la imagen pasa arriba del texto. Las container queries funcionan en todos los navegadores principales actuales.

Estilos para imprimir

@media print se aplica solo cuando la página se imprime o se guarda como PDF. Oculta la navegación y los botones, y usa texto oscuro sobre blanco:

@media print {
  nav, .ad, button { display: none; }
  body { color: black; background: white; }
  a::after { content: " (" attr(href) ")"; } /* print the URL after each link */
}

Errores comunes

  • Sin etiqueta meta viewport. Los teléfonos informan entonces un viewport de layout ancho y las consultas de pantalla pequeña nunca coinciden.
  • Consultas en el orden equivocado. Dos consultas verdaderas con el mismo selector: gana la posterior. Ordena las consultas min-width de menor a mayor.
  • Límites que se superponen o dejan huecos. max-width: 768px y min-width: 768px coinciden las dos en exactamente 768px. Usa 767px en una de ellas, o la sintaxis de rangos (width < 768px) y (width >= 768px).
  • Sin espacio después de and. and( es inválido y la consulta se descarta en silencio.
  • Probar solo cambiando el tamaño de una ventana de escritorio. Revisa también un teléfono real o el modo dispositivo del navegador, que aplica el viewport, la densidad de píxeles y el tacto del teléfono.
  • Demasiados breakpoints. Si cada componente necesita los suyos, prueba grid con auto-fit, flex-wrap o container queries.

Preguntas frecuentes

¿Qué es una media query en CSS?

Una regla que aplica el CSS que contiene solo cuando se cumple una condición sobre el dispositivo o la ventana. @media (min-width: 600px) { ... } aplica sus estilos solo cuando el viewport mide al menos 600px de ancho, y así una misma página se adapta de los teléfonos a los escritorios.

¿Uso media queries con min-width o con max-width?

La mayoría de los sitios se escriben mobile first: el CSS base es para pantallas pequeñas y las consultas min-width agregan layout a medida que crece la pantalla. Las consultas max-width funcionan al revés, partiendo del layout de escritorio. Las dos sirven; mezclarlas en el mismo elemento produce superposiciones y huecos en los límites.

¿Cuáles son los breakpoints estándar de las media queries?

No hay un estándar oficial. Los valores habituales rondan los 640px, 768px, 1024px y 1280px, pero la mejor regla es agregar un breakpoint donde tu propio layout empieza a verse mal, y mantener pocos breakpoints.

¿Por qué mi media query no funciona en el celular?

La causa más común es que falta la etiqueta meta viewport. Sin <meta name="viewport" content="width=device-width, initial-scale=1">, los navegadores móviles fingen que la página mide unos 980px de ancho, así que las consultas de ancho pequeño nunca coinciden. Comprueba también que la consulta vaya después de las reglas que sobrescribe.

¿Cómo escribo una media query para el modo oscuro?

Usa @media (prefers-color-scheme: dark) { ... }. Coincide cuando el sistema operativo o el navegador del usuario tiene un tema oscuro, y dentro puedes sobrescribir colores o variables CSS.

¿Qué diferencia hay entre media queries y container queries?

Una media query evalúa el viewport (toda la ventana). Una container query, escrita con @container, evalúa el tamaño de un elemento padre que marcas con container-type: inline-size. Usa container queries para un componente que aparece en lugares anchos y angostos de la misma página.

Coddy programming languages illustration

Aprende a programar con Coddy

COMENZAR