WA3.2 Capas, adaptación por contenedor y layouts avanzados¶
Cómo se han comprobado los ejemplos
Todos los ejemplos son editores con vista previa que se ejecutan en tu navegador: cámbialos y mira el resultado. Los valores que se citan en el texto (tamaños, número de columnas, qué color gana) se han comprobado en un navegador real. Las funciones de esta unidad funcionan en los navegadores actuales; si tu proyecto debe funcionar en navegadores antiguos, mira Can I use antes de usarlas.
La cascada, y por qué a veces ganan «los que no deben»¶
Cuando dos reglas chocan, el navegador decide por este orden:
- Origen e importancia (estilos del navegador, del usuario, del autor; y
!important). - Capa (
@layer), si las hay. - Especificidad del selector.
- Orden: la última gana.
En proyectos grandes (con un reset, una librería de componentes y tu propio CSS), la lucha de especificidades acaba en !important por todas partes. Las capas lo evitan: tú decides el orden de importancia de grupos enteros de reglas, sin importar lo específicos que sean sus selectores.
@layer: capas de estilos¶
Se declara el orden de las capas (de menos a más prioridad) y se mete cada grupo de reglas en la suya. Una capa posterior gana a una anterior aunque su selector sea mucho menos específico.
#b1 tiene un selector de id (muy específico) pero está en la capa base, que pierde contra componentes: el botón sale azul. El #b2, sin capa, gana a todo: verde. Un esquema habitual:
@layer reset, base, componentes, utilidades; /* de menor a mayor prioridad */
| Capa | Contenido | Por qué en ese orden |
|---|---|---|
reset |
Normalizar márgenes, box-sizing… |
Lo más fácil de pisar |
base |
Estilos de body, a, h1… |
Valores por defecto |
componentes |
Botones, tarjetas, menús | El CSS de cada pieza |
utilidades |
.oculto, .centrado |
Siempre deben ganar |
Además, una librería de terceros que cargues dentro de una capa (@import url(...) layer(libreria);) nunca pisará tu CSS, por muy específico que sea el suyo.
!important en capas va al revés
Con !important el orden de las capas se invierte: gana la capa anterior. Es una función pensada para que un reset o una regla de accesibilidad se pueda proteger. Si no entiendes por qué algo no cambia, mira las herramientas del navegador: indican la capa de cada regla.
Consultas de contenedor¶
Una consulta de medios (@media) mira el tamaño de la ventana. Pero un componente (una tarjeta) puede estar en una barra lateral estrecha o en la zona principal ancha con la misma ventana. Las consultas de contenedor miran el espacio que tiene el componente, así que la tarjeta se adapta a donde está, no a la pantalla.
Hay que hacer dos cosas: declarar quién es el contenedor (container-type) y escribir la consulta con @container.
Al ensanchar la caja por encima de 28 rem la tarjeta pasa de columna a fila, sin que cambie la ventana. Dos detalles:
container-type: inline-sizehace que el elemento controle su propio ancho (la consulta mira solo su anchura).- Los estilos de dentro no pueden cambiar el propio contenedor con la consulta (sería un círculo), solo a sus descendientes.
Con contenedores también hay unidades relativas a su tamaño: cqw (1 % del ancho del contenedor), cqi, cqh.
Grid avanzado¶
Columnas que se adaptan solas¶
La combinación repeat(auto-fit, minmax(…, 1fr)) crea tantas columnas como quepan, y todas del mismo ancho, sin una sola consulta de medios:
minmax(9rem, 1fr) quiere decir «cada columna mide al menos 9 rem y se reparte lo que sobra». auto-fit crea las columnas que quepan. El min(100%, 9rem) evita que, en pantallas más estrechas que 9 rem, la columna se desborde.
auto-fit |
auto-fill |
|
|---|---|---|
| Con pocos elementos | Las columnas se estiran para ocupar todo el ancho | Se conservan columnas vacías |
subgrid: alinear el interior de tarjetas distintas¶
Un problema clásico: tres tarjetas con títulos de distinta longitud; el texto y el pie de cada una quedan desalineados entre sí. Con subgrid, las tarjetas comparten las filas de la rejilla padre:
Sin subgrid, cada tarjeta calcularía sus filas por su cuenta. Con él, «Ver más» queda a la misma altura en las tres, aunque los títulos tengan distinta longitud.
Más herramientas útiles¶
| Propiedad | Para qué |
|---|---|
aspect-ratio: 16 / 9 |
Mantener la proporción de una caja sin trucos de padding |
object-fit: cover |
Una imagen que llena su caja recortándose, sin deformarse |
position: sticky; top: 0 |
Un elemento que se queda pegado al hacer scroll (cabeceras de tabla, menús) |
scroll-snap-type |
Carruseles que se detienen en cada elemento |
text-wrap: balance |
Reparte el texto de un título en líneas equilibradas |
color-mix(in srgb, red 30%, white) |
Mezclar colores en CSS (tonos de un color de marca) |
@supports (propiedad: valor) |
Usar algo solo si el navegador lo entiende |
gap |
Espacio entre elementos en Flexbox y Grid (¡sin márgenes!) |
Errores frecuentes¶
| Error | Cómo evitarlo |
|---|---|
!important por todas partes para ganar a una librería |
@layer: la librería en una capa anterior |
@media para algo que depende del espacio del componente, no de la pantalla |
@container |
Olvidar container-type y preguntarse por qué la consulta no hace nada |
El contenedor debe declararlo |
auto-fill cuando se quieren columnas que llenen el ancho |
auto-fit |
minmax(12rem, 1fr) en una pantalla de 10 rem (se desborda) |
minmax(min(100%, 12rem), 1fr) |
| Alinear el interior de tarjetas con alturas fijas | subgrid |
padding-top: 56% para fijar una proporción |
aspect-ratio |
Para practicar¶
Los ejercicios WA3.4 a WA3.6 de WA3 · Ejercicios practican @layer, consultas de contenedor y rejillas adaptables.