CSS Media Queries
El lenguaje CSS (“Cascading Style Sheets” en español “hojas de estilo en cascada”), junto con HTML y JavaScript, forman la estructura básica para el desarrollo de las páginas web modernas. El CSS es un lenguaje de programación, pero no describe los pasos individuales para resolver un problema. En lugar de ello, define un objetivo que se debe alcanzar. Esto convierte a CSS en un lenguaje declarativo similar a SQL.
Parte del lenguaje CSS son las llamadas Media Queries, que consultan las características técnicas del dispositivo de salida. Se utilizan para el diseño web responsivo (también diseño responsivo o responsive web design). ¿Cómo funciona exactamente?
- Certificado SSL Wildcard
- Registro privado
- 1 cuenta de correo electrónico por contrato
¿Qué son las CSS Media Queries?
Las CSS Media Queries se introdujeron con la especificación CSS3. Una Media Query vincula la asignación de propiedades CSS que tiene un elemento a una o varias condiciones de medios. En el caso más sencillo, se distingue la información que se muestra en cada medio: en una pantalla, en una página impresa (esto incluye también la salida como PDF) o en forma de texto leído en voz alta:
Medio | Explicación |
---|---|
all | Cualquier medio de salida |
Screen | Presentación del contenido de una página web en una pantalla táctil |
Presentación del contenido de una página web en varias páginas con dimensiones fijas | |
speech | Lectura en voz alta del contenido de una página web mediante un sintetizador de habla |
Un CSS Media Query se define dentro de un bloque de código CSS mediante una regla especial: ‘@media’. Las reglas y selectores CSS contenidos en el bloque de código solo se activan bajo las condiciones que se hayan especificado. Por ejemplo, los elementos que no deben ser mostrados pueden ser ocultados a la hora de imprimirse en una página:
/* Ocultar elementos no imprimibles */
@media print {
video, audio {
display: none;
}
}
Además del medio utilizado, se pueden utilizar CSS Media Queries para solicitar específicamente las características del medio respectivo. Las CSS Media Queries son, por tanto, la característica técnica principal que ha permitido que surja el responsive webdesign.
CSS Media Queries como elemento de control central para el responsive webdesign
El diseño responsivo tiene como objetivo adaptar la visualización de una página web a cada dispositivo de la mejor manera posible. Las Media Queries se utilizan para obtener las características técnicas del dispositivo que solicita la visualización de la página web. Las obtiene solicitando al dispositivo las llamadas Media Features. De esta manera, es posible definir reglas de estilo para diferentes dimensiones de pantalla. Es más, se pueden definir reglas de estilo optimizadas para cuando se inclina el dispositivo móvil.
A continuación, un resumen de las características de los Media Features que se utilizan actualmente con más frecuencia para el diseño responsivo:
Media Feature | Explicación |
---|---|
width | Solicita el ancho de la pantalla en píxeles |
height | Solicita el alto de la pantalla en píxeles |
orientation | Detecta la orientación de la pantalla en posición vertical u horizontal |
resolution | Detecta la resolución de pantalla disponible |
Veamos algunos ejemplos. Imaginemos el título principal de una página web. HTML proporciona el elemento ‘h1’ para el título. En primer lugar, estableceremos las reglas de estilo para el elemento h1 independientemente del dispositivo que lo visualice:
h1 {
font-size: 24px;
line-height: 1.25;
}
A continuación, definimos una Media Query que solicita el ancho de la pantalla. Dentro de la solicitud, definimos las reglas de estilo que deben aplicarse al título en función del ancho que tenga. En este ejemplo en concreto, aumentamos el tamaño de la fuente del título h1 en las pantallas que tienen al menos 1024 píxeles de ancho:
@media screen and (min-width: 1024px) {
h1 {
font-size: 36px;
}
}
Ten en cuenta que aquí solo ajustamos la propiedad ‘font-size’ del título h1. El interlineado se define como una unidad relativa mediante la propiedad ‘line-height’ y su valor se hereda hasta que una nueva línea de código lo sobrescriba. En este ejemplo concreto, el interlineado del elemento h1 es por defecto de 24px * 1.25 = 30px. En pantallas con una anchura de 1024 píxeles o más, el interlineado aumenta proporcionalmente, por ejemplo: 36px * 1.25 = 45px.
Esta mezcla de reglas de estilo existentes y recién definidas se expresa en el lenguaje CSS con la palabra “cascading”: un elemento hereda las reglas de estilo de sus elementos padre o de las reglas generales ya definidas. Normalmente, se establecen unas propiedades por defecto para los elementos para luego sobrescribirlas individualmente en función de las circunstancias.
Otro ejemplo: imaginemos que queremos mostrar tres elementos en un contenedor. Los elementos deben aparecer uno debajo de otro en la pantalla del dispositivo móvil cuando éste se mantiene en posición vertical. Cuando el dispositivo se pone en posición horizontal, el layout de la pantalla debe cambiar para que los elementos se muestren uno al lado del otro. Con el módulo Flexbox Layout y una CSS Media Query, que solicita la orientación del dispositivo, se puede condicionar el layout del dispositivo a su orientación en unas pocas líneas de código HTML y CSS. A continuación, definimos el contenedor y los elementos que contiene en HTML:
<div class="container">
<div class="element">…</div>
<div class="element">…</div>
<div class="element">…</div>
</div>
Además, definimos las siguientes reglas CSS. Definimos la propiedad ‘display: flex’ para el contenedor y definimos la propiedad ‘flex-direction’ condicionada por la CSS Media Query. Si se posiciona el dispositivo de manera horizontal (apaisada), los elementos se mostrarán en una fila, uno al lado del otro; en cambio, si se posiciona el dispositivo de manera vertical, los elementos se mostrarán en una columna, uno debajo del otro.
.container {
display: flex;
}
/* Posición horizontal */
@media screen and (orientation: landscape) {
.container {
flex-direction: row;
}
}
/* Posición vertical */
@media screen and (orientation: portrait) {
.container {
flex-direction: column;
}
}
Además de las dimensiones de le pantalla y la orientación del dispositivo, también podemos solicitar los datos de la resolución física de la pantalla mediante una Media Query. Esto es especialmente interesante para mostrar las imágenes compuestas por píxeles. Imagínate este ejemplo: un logotipo está disponible en dos versiones, una versión optimizada para pantallas de baja calidad y la otra para pantallas de alta calidad. Un truco sencillo para mostrar el logotipo adecuado en cada caso es poner ambos en la página web, usar un CSS Media Query para consultar la resolución de pantalla del dispositivo e implementar ‘display: none’ para ocultar la versión que no le corresponda. Este tipo de solución se podría implementar en el código HTML y CSS de la siguiente manera:
<!--— Imagen de alta resolución ---->
<img class="logo--high-res" src="/img/logo-high-res.png" alt="Logo en alta resolución">
<!--— Imagen de baja resolución---->
<img class="logo--low-res" src="/img/logo-low-res.png" alt="Logo en baja resolución">
/* Ocultar la imagen de alta resolución en la pantalla de baja resolución */
@media (max-resolution: 149dpi) {
.logo--high-res {
display: none;
}
}
/* Ocultar la imagen de baja resolución en la pantalla de alta resolución */
@media (min-resolution: 150dpi) {
.logo--low-res {
display: none;
}
}
En nuestro artículo sobre diseño responisvo mostramos más maneras de presentar las imágenes con el diseño responsivo de la mejor manera posible.
Habilitar el viewport variable para el diseño responsivo
En las explicaciones anteriores, hemos hablado de la “pantalla” en relación con la anchura disponible del dispositivo de salida. Esto es conceptualmente correcto, pero técnicamente no lo es del todo. El navegador opera internamente con el concepto de “viewport”. Para que la anchura del viewport se corresponda realmente con la anchura de la pantalla, se necesita definir un ‘meta-viewport’ en el ‘<head>’ del documento HTML. Sin este dato, la página se muestra en los dispositivos móviles igual que en el PC, lo que reduce drásticamente su tamaño.
<head>
<!— Activar CSS Media Queries -->
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
Comprender las unidades CSS para el diseño responsivo
En el responsive webdesign, los elementos deben adaptarse al espacio disponible en la pantalla. A menudo se trata de especificar las dimensiones de los elementos en diferentes condiciones. El lenguaje CSS define una variedad de unidades; la unidad de dimensión base es el píxel. Por ejemplo, una imagen de 1080p tiene unas dimensiones de 1920 píxeles de ancho por 1080 de alto.
El pixel es una unidad absoluta por lo que, por definición, no se adapta al ancho de pantalla disponible. Veamos un ejemplo de por qué esto puede ser problemático. Supongamos que una página web contiene una imagen con una anchura de 1920 píxeles. Si ajustamos el ancho de la imagen a este valor mediante CSS, la visualización puede resultar incómoda en pantallas pequeñas ya que la imagen sobresale del espacio disponible.
Aquí definimos una imagen en HTML con la etiqueta '<img>':
<img class="img-1080p" src="/bild-1080p.png">
Mediante CSS, le asignamos un ancho de 1920 píxeles:
.img-1080p {
width: 1920px;
}
En este caso, es mejor utilizar una unidad relativa en vez de píxeles. Desde los primeros días, cuando los layouts estaban basados en tablas, el idioma CSS reconoce el porcentaje como una unidad relativa. Si establecemos mediante CSS un ancho de la imagen del ‘100%’, la imagen se ajustará al espacio disponible. Esto ocurre porque los porcentajes siempre se refieren al elemento que los encierra.
img {
width: 100%;
}
Nos hemos acercado bastante a nuestro objetivo de ajustar el ancho de una imagen al espacio disponible. Sin embargo, hemos creado un nuevo problema: En una pantalla de más de 1920 píxeles, la imagen se muestra ampliada y pixelada. Por lo tanto, hay que limitar el ancho máximo de la imagen a sus dimensiones reales en píxeles:
.img-1080p {
/* Heredado implícitamente de `img` */
/* width: 100%; */
max-width: 1920px;
}
Además de los píxeles y los porcentajes, el idioma CSS reconoce otras unidades. Las unidades relativas em, rem y vw, vh ofrecen interesantes posibilidades de uso en el diseño responsivo. A continuación, tienes un resumen de las unidades más utilizadas en CSS para el diseño responsivo, junto con su uso:
Unidad en CSS | Uso |
---|---|
rem | Tamaño de la fuente del texto, ‘max-width’ de los elementos layout; ‘width’ de los elementos. |
% | ‘width’ de las imágenes y elementos layout, limitados por ‘max-width’ si es necesario |
vw, vh | Tamaño de letra de los títulos, textos hero, dimensiones de los elementos de relleno de la pantalla |
em | Definición de breakpoints, ‘max-width’ de los elementos layout |
px | Definición de breakpoints, ‘max-width’ de las imágenes |
Comprender Media Queries más avanzadas
Además de las Media Queries simples mostradas hasta ahora, también se pueden escribir CSS Media Queries más complejas. Para ello, CSS reconoce los operadores lógicos ‘and’, ‘or’ y ‘not’. Este es un ejemplo de una Query compleja:
@media screen and (min-width: 30em) and (orientation: landscape) { /* … */ }
Además de las Media Features ya establecidas que pueden consultarse a través de CSS Media Query, habrá nuevas funciones interesantes en el futuro. La especificación “CSS Media Queries Level 5” (CSS5) reconoce, entre otras, las siguientes nuevas opciones de solicitud:
Media Feature | Explicación |
---|---|
light-level | Detectar la luminosidad ambiental |
prefers-color-scheme | Selecciona entre una combinación de colores claros u oscuros |
prefers-contrast | Selecciona el modo de contraste |
Otra innovación que se espera con el lanzamiento de CSS5 son las llamadas Container Queries. Con ellas será posible, por primera vez, vincular las reglas de estilo de los elementos a las propiedades del container que los envuelven. Las Container Queries se diferencian de las CSS Media Queries, que solicitan las propiedades generales del dispositivo en el que se muestran. El uso de las Container Queries permitirá tratar casos especiales para los que hasta ahora se utilizaba JavaScript o Media Queries complejas.
Comprender los CSS Breakpoints
En el contexto del diseño web responsivo y las CSS Media Queries, a menudo hablamos de “breakpoints” (en español “punto de ruptura”). Un breakpoint es un ancho de pantalla definido en el que se activa un conjunto de reglas CSS definidas previamente por una CSS Media Query. Puedes ver los breakpoints definidos en una página web si abres las herramientas de desarrollador en el navegador. Si la visualización responsiva está activa, los breakpoints se muestran como barras de color sobre la página web original.
Comprender el mobile first, los procesadores CSS y los CSS Utility Frameworks.
Una de las mejores prácticas reconocidas del diseño responsivo es el enfoque mobile first. Si el diseño y desarrollo de una página web sigue este enfoque, primero se definen las especificaciones de estilo para las pantallas más pequeñas. Estas definiciones constituyen el marco básico del diseño. A partir de ahí, se definen varios breakpoints para pantallas sucesivamente más grandes. Con esos breakpoints se definen selectivamente nuevas reglas de estilo para los elementos para pantallas más grandes, que van sobrescribiendo las reglas vigentes para las pantallas más pequeñas.
El enfoque mobile first queda bien ilustrado por el conocido CSS Utility Framework “Tachyons”. Este define 3 breakpoints por defecto: ‘not-small’, ‘medium’ y ‘large’:
/* Tachyons Breakpoints */
/* 'not-small' Breakpoint */
@media screen and (min-width: 30em) { /* … */ }
/* 'medium' Breakpoint */
@media screen and (min-width: 30em) and (max-width: 60em) { /* … */ }
/* 'large' Breakpoint */
@media screen and (min-width: 60em) { /* … */ }
Ten en cuenta que, siguiendo el enfoque mobile first, no tienes un ‘small’ breakpoint propio. Las especificaciones para los dispositivos pequeños simplemente se definen sin un breakpoint.
Tachyons-Breakpoint | Explicación |
---|---|
not-small | Incluye los anchos de pantalla de los breakpoints ‘medium’ y ’large’ |
medium | Incluye los anchos de pantalla entre los Breakpoints ’not-small’ y ’large’ |
large | Incluye solo las pantallas grandes |
Dentro de los breakpoints, se definen reglas de estilo para los elementos cuya visualización debe adaptarse a pantallas de distinto tamaño. Puede que ya te hayas dado cuenta de que esta centralización del CSS Codebase de un proyecto web es complicada. Normalmente es preferible almacenar todas las propiedades CSS de un elemento en su propio archivo por separado.
- Plantillas profesionales, dominio y correo electrónico
- Herramientas SEO y más de 17 000 imágenes libres de derechos
- Plugin para hacer reservas online
Entender los preprocesadores y postprocesadores de CSS
Para poder modular el código CSS de un proyecto, se utilizaron primero varios preprocesadores de CSS. Tal vez estés familiarizado con los lenguajes Sass, Less o Stylus. Más tarde, se incorporó un postprocesador de CSS llamado PostCSS a través del proyecto Node.js. Todas las tecnologías mencionadas permiten encapsular las CSS Media Queries dentro de un selector CSS. De este modo, las reglas de estilo de un elemento pueden definirse de forma conjunta para las diferentes condiciones de los medios. A continuación, un ejemplo con Stylus.
Archivo Stylus ‘text.styl’ para las propiedades del texto:
// Definiciones mobile first
p
font-size: 16px
// Definiciones para el breakpoint 'not-small'
@media screen and (min-width: 30em)
font-size: 18px
Archivo Stylus ‘link.styl’ para las propiedades de los enlaces:
// Definiciones mobile first
a
color: blue
// Definiciones para el breakpoint 'not-small'
@media screen and (min-width: 30em)
text-decoration: underline
El preprocesador Stylus traduce los archivos al idioma CSS y junta las reglas de CSS Media Query bajo un único breakpoint. El código Stylus mencionado se traduce al código CSS de la siguiente manera:
/* Definiciones mobile first */
p {
font-size: 16px;
}
a {
color: blue;
}
/* Definiciones para el breakpoint 'not-small' */
@media screen and (min-width: 30em) {
p {
font-size: 18px;
}
a {
text-decoration: underline;
}
}
Comprender los CSS Utility Frameworks
El enfoque de encapsular las CSS Media Queries dentro de las reglas de estilo de un elemento y procesarlas a través del procesador CSS funciona. Sin embargo, esto sigue obligando al desarrollador a alternar entre el plano HTML y el CSS. También es necesario dividir los elementos en diferentes categorías dentro de HTML, cada categoría con nombre único. La logística que resulta de ello genera una complejidad no deseada. Aquí es donde entran a jugar los CSS Utility Frameworks, una tecnología imprescindible en la actualidad.
Un CSS Utility Framework interconecta las propiedades CSS base mediante breakpoints. Las categorías CSS resultantes pueden asignarse a cualquier elemento en HTML. Esto permite definir responsive layouts y componentes únicamente en HTML sin necesidad de redactar código en CSS. El uso de un CSS Utility Framework permite crear prototipos de manera rápida y es ideal para el desarrollo de componentes. Por ello, los CSS Utility Frameworks suelen utilizarse junto con tecnologías orientadas a componentes como son React y Vue.
Veamos otro ejemplo del CSS Utility Framework Tachyons. Echa un vistazo al siguiente código CSS. Primero definimos las categorías que van de ‘mw1’ a ‘mw3’, las cuales limitan el ancho máximo de cualquier elemento a valores entre ‘1rem’ y ‘3rem’. Además, definimos las correspondientes categorías CSS dentro de los breakpoints “medio” y “grande” ya existentes, las categorías llevarán en su nombre la abreviatura de su breakpoint respectivo:
/* Tachyons */
/* Ancho del Mobile-First */
.mw1 { max-width: 1rem; }
.mw2 { max-width: 2rem; }
.mw3 { max-width: 3rem; }
/* Breakpoint 'medium' */
@media screen and (min-width: 30em) and (max-width: 60em) {
.mw1-m { max-width: 1rem; }
.mw2-m { max-width: 2rem; }
.mw3-m { max-width: 3rem; }
}
/* Breakpoint 'large' */
@media screen and (min-width: 60em) {
.mw1-l { max-width: 1rem; }
.mw2-l { max-width: 2rem; }
.mw3-l { max-width: 3rem; }
}
Con la ayuda de las categorías CSS, podemos redactar la totalidad de los elementos responsivos en HTML. El siguiente segmento de código HTML define una imagen que tiene un ancho máximo de ‘1rem’ en pantallas pequeñas. La imagen se ajusta automáticamente al ancho de pantalla disponible. En las pantallas medianas, el elemento ocupa un máximo de ‘2rem’, en las grandes un máximo de ‘3rem’.
<img class="mw1 mw2-m mw3-l" src="/imagen.png" alt="Una imagen responsiva">
Los CSS Utility Frameworks definen un gran número de categorías base, cada una de las cuales define una sola propiedad CSS. Además de las dimensiones de un elemento, también se especifican las características de la tipografía, el color y todas las demás propiedades que se nos puedan ocurrir. Para cada propiedad base, cada CSS Utility Framework tiene varias categorías definidas, una para cada breakpoint existente. Combinando varias categorías, se pueden juntar casi cualquier tipo de elemento responsivo que se desee.
El Framework Tachyons al que nos hemos referido anteriormente, tiene ya varios años y no se sigue desarrollando activamente. Sin embargo, debido a lo relativamente sencillo que es, sigue mereciendo la pena empezar con Tachyons para aprender sobre el diseño responsivo. La manera más fácil de entender este enfoque es fijándose en los componentes Tachyons. Estos son elementos de ejemplo que se definen por completo a través de las categorías de utilidad.
Como sucesor natural de Tachyons, hoy existe una variante moderna llamada TailwindCSS. TailwindCSS tiene algunas ventajas sobre Tachyons. Por ejemplo, el proyecto sigue en desarrollo activo y es compatible con la mayoría de los sistemas de desarrollo front-end más populares. Además, TailwindCSS puede adaptarse completamente a las necesidades específicas de un proyecto. Todos los ajustes por defecto se pueden configurar fácilmente, como los breakpoints, la escala del tamaño de la fuente, etc.
A pesar de lo cómodo que resulta trabajar con los CSS Utility Frameworks, también tienen un gran inconveniente: para definir un elemento puede que necesite combinar un gran número de categorías base. Además, por defecto, el archivo CSS original contiene categorías para todas las combinaciones de valores CSS y breakpoints. En el caso de TailwindCSS, hay miles de categorías, lo que hace que el archivo CSS sin comprimir aumente su tamaño hasta alcanzar varios megabytes, un tamaño insostenible desde el punto de vista del rendimiento.
Afortunadamente, TailwindCSS ofrece dos soluciones. En primer lugar, el framework reconoce la instrucción ‘@apply’, que sirve para combinar varias categorías utilizadas repetidamente bajo una nueva categoría. En segundo lugar, TailwindCSS es compatible con la herramienta PurgeCSS. Esta herramienta se utiliza como parte del proceso de construcción para eliminar todas las categorías no empleadas en la construcción de productos. PurgeCSS procesa las plantillas HTML del proyecto e incluye solo las categorías CSS del código CSS original que haya encontrado. Esto reduce el tamaño del archivo de código original a un nivel admisible.