CSS (Cascading Style Sheets) es el lenguaje de estilo estándar de la web. Define cómo se presenta cada elemento HTML en pantalla, en papel o en cualquier otro medio. En 2026 CSS es un lenguaje maduro capaz de resolver layout bidimensional, sistemas de diseño completos, animación, transiciones entre vistas y tematización con una expresividad que hace innecesarios muchos preprocesadores.
¿Qué es CSS?
CSS separa el contenido (HTML) de la presentación. Esta separación permite rediseñar una página sin tocar la estructura, mantener hojas de estilo reutilizables y ofrecer experiencias adaptadas al dispositivo, al idioma y a las preferencias del usuario (tema claro u oscuro, movimiento reducido, contraste alto).
.boton {
background: var(--color-primario);
color: light-dark(white, black);
padding-inline: var(--space-4);
padding-block: var(--space-2);
border-radius: var(--radius-md);
transition: background 200ms ease-out;
}
Sintaxis básica
Una regla se compone de un selector y un bloque de declaración con pares propiedad y valor.
selector {
propiedad: valor;
}
- Selector: apunta a los elementos HTML que recibirán los estilos.
- Propiedad: el aspecto visual o de layout que se modifica (
color,font-size,display). - Valor: el valor asignado a la propiedad (
oklch(0.7 0.12 250),1rem,grid).
Cómo incluir CSS en HTML
Hay tres formas de aplicar CSS. Para proyectos reales se recomienda siempre la hoja externa porque permite caché, versionado y separación de responsabilidades.
<link rel="stylesheet" href="estilos.css">
Los estilos internos en <style> sirven para prototipos y los estilos en línea (style="...") solo para casos puntuales y librerías de componentes.
Cascada, herencia y especificidad
Cuando varias reglas apuntan al mismo elemento, CSS decide cuál aplica en este orden:
- Origen y capas (
@layer): las reglas declaradas dentro de capas ceden ante las reglas fuera de capas; entre capas gana la declarada más tarde. - Especificidad: ID (1,0,0) supera a clase (0,1,0), que supera a tipo (0,0,1).
- Orden de aparición: a igual especificidad, gana la última regla.
!importantrompe la especificidad dentro del mismo origen y capa.
Diagrama de cascada
flowchart TD
A["Origen: User agent, User, Author"] --> B{"Capas @layer"}
B --> C["Dentro de capas (orden declarado)"]
B --> D["Fuera de capas (prioridad mayor)"]
C --> E["Especificidad: ID / clase / tipo"]
D --> E
E --> F["Orden de aparición"]
F --> G["!important invierte el orden entre capas"]
G --> H["Regla ganadora aplicada al elemento"]
Selectores esenciales
h1 { font-size: 2rem; }
.destacado { font-weight: 600; }
#encabezado { background: var(--color-superficie); }
ul li { color: var(--color-acento); }
div > p { margin-block: 0.5rem; }
Los selectores modernos :is(), :where() y :has() amplían mucho las posibilidades: :where() no suma especificidad (ideal para resets), :is() agrupa selectores manteniendo la mayor especificidad del grupo, y :has() permite estilos de padre según los hijos.
Modelo de caja
Cada elemento es una caja rectangular con contenido, padding, border y margin. La propiedad box-sizing: border-box incluye padding y border dentro del ancho declarado; es el ajuste recomendado globalmente.
flowchart TB
subgraph Margin["margin (fuera de la caja)"]
subgraph Border["border"]
subgraph Padding["padding"]
Content["content-box"]
end
end
end
Las propiedades lógicas (margin-inline, padding-block, border-inline-start) son preferibles a margin-left o padding-top porque se adaptan a la dirección de lectura (LTR, RTL, vertical).
Tipografía y color
-
Tipografía fluida con
clamp()para adaptar tamaños entre móvil y escritorio sin saltos:h1 { font-size: clamp(2rem, 5vw + 1rem, 3.5rem); line-height: 1.2; text-wrap: balance; } -
Color perceptualmente uniforme con
oklch(), que permite escalas de color coherentes::root { --primario: oklch(0.7 0.15 250); --primario-suave: oklch(from var(--primario) calc(l + 0.15) c h); } -
Mezcla de colores con
color-mix(in oklch, A X%, B)para estados (hover, disabled) sin calcular manualmente cada tono. -
Tema claro u oscuro automático con
light-dark()ycolor-scheme: light dark;en:root.
Layout: Flexbox y Grid
Flexbox (una dimensión)
Ideal para barras de navegación, listas de acciones o tarjetas simples. Se organiza a lo largo de un eje principal y otro transversal.
flowchart LR
A[Contenedor flex] --> B[justify-content: eje principal]
A --> C[align-items: eje transversal]
A --> D[flex-wrap: salto de línea]
B --> E[flex-start / center / space-between / space-evenly]
C --> F[stretch / center / baseline]
.barra {
display: flex;
gap: 1rem;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
}
Grid (dos dimensiones)
Grid resuelve layouts completos con filas y columnas. Las pistas (tracks) se definen con grid-template-columns, grid-template-rows y grid-template-areas.
flowchart TB
G[display: grid] --> C[grid-template-columns]
G --> R[grid-template-rows]
G --> A[grid-template-áreas]
C --> C1["repeat(auto-fit, minmax(15rem, 1fr))"]
R --> R1["auto 1fr auto"]
A --> A1["'header header' 'nav main' 'footer footer'"]
G --> S[subgrid: hereda pistas del padre]
G --> Gap[gap: espacio entre pistas]
.tablero {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
gap: 1.5rem;
}
Subgrid
subgrid permite que un hijo comparta las pistas del grid padre y alinee columnas o filas entre varios niveles sin recalcular medidas.
Responsive moderno
Tres herramientas complementarias cubren todo el abanico responsive:
@media: adapta estilos según el viewport y las preferencias del usuario (prefers-color-scheme,prefers-reduced-motion,prefers-contrast).@container: adapta un componente según el ancho de su contenedor, no del viewport. Requierecontainer-type: inline-sizeen el contenedor.@scope: limita el alcance de un bloque de estilos a un subárbol concreto, útil para componentes aislados.
.tarjetas { container-type: inline-size; }
@container (min-width: 30rem) {
.tarjeta { display: grid; grid-template-columns: 40% 1fr; }
}
Custom properties, @property y cascade layers
-
Custom properties: variables CSS reutilizables (
--color-primario) consultadas convar(). -
@property: tipa las variables (sintaxis, valor inicial, herencia) para poder animarlas. -
@layer: declara una cascada explícita. Patrón recomendado:@layer reset, base, components, utilities;
Stacking context
Cuando un elemento tiene position distinto de static y un z-index, un opacity menor que 1 o un transform, crea un nuevo contexto de apilamiento que aísla a sus hijos del exterior. Entender esto es clave para resolver bugs de superposición.
flowchart TB
Root["Contexto raíz (html)"] --> Ctx1["Contexto creado por position + z-index"]
Root --> Ctx2["Contexto creado por opacity < 1"]
Ctx1 --> H1[Hijo con z-index: 10]
Ctx1 --> H2[Hijo con z-index: 5]
Ctx2 --> H3[Hijo aislado: no compite con Ctx1]
Transiciones, animaciones y view transitions
Las transiciones animan cambios de propiedad; las animaciones definen secuencias con @keyframes. view-transition permite transiciones suaves al cambiar de ruta en una SPA o al actualizar grandes zonas del DOM, nombrando elementos con view-transition-name.
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important;
}
}
Pseudo-clases y pseudo-elementos
:hover, :focus, :focus-visible, :active, :target, :disabled, :invalid y :has() son las pseudo-clases más utilizadas. Entre los pseudo-elementos, ::before, ::after, ::first-letter, ::marker, ::placeholder y ::selection cubren la mayoría de necesidades decorativas.
Accesibilidad y buenas prácticas
- Contraste suficiente (AA o AAA) calculado en espacio perceptual (
oklch). - Foco visible: nunca suprimir
outlinesin ofrecer un:focus-visiblealternativo. - Respeto a
prefers-reduced-motionyprefers-contrast. - Semántica HTML fuerte antes de cualquier estilo.
- Nombres de clases en una metodología (BEM, utility-first, OOCSS) para escalar.
Anchor positioning
CSS 2026 introduce anchor-name y la función anchor() para posicionar un elemento relativo a otro sin JavaScript (tooltips, popovers, menús). Combinado con el atributo HTML popover, simplifica componentes antes dependientes de librerías externas.
Nesting nativo
La sintaxis anidada llega a CSS estándar sin preprocesadores. Se ancla con el símbolo & y permite agrupar selectores relacionados mejorando la legibilidad.
.card {
padding: var(--space-4);
& .titulo { font-size: 1.25rem; }
&:hover { background: color-mix(in oklch, canvas 90%, var(--primario)); }
}
Herramientas y recursos
- DevTools del navegador para inspección, auditoría de accesibilidad y pruebas de container queries.
- Validador oficial W3C CSS Validator.
- Documentación completa en MDN Web Docs.
- Playgrounds como CodePen o StackBlitz para experimentar.