CSS en Astro

Cómo definir estilos en Astro


Hasta ahora hemos visto como crear componentes en Astro, pero no hemos utilizado CSS ni le hemos dado estilo a nuestros componentes. Hacerlo en Astro es muy sencillo, pero hay muchas formas diferentes, y cuál utilizar depende mucho de nuestra forma de trabajar y de lo que queramos.

La etiqueta <style>

La primera forma recomendada, muy sencilla y directa, es utilizar una etiqueta <style> y meter los estilos en su interior. Aunque en CSS estándar no se suelen utilizar mucho las etiquetas <style>, en Astro se recomienda como primera opción, puesto que el código final no queda como lo estamos escribiendo, sino que Astro se encarga de procesarlo, hacer ciertos cambios y acomodarlo de la mejor forma de cara al rendimiento y optimización del CSS.

En nuestro caso, sólo tendríamos que hacer algo como esto:

---
const title = "Mi componente de Astro";
---

<style>
  .container {
    background: #333;
    color: #ddd;

    h1 {
      color: deeppink;
    }
  }
</style>

<div class="container">
  <h1>{title}</h1>
  <p>Este es un pequeño componente para Manz.dev</p>
</div>

Uno de los puntos más interesantes de Astro, es que al tener todo separado por componentes .astro, los estilos CSS definidos en <style> no se aplican a ningún otro componente, sino que sólo se aplican al componente actual. Esto hace que no tengamos que preocuparnos de la colisión de clases y podamos incluso utilizar elementos muy genéricos al estilar.

Como se puede ver, se puede usar nesting puesto que ya es una característica nativa de CSS.

Estilos globales

En ciertos casos nos puede interesar utilizar estilos globales, porque queremos que el CSS que estamos escribiendo tenga efecto en todos los componentes de nuestro sitio. Para ello, podemos utilizar un bloque <style> pero añadirle el atributo is:global:

---
const title = "Mi componente de Astro";
---

<style>
  .container {
    background: #333;
    color: #ddd;
  }
</style>

<style is:global>
  h1 { color: deeppink }
</style>

<div class="container">
  <h1>{title}</h1>
  <p>Este es un pequeño componente para Manz.dev</p>
</div>

Observa que ahora tenemos dos bloques <style>. El primero sólo afecta al componente actual, sin embargo, el segundo es global, y afectará a todos los <h1> del sitio web de Astro, ya que se aplicará en un CSS global.

Por norma general, y por una cuestión de organización, recomiendo crear un bloque de estilos globales en el componente layout de modo que siempre que necesitemos establecer unos estilos globales, lo hagamos allí. Esto hará que tu CSS sea más organizado y predecible.

Se recomienda sólo utilizar los bloques <style is:global> en componentes específicos como excepciones muy concretas, sólo cuando sea absolutamente necesario.

Selector :global()

Existe una forma de definir estilos globales en el bloque <style> anterior, sin el atributo is:global. Se trata de utilizar el selector :global() de Astro:

---
const title = "Mi componente de Astro";
---

<style>
  .container {
    background: #333;
    color: #ddd;
  }

  :global(h1) { color: deeppink }
</style>

<div class="container">
  <h1>{title}</h1>
  <p>Este es un pequeño componente para Manz.dev</p>
</div>

Aunque es interesante, recomiendo no utilizarlo salvo que sea absolutamente necesario, ya que no es una sintaxis estándar que se está mezclando con código CSS estándar y que podría dar problemas si utilizaramos LightningCSS por ejemplo.

Importar estilos mediante import

Otra de las formas que proporciona Astro para definir estilos es utilizar un import de Javascript para importar un fichero .css. Esto permite que los estilos estén en un archivo .css a parte, pero aún así sean procesados por Astro.

---
import "./Component.css";   // El estilo es global
---

<div class="container">
  <h1>{title}</h1>
  <p>Este es un pequeño componente para Manz.dev</p>
</div>

En este caso tendríamos todo el código CSS en el fichero Component.css. Ten en cuenta que si utilizas esta forma de importar estilos, los estilos serán globales, por lo que afectarán a otros componentes, salvo que definas muy bien los selectores CSS para que no afecten a otras zonas.

Importar usando CSS Modules

Por último, si estás en el caso de que quieres utilizar la forma anterior de importar archivos .css independientes pero no quieres que sean globales, sino modulares y gestionarlo manualmente, lo que probablemente buscas es CSS Modules.

Astro es compatible con CSS Modules, ya que utiliza Vite por debajo y Vite soporta CSS modules. Lo único que tendrías que hacer es renombrar la extensión de tu archivo de .css por .module.css.

Nuestro componente quedaría así:

---
import styles from "./Component.module.css";
---

<div class={styles.container}>
  <h1>{title}</h1>
  <p>Este es un pequeño componente para Manz.dev</p>
</div>

El contenido del archivo Component.module.css sería exactamente igual al anterior Component.css. La diferencia de este sistema es que el import que realizamos se guarda en un objeto llamado styles. En este objeto se guardarán las clases que definimos en nuestro archivo CSS.

Observa más abajo, la etiqueta que antes era un <div class="container"> ahora es una etiqueta <div class={styles.container}>, es decir, una etiqueta que tendrá la clase que se ha definido en CSS Modules y corresponde con esos estilos.

Ten en cuenta que CSS Modules sólo procesa las clases. Los elementos base, como <h1>, seguirán siendo globales. Si no quieres que sean globales, usa una clase.

Si quieres saber más sobre CSS Modules, echa un vistazo al post CSS Modules.

¿Quién soy yo?

Soy Manz, vivo en Tenerife (España) y soy streamer partner en Twitch y profesor. Me apasiona el universo de la programación web, el diseño y desarrollo web y la tecnología en general. Aunque soy full-stack, mi pasión es el front-end, la terminal y crear cosas divertidas y locas.

Puedes encontrar más sobre mi en Manz.dev