Saltearse al contenido

Estilos y CSS

Astro fue diseñado para que estilar y escribir CSS sea pan comido. Escribe tu propio CSS directamente dentro de un componente de Astro o importa tu biblioteca de CSS favorita como Tailwind. También es compatible con lenguajes de estilo avanzados como Sass y Less.

Estilar un componente de Astro es tan fácil como agregar una etiqueta <style> a tu componente o plantilla de página. Cuando colocas una etiqueta <style> dentro de un componente de Astro, Astro detectará el CSS e incluirá tus estilos automáticamente.

src/components/MyComponent.astro
<style>
h1 { color: red; }
</style>

Las reglas de CSS en Astro <style> tienen un alcance local de forma predeterminada. Los estilos con alcance local se compilan para que sólo se apliquen al HTML escrito dentro de ese mismo componente. El CSS escrito dentro de un componente de Astro se encapsula automáticamente dentro del mismo.

Este CSS:

src/pages/index.astro
<style>
h1 {
color: red;
}
.text {
color: blue;
}
</style>

Se compila en esto:

<style>
h1[data-astro-cid-hhnqfkh6] {
color: red;
}
.text[data-astro-cid-hhnqfkh6] {
color: blue;
}
</style>

Los estilos locales no se filtran y no afectarán al resto de tu sitio web. En Astro, está bien usar selectores de baja especificidad como h1 {} o p {} porque se compilarán con alcance local en el resultado final.

Los estilos locales tampoco se aplicarán a otros componentes de Astro contenidos dentro del maquetado. Si necesitas estilar un componente hijo, considera envolver ese componente en un <div> (u otro elemento) que luego puedas estilar.

La especificidad de los estilos locales se conserva, lo que les permite convivir junto con otros archivos o librerías de CSS y, al mismo tiempo, conservar el encapsulamiento que impide que los estilos se filtren fuera del componente.

Si bien recomendamos estilos locales para la mayoría de los componentes, eventualmente puedes encontrar una razón válida para escribir CSS global. Puedes desactivar el CSS con alcance local predeterminado con el atributo <style is:global>.

src/components/GlobalStyles.astro
<style is:global>
/* Global, entregada tal como está al navegador.
Se aplica a todas las etiquetas <h1> de tu sitio web. */
h1 { color: red; }
</style>

También puedes mezclar reglas de CSS globales y locales en la misma etiqueta <style> usando el selector :global(). Esto se convierte en un patrón poderoso para aplicar estilos CSS a los elementos hijos de tu componente.

src/components/MixedStyles.astro
<style>
/* Con alcance solo a este componente */
h1 { color: red; }
/* Mixta: se aplica solo a los elementos `h1` hijos. */
article :global(h1) {
color: blue;
}
</style>
<h1>Title</h1>
<article><slot /></article>

Esta es una excelente manera de estilar cosas como artículos de blog o documentos con contenido basado en CMS donde el contenido vive fuera de Astro. Pero ten cuidado: los problemas relacionados a componentes cuyo estilo depende del componente padre pueden volverse difíciles de solucionar.

Los estilos locales deben usarse con la mayor frecuencia posible. Los estilos globales deben usarse solo cuando sea necesario.

Si necesitas combinar clases sobre un elemento dinámicamente, puedes usar el atributo class:list en archivos .astro.

src/components/ClassList.astro
---
const { isRed } = Astro.props;
---
<!-- Si `isRed` es verdadero, la clase será "box red". -->
<!-- Si `isRed` es falso, la clase será "box". -->
<div class:list={['box', { red: isRed }]}><slot /></div>
<style>
.box { border: 1px solid blue; }
.red { border-color: red; }
</style>
Visita nuestra página referencia de directivas para aprender más sobre class:list.

Agregado en: astro@0.21.0

La etiqueta <style> de Astro puede hacer referencia a cualquier variable CSS disponible en la página. También puedes pasar variables CSS directamente desde el frontmatter de tu componente usando la directiva define:vars.

src/components/DefineVars.astro
---
const foregroundColor = "rgb(221 243 228)";
const backgroundColor = "rgb(24 121 78)";
---
<style define:vars={{ foregroundColor, backgroundColor }}>
h1 {
background-color: var(--backgroundColor);
color: var(--foregroundColor);
}
</style>
<h1>Hola</h1>
Consulta nuestra página de referencia de directivas para obtener más información sobre define:vars.

Pasando una class a un componente hijo

Sección titulada Pasando una class a un componente hijo

En Astro, los atributos HTML tales como class no se pasan automáticamente a los componentes hijos.

En cambio, debes aceptar una prop class en el componente hijo y aplicársela al elemento raíz. Al desestructurar las props debes renombrarlo, porque class es una palabra clave (o reservada) en JavaScript.

