astro-css-estilos-scoped-global

CSS en Astro Scoped, Global y Variables

  • 4 min

Uno de los puntos mas fuertes de Astro es como gestiona el Scope, la cascada y la especificidad de los estilos CSS.

Astro implementa por defecto CSS Scoped, a la vez que nos da herramientas para romper ese ámbito cuando sea necesario.

El estilo CSS Scope significa que el CSS de un componente se aplica solo al propio componente y no a toda la web.

El manejo de estilos en Astro es nativo y sin configuración. No necesitas instalar preprocesadores ni librerías CSS-in-JS complejas para empezar.

CSS Scoped

Imagina que tienes dos componentes: Hero.astro y Footer.astro. Ambos tienen un <h1> dentro.

En el desarrollo tradicional, si haces esto en tu CSS:

h1 { color: red; }
Copied!

Todos los títulos de tu web se volverán rojos. En Astro, esto no ocurre.

Cuando escribes una etiqueta <style> dentro de un componente .astro, esos estilos solo aplican a ese componente.

src/components/Hero.astro
<h1>Hola, soy el Hero</h1>

<style>
  /* Esto SOLO afecta al h1 dentro de Hero.astro */
  h1 {
    color: blue;
    font-size: 3rem;
  }
</style>
Copied!

Puedes tener otro componente Footer.astro con otro h1 y otro color, y nunca entrarán en conflicto.

Estilos globales

A veces queremos que los estilos sean globales. Por ejemplo, para un reset de CSS, para definir las fuentes base o para estilos de utilidades.

En Astro tenemos dos formas de hacerlo.

Si añades el atributo is:global a la etiqueta de estilo, Astro dejará de procesar esos selectores con el hash de ámbito. Se comportará como CSS “normal”.

<style is:global>
  /* Esto afectará a TODOS los h1 de la aplicación */
  h1 {
    font-family: 'Comic Sans MS', sans-serif; /* Por favor, no hagas esto */
  }

  body {
    background-color: #f0f0f0;
  }
</style>
Copied!

Usa is:global con precaución. Si abusas de él, pierdes las ventajas de la arquitectura de islas y vuelves a los problemas de mantenimiento del CSS tradicional.

A veces necesitas una mezcla: quieres que la mayoría de estilos sean locales, pero necesitas acceder a un elemento hijo que no controlas (por ejemplo, HTML inyectado desde un CMS o Markdown).

Para eso usamos el pseudo-selector :global().

<style>
  /* Estilo local para el contenedor */
  .articulo-blog {
    padding: 20px;
  }

  /* Estilo global SOLO para los hijos de .articulo-blog */
  .articulo-blog :global(p) {
    font-size: 1.2rem;
    line-height: 1.6;
  }
</style>
Copied!

Esto es extremadamente útil cuando estilas contenido que viene de un <slot />.

Importando archivos CSS externos

No estás obligado a escribir el CSS dentro del archivo .astro. Si prefieres tener tus estilos en archivos separados (o usas una librería), puedes importarlos.

---
// Importación directa en el frontmatter
import '../styles/mi-tema.css';
import 'bootstrap/dist/css/bootstrap.min.css';
---
Copied!

Astro detectará estos imports, los procesará (minificación, bundling) y los inyectará en la página automáticamente.

Variables CSS y define:vars

Podemos pasar variables de JavaScript (del frontmatter) directamente a nuestro CSS. Astro se encarga de crear las Custom Properties (variables CSS) necesarias.

Esta es, una de las características más potentes y menos conocidas de Astro.

Imagina un componente que acepta un color de fondo como Prop:

---
interface Props {
  colorFondo: string;
  imagenUrl: string;
}

const { colorFondo, imagenUrl } = Astro.props;
---

<div class="tarjeta">
  <h2>Tarjeta Dinámica</h2>
</div>

<style define:vars={{ colorFondo, url: `url(${imagenUrl})` }}>
  .tarjeta {
    background-color: var(--colorFondo);
    background-image: var(--url);
    padding: 20px;
    border-radius: 8px;
  }
</style>
Copied!

La directiva define:vars={{ variable }} hace lo siguiente:

  1. Toma el valor de JS.
  2. Lo inyecta como un estilo en línea en el elemento padre del componente (style="--colorFondo: #ff0000; ...").
  3. Lo hace disponible dentro del bloque <style> usando la sintaxis estándar var(--variable).

Esto elimina la necesidad de librerías CSS-in-JS (como Styled Components o Emotion) para el 90% de los casos de uso de estilos dinámicos.