Estilos en Astro
Astro te deja elegir cómo quieres trabajar los estilos.
Puedes usar CSS tradicional, módulos CSS, Tailwind, Sass o incluso librerías externas.
Lo mejor es que todo convive sin problemas.
1. Tipos de estilos en Astro #
Astro soporta tres formas principales de aplicar estilos:
| Tipo de estilo | Dónde se aplica | Ideal para |
|---|---|---|
Local (en el mismo archivo .astro) | Solo afecta a ese componente/página | Componentes pequeños |
Global (src/styles/global.css) | Se aplica a toda la web | Layouts o estilos generales |
| Frameworks (Tailwind, Bootstrap, etc.) | A toda la web | Diseños rápidos y modernos |
2. Estilos locales (scoped) #
Astro aplica por defecto el encapsulamiento de estilos, es decir:
un <style> dentro de un archivo .astro solo afecta a ese archivo.
Ejemplo:
1<h1>Hola mundo</h1> 2 3<style> 4 h1 { 5 color: #4f46e5; 6 text-align: center; 7 } 8</style>
✅ Este color solo afecta al <h1> de este archivo.
Si en otra página tienes un <h1>, no heredará este color.
💡 Esto evita conflictos entre estilos de distintas páginas o componentes.
3. Estilos globales #
Si quieres que los estilos afecten a toda la web (fuentes, colores, márgenes, etc.), crea:
src/styles/global.css
Ejemplo:
1body { 2 margin: 0; 3 font-family: system-ui, sans-serif; 4 background-color: #f8fafc; 5} 6 7a { 8 color: #4f46e5; 9 text-decoration: none; 10}
Y luego impórtalo en tu layout principal (BaseLayout.astro):
1--- 2import '../styles/global.css'; 3--- 4<html lang="es"> 5 <body> 6 <slot /> 7 </body> 8</html>
Así, todos tus estilos globales se aplicarán a las páginas que usen ese layout.
4. CSS Modules (opcional) #
También puedes usar CSS Modules, un sistema que crea nombres únicos automáticamente.
Ejemplo:
Button.module.css
1.btn { 2 background-color: #4f46e5; 3 color: white; 4 padding: 10px 20px; 5 border-radius: 8px; 6}
Button.astro
1--- 2import styles from './Button.module.css'; 3--- 4 5<button class={styles.btn}>Haz clic</button>
Resultado:
Astro renombra automáticamente .btn a algo como .btn_ab123 para evitar choques de nombres.
5. Usar Tailwind CSS en Astro #
¿Qué es Tailwind? #
Tailwind CSS es un framework que te permite escribir clases en HTML directamente para diseñar sin archivos CSS separados.
Instalación: #
Ejecuta en la terminal:
1npx astro add tailwind
Esto instalará Tailwind y configurará los archivos automáticamente (tailwind.config.mjs, postcss.config.mjs).
Ejemplo con Tailwind #
1<h1 class="text-4xl font-bold text-indigo-600 text-center mt-10"> 2 ¡Hola desde Tailwind y Astro! 3</h1> 4<p class="text-gray-600 text-center"> 5 Rápido, moderno y sin complicaciones. 6</p>
✅ No necesitas crear hojas CSS.
✅ Todo está optimizado y listo para producción.
6. Combinar estilos personalizados y Tailwind #
Puedes seguir usando tus propios archivos CSS además de Tailwind.
Por ejemplo:
global.css
1.card { 2 box-shadow: 0 2px 8px rgba(0,0,0,0.1); 3 border-radius: 10px; 4 background: white; 5}
Y en tu componente:
1<div class="card p-6 text-center"> 2 <h3 class="text-lg font-semibold text-indigo-600">Combinando Tailwind y CSS</h3> 3</div>
💡 Tailwind y tu CSS pueden coexistir sin problema.
7. Integrar librerías de diseño #
Puedes añadir frameworks como Flowbite, DaisyUI, Bootstrap o Material UI (si usas React).
Ejemplo con Flowbite:
1npm install flowbite
Luego, en astro.config.mjs:
1import { defineConfig } from 'astro/config'; 2import tailwind from "@astrojs/tailwind"; 3 4export default defineConfig({ 5 integrations: [tailwind({ config: { plugins: ['flowbite/plugin'] } })], 6});
Y en tu HTML puedes usar componentes listos, como:
1<button class="btn btn-primary">Guardar</button>
8. Buenas prácticas con estilos en Astro #
- ✅ Usa estilos locales por defecto.
- ✅ Crea un archivo
global.csssolo para lo esencial (fuentes, colores, body). - ✅ Tailwind simplifica y acelera el diseño.
- ✅ Evita CSS duplicado en varios componentes.
- ✅ Si usas Tailwind, define variables en
tailwind.config.mjs(colores, fuentes, etc.).
Laboratorios: diseñar componentes con CSS real #
El ámbito local de Astro decide a qué elementos se aplica un estilo.
Flexbox, Grid, las media queries y el modelo de caja deciden cómo se dibujan
esos elementos. Estos laboratorios usan CSS en el navegador, por lo que puedes
aplicar las mismas propiedades dentro del <style> de un componente .astro.
Los ejemplos de Tailwind serían otra forma de expresar esas reglas.
1. Flexbox para navegación y grupos de elementos #
Prueba una fila centrada o un menú espaciado. Después cambia a columnas con
wrap: el eje principal pasa a ser vertical, y los elementos que no caben en
la altura disponible saltan a otra columna. Reduce el ancho y comprueba qué
ocurre con nowrap cuando las tarjetas no se encogen.
Laboratorio interactivo
Flexbox: coloca elementos y cambia los ejes
Modifica las propiedades y observa cómo el navegador distribuye cinco elementos. El borde marca el contenedor; cada tarjeta conserva una base de 80 px.
Si la vista supera el ancho disponible, desliza horizontalmente para ver el resto.
Eje principal: horizontal. Eje transversal: vertical. justify-content actúa en el principal; align-items, en el transversal. Las tarjetas no se encogen (flex-shrink: 0).
.contenedor {
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: center;
flex-wrap: wrap;
gap: 12px;
width: 480px;
height: 320px;
}
.tarjeta { flex: 0 0 80px; }Experimenta: Centra las tarjetas en ambos ejes. Cambia row por column: ¿qué controla ahora justify-content? Reduce el ancho y compara wrap con nowrap.
2. Grid para tarjetas y cabeceras #
Parte de tres columnas iguales y haz que la primera tarjeta ocupe toda la fila.
Prueba después una sola columna estrecha. Si reduces el número de columnas,
el laboratorio ajusta el span para mantenerlo dentro de la cuadrícula.
Laboratorio interactivo
Grid: reparte columnas y ocupa celdas
Construye una cuadrícula con columnas del mismo tamaño. Haz que la primera tarjeta ocupe varias columnas y observa cómo se recolocan las demás.
Si la vista supera el ancho disponible, desliza horizontalmente para ver el resto.
3 columnas iguales; la primera tarjeta ocupa 1. Grid coloca los demás elementos en las siguientes celdas disponibles.
.contenedor {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 12px;
justify-items: stretch;
}
.tarjeta:first-child { grid-column: span 1; }Experimenta: Crea tres columnas y haz que la primera tarjeta ocupe dos. Cambia a dos columnas. ¿Dónde se coloca la tercera tarjeta? Prueba start frente a stretch.
3. Responsive sin cambiar el tamaño de tu navegador #
La página de prueba tiene su propio viewport. Compara móvil, tablet y escritorio;
después prueba justo antes y justo en el breakpoint. min-width incluye el
valor límite. Un diseño responsive responde al ancho disponible, no al nombre
del dispositivo: los tamaños de ejemplo solo facilitan la comparación.
Laboratorio interactivo
Responsive: prueba los límites del breakpoint
La vista previa tiene su propio viewport. Su media query se ejecuta dentro de un iframe y responde al ancho del laboratorio, independientemente del tamaño de tu pantalla.
Si la vista supera el ancho disponible, desliza horizontalmente para ver el resto.
480 < 600: reglas base; una columna y navegación vertical.
.cards { display: grid; grid-template-columns: 1fr; }
nav { display: flex; flex-direction: column; }
@media (min-width: 600px) {
.cards { grid-template-columns: repeat(3, minmax(0, 1fr)); }
nav { flex-direction: row; }
}Experimenta: Prueba un píxel por debajo del breakpoint, exactamente en él y un píxel por encima. ¿min-width incluye el valor límite? Cambia el breakpoint y repite.
4. Modelo de caja y dimensiones reales #
Compara content-box y border-box con el mismo width, padding y borde.
Los paneles muestran simultáneamente ambos cálculos. El margen permanece fuera
del ancho declarado en los dos casos.
Laboratorio interactivo
Modelo de caja: ¿cuánto espacio ocupa?
Distingue contenido, padding, borde y margen. Alterna box-sizing y comprueba por qué dos elementos con el mismo width pueden ocupar distinto espacio.
Si la vista supera el ancho disponible, desliza horizontalmente para ver el resto.
Verde: contenido · Azul: padding · Violeta: borde · Naranja: margen.
Contenido: 160 px. Caja con borde: 200 px. Huella horizontal con márgenes: 232 px.
Con content-box: caja de 200 px; el contenido mide 160 px.
Con border-box: caja de 160 px; el contenido mide 120 px.
.caja {
box-sizing: content-box;
width: 160px;
padding: 16px;
border: 4px solid purple;
margin: 16px;
}
/* 160 + 2 × 16 + 2 × 4 = 200 px; margen fuera */Experimenta: Pon width en 160, padding en 20 y borde en 10. Predice el ancho exterior y cambia a border-box. ¿Se incluye el margen dentro de width?
5. Compara el movimiento con CSS #
Una animación puede durar lo mismo y recorrer la misma distancia con distintas
curvas de velocidad. Compara la referencia lineal con ease-in, ease-out y
pasos discretos. Pausa el movimiento para observar la posición de las tarjetas.
Laboratorio interactivo
Animaciones: tiempo, curva y dirección
Compara una referencia lineal con una animación configurable. Ambas recorren la misma distancia en el mismo tiempo; observa cómo cambia su velocidad dentro del recorrido.
Referencia linear
Configurada: linear
Si la vista supera el ancho disponible, desliza horizontalmente para ver el resto.
En pausa · 2 s por vuelta · normal. Cambiar parámetros reinicia la posición. Si tu sistema solicita reducir movimiento, la vista permanece estática.
@keyframes mover {
from { transform: translateX(0); }
to { transform: translateX(220px); }
}
.tarjeta {
animation: mover 2s linear infinite normal;
animation-play-state: paused;
}Experimenta: Selecciona ease-in y reproduce. ¿Qué tarjeta avanza primero? Pausa a mitad del recorrido. Prueba alternate y compara lo que ocurre al terminar cada vuelta.
Resumen del tema
Conceptos clave #
- CSS con ámbito local (Scoped): las etiquetas
<style>dentro de componentes.astroaplican aislamiento automático de clases para evitar colisiones globales. - Estilos globales (
global.css): configuración de tipografías base, resets de margen y variables de diseño importadas en el layout principal. - Módulos CSS (
.module.css): soporte nativo para nombres de clase hasheados únicos importables como objetos JavaScript (class={styles.btn}). - Integración con Tailwind CSS: instalación automática mediante
npx astro add tailwindconfigurando PostCSS y plugins enastro.config.mjs. - Convivencia y librerías UI: combinación libre de utilidades de Tailwind, CSS personalizado y componentes de librerías como Flowbite o DaisyUI.
Qué debes recordar #
Astro aísla los estilos en <style> por defecto; añade global.css en tu layout base para estilos transversales o integra Tailwind con npx astro add tailwind para estilado utilitario.