Usando la estrategia por defecto de estilo con ámbito, también debes pasar el atributo data-astro-cid-*. Puedes hacer esto pasando el ...rest de las props al componente. Si has cambiado scopedStyleStrategy a 'class' o 'where', la prop ...rest no es necesaria.

src/components/MyComponent.astro
---
const { class: className, ...rest } = Astro.props;
---
<div class={className} {...rest}>
<slot/>
</div>
src/pages/index.astro
---
import MyComponent from "../components/MyComponent.astro"
---
<style>
.red {
color: red;
}
</style>
<MyComponent class="red">¡Esto será rojo!</MyComponent>

Puedes estilar elementos HTML en línea utilizando el atributo style. Esto puede ser un string CSS o un objeto de propiedades CSS.

src/pages/index.astro
// Estos son equivalentes:
<p style={{ color: "brown", textDecoration: "underline" }}>My text</p>
<p style="color: brown; text-decoration: underline;">My text</p>

Hay dos formas de resolver hojas de estilo globales externas: la primera es usando una importación ESM para archivos ubicados dentro de src/, y la segunda es usando la URL absoluta para archivos ubicados en la carpeta public/, o alojados fuera de tu proyecto.

Lee más sobre el uso de archivos estáticos ubicados en public/ o src/.

Puedes importar hojas de estilo en el script de tu componente de Astro utilizando la sintaxis de importación ESM. Las importaciones de CSS funcionan como cualquier otra importación ESM en un componente de Astro, deben referenciarse usando la ruta relativa al componente y deben estar escritas en la parte superior del script de su componente, con cualquier otra importación.

src/pages/index.astro
---
// Astro empaquetará y optimizará este CSS automáticamente
// Esto también funciona para archivos de preprocesadores como .scss, .styl, etc.
import '../styles/utils.css';
---
<html><!-- Tu página aquí --></html>

Usar import con CSS a través de ESM es compatible con cualquier archivo JavaScript, incluidos los componentes JSX como React y Preact. Esto puede ser útil para escribir estilos granulares por componente para tus componentes de React.

Importando una hoja de estilos desde un paquete npm

Sección titulada Importando una hoja de estilos desde un paquete npm

Es posible que también necesites cargar hojas de estilos desde un paquete npm externo. Esto es especialmente común para utilidades como Open Props. Si tu paquete recomienda usar una extensión de archivo (es decir, package-name/styles.css en lugar de package-name/styles), esto debería funcionar como cualquier hoja de estilo local:

src/pages/random-page.astro
---
import 'package-name/styles.css';
---
<html><!-- Tu página aquí --></html>

Si tu paquete no sugiere usar una extensión de archivo (es decir, package-name/styles), ¡primero deberás actualizar tu configuración de Astro!

Digamos que estás importando un archivo CSS desde package-name llamado normalize (con la extensión de archivo omitida). Para asegurarnos de que podamos prerenderizar tu página correctamente, agrega package-name al array vite.ssr.noExternal:

astro.config.mjs
import { defineConfig } from 'astro/config';
export default defineConfig({
vite: {
ssr: {
noExternal: ['package-name'],
}
}
})

Ahora, puedes importar package-name/normalize. Esto será incluido y optimizado por Astro como cualquier otra hoja de estilos local.

src/pages/random-page.astro
---
import 'package-name/normalize';
---
<html><!-- Tu página aquí --></html>
Sección titulada Carga una hoja de estilos a través de etiquetas de “link”

También puedes usar la etiqueta <link> para cargar una hoja de estilos en la página. Esta deberá ser una ruta URL absoluta a un archivo CSS ubicado en la carpeta /public, o una URL a un sitio web externo. Los valores href relativos en <link> no son compatibles.

src/pages/index.astro
<head>
<!-- Local: /public/styles/global.css -->
<link rel="stylesheet" href="/styles/global.css" />
<!-- Externo -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs@1.24.1/themes/prism-tomorrow.css" />
</head>

Debido a que este método utiliza la carpeta public/, se salta el procesamiento, empaquetado y las optimizaciones de CSS que proporciona Astro. Si necesitas estas transformaciones, utiliza el método anterior importando una hoja de estilo local.

En ocasiones, los componentes de Astro deberán evaluar múltiples fuentes de CSS. Por ejemplo, tu componente podría importar una hoja de estilos CSS, incluir su propia etiqueta <style>, y ser renderizado dentro de un layout que importa CSS.

Cuando se aplican reglas conflictivas de CSS a un mismo elemento, los navegadores usan primero la especificidad y después el orden de aparición para determinar qué valor mostrar.

Si una regla es más específica que otra, no importa dónde aparezca la regla de CSS, su valor tendrá prioridad:

src/components/MiComponente.astro
<style>
h1 { color: red }
div > h1 {
color: purple
}
</style>
<div>
<h1>
¡Este encabezado será morado!
</h1>
</div>

Si dos reglas tienen la misma especificidad, entonces el orden de aparición es evaluado, y el último valor de la regla tomará prioridad:

src/components/MiComponente.astro
<style>
h1 { color: purple }
h1 { color: red }
</style>
<div>
<h1>
¡Este encabezado será rojo!
</h1>
</div>

Las reglas de CSS de Astro son evaluadas en este orden de aparición:

  • etiquetas <link> dentro de la etiqueta head (prioridad más baja)
  • estilos importados
  • estilos locales (prioridad más alta)

Usar estilos locales no incrementa la especificidad de tu CSS, pero siempre vendrán al final en el orden de aparición. Por lo tanto, tomarán prioridad sobre otros estilos de la misma especificidad. Por ejemplo, si importas una hoja de estilos que conflictúe con un estilo local, el valor del estilo local será aplicado:

src/components/hazlo-morado.css
h1 {
color: purple;
}
src/components/MiComponente.astro
---
import "./hazlo-morado.css"
---
<style>
h1 { color: red }
</style>
<div>
<h1>
¡Este encabezado será rojo!
</h1>
</div>

Si haces el estilo importado más específico, éste tendrá una mayor importancia que el estilo local:

src/components/hazlo-morado.css
div > h1 {
color: purple;
}
src/components/MiComponente.astro
---
import "./hazlo-morado.css"
---
<style>
h1 { color: red }
</style>
<div>
<h1>
¡Este encabezado será morado!
</h1>
</div>

Cuando importas múltiples hojas de estilo en un componente de Astro, las reglas de CSS son evaluadas en el orden en que son importadas. Una mayor especificidad siempre determinará qué estilos mostrar, no importa cuándo es evaluado el CSS. Pero, cuando haya estilos conflictivos que tengan la misma especificidad, el último estilo importado gana:

src/components/hazlo-morado.css
div > h1 {
color: purple;
}
src/components/hazlo-verde.css
div > h1 {
color: green;
}
src/components/MiComponente.astro
---
import "./hazlo-verde.css"
import "./hazlo-morado.css"
---
<style>
h1 { color: red }
</style>
<div>
<h1>
¡Este encabezado será morado!
</h1>
</div>

Mientras que las etiquetas <style> son locales y solo aplican al componente donde se las declara, puede “filtrarse” CSS importado a otros componentes. Al importar un componente se aplica cualquier CSS que este importe, incluso si el componente nunca es usado:

src/components/ComponenteMorado.astro
---
import "./hazlo-morado.css"
---
<div>
<h1>Yo importo CSS morado.</h1>
</div>
src/components/MiComponente.astro
---
import "./hazlo-verde.css"
import ComponenteMorado from "./ComponenteMorado.astro";
---
<style>
h1 { color: red }
</style>
<div>
<h1>
¡Este encabezado será morado!
</h1>
</div>

Las hojas de estilo cargadas mediante etiquetas link son evaluadas en orden, antes que cualquier otro estilo en un archivo de Astro. Por lo tanto, esos estilos tendrán menor importancia que las hojas de estilo importadas y los estilos locales:

src/pages/index.astro
---
import "../components/hazlo-morado.css"
---
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width" />
<meta name="generator" content={Astro.generator} />
<title>Astro</title>
<link rel="stylesheet" href="/styles/hazlo-azul.css" />
</head>
<body>
<div>
<h1>Esto será morado</h1>
</div>
</body>
</html>

¡Astro viene con soporte para agregar bibliotecas, herramientas y frameworks de CSS populares a tu proyecto como Tailwind y más!

Para usar Tailwind en tu proyecto, instala la integración oficial de Astro Tailwind utilizando el comando astro add para tu gestor de paquetes:

Ventana de terminal
npx astro add tailwind
Consulta la guía de integraciones para obtener instrucciones sobre cómo instalar, importar y configurar estas integraciones de Astro.

Astro es compatible con preprocesadores de CSS como Sass, Stylus y Less usando Vite.

Ventana de terminal
npm install sass

Usa <style lang="scss"> o <style lang="sass"> en los archivos .astro.

Ventana de terminal
npm install stylus

Usa <style lang="styl"> o <style lang="stylus"> en los archivos .astro.

Ventana de terminal
npm install less

Usa <style lang="less"> en los archivos .astro.

Ventana de terminal
npm install lightningcss

Actualiza tu configuración de vite en astro.config.mjs:

astro.config.mjs
import { defineConfig } from 'astro/config'
export default defineConfig({
vite: {
css: {
transformer: "lightningcss",
},
},
})

¡También puedes usar todos los preprocesadoress de CSS anteriores dentro de los frameworks de JS! Asegúrate de seguir los patrones que recomienda cada framework:

  • React / Preact: import Styles from './styles.module.scss';
  • Vue: <style lang="scss">
  • Svelte: <style lang="scss">

Astro viene con PostCSS incluido como parte de Vite. Para configurar PostCSS para tu proyecto, crea un archivo postcss.config.cjs en la raíz del proyecto. Puedes importar complementos usando require() después de instalarlos (por ejemplo, npm install autoprefixer).

postcss.config.cjs
module.exports = {
plugins: [
require('autoprefixer'),
require('cssnano'),
],
};

Los archivos .jsx son compatibles con los módulos CSS y CSS globales. Para habilitar el primero, usa la extensión .module.css (o .module.scss/.module.sass si usas Sass).

src/components/MyReactComponent.jsx
import './global.css'; // incluye CSS global
import Styles from './styles.module.css'; // Utiliza módulos CSS (¡debe terminar en `.module.css`, `.module.scss` o `.module.sass`!)

Vue en Astro es compatible con los mismos métodos que vue-loader:

Svelte en Astro también funciona exactamente como se espera: Svelte Styling Docs.

Cualquier método de estilo en Astro está disponible para un componente de diseño de Markdown, pero métodos diferentes tendrán efectos de estilo diferentes en tu página.

Puedes aplicar estilos globales a tu contenido de Markdown agregando hojas de estilo importadas a la plantilla que envuelve el contenido de tu página. También es posible estilizar tu Markdown con etiquetas <style is:global> en el componente de diseño. Ten en cuenta que cualquier estilo agregado está sujeto al orden de cascada de Astro, por lo que debes revisar cuidadosamente tu página renderizada para asegurarte de que los estilos se apliquen como se pretende.

También puedes agregar integraciones de CSS, incluyendo Tailwind. Si usas Tailwind, el plugin de tipografía puede ser útil para estilar Markdown.

Cuando Astro genera tu sitio para desplegarlo en producción, minifica y combina tu CSS en fragmentos. Cada página de tu sitio es un fragmento separado, y además, el CSS que se comparte entre varias páginas se separa en fragmentos adicionales para su reutilización.

Sin embargo, cuando varias páginas comparten estilos, algunos fragmentos compartidos pueden volverse muy pequeños. Si se enviaran todos por separado, se generarían muchas solicitudes de hojas de estilo y afectarían el rendimiento del sitio. Por lo tanto, de forma predeterminada, Astro solo vinculará aquellos en tu HTML que tengan un tamaño superior a 4 KB como etiquetas <link rel="stylesheet">, mientras que incluirá en línea los más pequeños en etiquetas <style type="text/css">. Este enfoque proporciona un equilibrio entre el número de solicitudes adicionales y el volumen de CSS que se puede almacenar en caché entre las páginas.

Puedes configurar el tamaño en el que las hojas de estilo se vincularán externamente (en bytes) utilizando la opción de compilación assetsInlineLimit en Vite. Ten en cuenta que esta opción también afecta la inclusión en línea de scripts e imágenes.

astro.config.mjs
import { defineConfig } from 'astro/config';
export default defineConfig({
vite: {
build: {
assetsInlineLimit: 1024,
}
};
});

Si prefieres que todos los estilos del proyecto sigan siendo externos, puedes configurar la opción de compilación inlineStylesheets.

astro.config.mjs
import { defineConfig } from 'astro/config';
export default defineConfig({
build: {
inlineStylesheets: 'never'
}
});

También puedes establecer esta opción en 'always', lo cual incrustará todas las hojas de estilo.

Para casos avanzados, el CSS se puede leer directamente desde el disco sin que Astro lo empaquete ni lo optimice. Esto puede ser útil cuando necesitas un control completo sobre algún fragmento de CSS y necesitas omitir el procesamiento automático de CSS de Astro.

Esto no es recomendable para la mayoría de los usuarios.

src/components/RawInlineStyles.astro
---
// ¡Ejemplo avanzado! No recomendado para la mayoría de los usuarios.
import rawStylesCSS from '../styles/main.css?raw';
---
<style is:inline set:html={rawStylesCSS}></style>

Consulta la documentación de Vite para obtener más detalles.

Para casos de uso avanzado, puedes importar una URL de referencia directa a un archivo CSS dentro de la carpeta src/ de tu proyecto. Esto puede ser útil cuando necesitas un control completo sobre cómo se carga del CSS en la página. Sin embargo, esto evitará la optimización del CSS con el resto de la página.

Esto no es recomendable para la mayoría de los usuarios. En su lugar, coloque los archivos CSS dentro de public/ para obtener una ruta URL.

src/components/RawStylesUrl.astro
---
// ¡Ejemplo avanzado! No recomendado para la mayoría de los usuarios.
import stylesUrl from '../styles/main.css?url';
---
<link rel="preload" href={stylesUrl} as="style">
<link rel="stylesheet" href={stylesUrl}>

Consulta la documentación de Vite para obtener más detalles.