Pular para o conteúdo

Estilos e CSS

Astro foi desenvolvido pensando em tornar a estilização e a escrita de CSS fácil. Escreva seu próprio CSS diretamente em componentes Astro ou importe sua biblioteca CSS favorita como Tailwind. Além disso, linguagens avançadas de estilização com Sass e Less também são suportadas.

Estilizar um componente Astro é tão fácil quanto adicionar uma tag <style> no seu componente ou template de página. E quando você coloca uma tag <style> dentro de um componente Astro, Astro vai detectar o CSS e manipular os estilos para você automaticamente.

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

As regras de CSS em <style> no Astro são automaticamente adicionadas a um escopo por padrão. Estilos com escopo são compilados nos bastidores para serem somente aplicados no HTML escrito dentro do mesmo componente onde a regra CSS foi definida. O CSS que você escreve dentro de um componente é automaticamente encapsulado dentro desse componente.

Este CSS:

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

Compila para isto:

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

Estilos com escopo não conflitam e não irão impactar o restante do seu site. Em Astro, não é um problema utilizar seletores de baixa especificidade como h1{} ou p{} pois eles serão compilados com escopos no resultado final.

Estilos com escopo também não serão aplicados em outros componentes astro contidos dentro de seu template. Se você precisa estilizar um componente filho, considere envolver esse componente em uma <div> ( ou em outro elemento ) para que você possa então estilizá-lo.

A especificidade de estilos com escopo é preservada, os permitindo funcionar de forma consistente com outros arquivos ou bibliotecas CSS enquanto ainda se preserva os limites exclusivos que previnem que estilos sejam aplicados fora do componente.

Ao mesmo tempo que nós recomendamos estilos com escopo para a maioria dos componentes, você pode eventualmente ter uma razão válida para escrever CSS global. Você pode optar por remover CSS com escopo automático adicionando o atributo is:global na tag <style>.

src/components/EstilosGlobais.astro
<style is:global>
/* Sem escopo, entregue como está para o navegador.
Aplica para todas as tags <h1> do seu site. */
h1 { color: red; }
</style>

Você pode também mesclar regras CSS globais e com escopo juntas na mesma tag <style> usando o seletor :global(). Isto se tornar um padrão poderoso para aplicação de estilos CSS em filhos de seu componente.

src/components/EstilosMisturados.astro
<style>
/* Em escopo somente para este componente. */
h1 { color: red; }
/* Mesclado: Aplica somente para elementos filhos (`h1`). */
article :global(h1) {
color: blue;
}
</style>
<h1>Título</h1>
<article><slot /></article>

Isto é uma ótima forma de estilizar coisas como postagens em blogs ou documentos alimentados por conteúdos de um CMS, onde o conteúdo fica fora do Astro. Contudo, seja cuidadoso: os componentes cuja aparência muda de acordo com a condição de que ele tem um certo parente, torna mais difícil solucionar problemas futuros que o envolvam.

Estilos com escopo são recomendados para serem usados sempre que possível. E estilos globais, quando necessários.

Se você precisa combinar classes em um elemento dinamicamente, você pode utilizar o atributo utilitário class:list em arquivos .astro.

src/components/ClassList.astro
---
const { isVermelho } = Astro.props;
---
<!-- Se `isVermelho` for verdadeiro, a classe será "caixa vermelha". -->
<!-- Se `isVermelho` for falso, a classe será "caixa". -->
<div class:list={['caixa', { vermelha: isVermelho }]}><slot /></div>
<style>
.caixa { border: 1px solid blue; }
.vermelha { border-color: red; }
</style>

📚 Veja nossa página de referência de diretivas para aprender mais sobre class:list.

Adicionado em: astro@0.21.0

Em Astro, <style> pode referenciar quaisquer variáveis disponíveis na página. Ademais, você pode também passar variáveis CSS diretamente do frontmatter do seu componente usando a diretiva define:vars.

src/components/DefineVars.astro
---
const corPrimeiroPlano = "rgb(221 243 228)";
const corPlanoFundo = "rgb(24 121 78)";
---
<style define:vars={{ corPrimeiroPlano, corPlanoFundo }}>
h1 {
background-color: var(--corPlanoFundo);
color: var(--corPrimeiroPlano);
}
</style>
<h1>Olá</h1>

📚 Veja nossa página de referência de diretivas para saber mais sobre define:vars.

Passando class para um componente filho

Seção intitulada Passando class para um componente filho

No Astro, atributos HTML como class não são passados automaticamente para componente filhos.

Ao invés disso, aceite uma prop class no componente filho e aplique-a no elemento raiz. Ao fazer desestruturação, você precisa renomeá-la, pois class é uma palavra reservada no JavaScript.

Ao usar a estratégia de estilo com escopo padrão, você também deve passar o atributo data-astro-cid-*. Você pode fazer isso passando o ...rest das props para o componente. Se você alterou a propriedade scopedStyleStrategy para 'class' ou 'where', a prop ...rest não é necessária.

src/components/MeuComponente.astro
---
const { class: nomeClasse, ...resto } = Astro.props;
---
<div class={nomeClasse} {...resto}>
<slot/>
</div>
src/pages/index.astro
---
import MeuComponente from "../components/MeuComponente.astro"
---
<style>
.vermelho {
color: red;
}
</style>
<MeuComponente class="vermelho">Isso será vermelho!</MeuComponente>

Você pode estilizar elementos HTML em linha usando o atributo style. Isso pode ser uma string CSS ou um objeto de propriedades CSS:

src/pages/index.astro
// Estes são equivalentes:
<p style={{ color: "brown", textDecoration: "underline" }}>Meu texto</p>
<p style="color: brown; text-decoration: underline;">Meu texto</p>

Há duas formas para incluir folhas de estilos globais e externas: uma importação ESM para arquivos dentro de seu projeto, e com um link URL absoluto para arquivos em seu diretório public/ ou disponíveis fora de seu projeto.

📚 Leia mais sobre como utilizar assets estáticos localizados no diretório public/ ou src/.

Você pode importar folhas de estilos no frontmatter do seu componente Astro usando a sintaxe de importação ESM. Importação de CSS funcionam como qualquer outra importação ESM em um componente Astro, que deve ser referenciada relativo para o componente e obrigatoriamente deve ser escrito no início do script do seu componente junto com outras importações.

src/pages/index.astro
---
// Astro irá fazer bundle e otimizar este CSS para você automaticamente
// Isto também funciona para arquivos pré-processados como .scss, .styl, etc.
import '../estilos/utils.css';
---
<html><!-- Sua página aqui --></html>

import de CSS por meio de ESM é suportado dentro de qualquer arquivo JavaScript, incluindo componentes JSX como React e Preact. Isto pode ser útil para escrever estilos por componente de forma granular para seus componentes React.

Importe uma Folha de Estilos de um Pacote do NPM

Seção intitulada Importe uma Folha de Estilos de um Pacote do NPM

Você talvez precise incluir uma folha de estilos de um pacote externo. Isso é especialmente comum para utilitários como Open Props. Se seu pacote recomenda usar uma extensão de arquivo (ex.: nome-do-pacote/estilos.css ao invés de nome-do-pacote/estilos), isso deve funcionar como qualquer importação de uma folha de estilos local.

---
// src/pages/página-qualquer.astro
import 'nome-do-pacote/estilos.css';
---
<html><!-- Sua página aqui --></html>

Se seu pacote não recomenda usar uma extensão de arquivo (ex.: nome-do-pacote/estilos), antes, você vai precisar atualizar sua configuração Astro!

Digamos que você está importando um arquivo CSS de um nome-do-pacote chamado normalize (com a extensão omitida). Para garantir que nós podemos pré-renderizar sua página corretamente, adicione nome-do-pacote para o array vite.ssr.noExternal:

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

Agora, você está livre para importar nome-do-pacote/normalize. Isto passará por bundle e será otimizado pelo Astro como qualquer outra folha de estilos local.

---
// src/pages/página-qualquer.astro
import 'nome-do-pacote/normalize';
---
<html><!-- Sua página aqui --></html>
Seção intitulada Inclua uma Folha de Estilos Estática via tags link

Você pode também usar o elemento <link> para incluir uma folha de estilos na página. Isto deve ser um caminho de URL absoluto para um arquivo CSS localizado no seu diretório /public, ou uma URL para um website externo. Note que valores relativos de href para o elemento <link> não são suportados.

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

Como esta abordagem usa o diretório public/, ela pula o processamento normal do CSS, o processo de bundle e outras otimizações feitas por Astro. Sendo assim, se você precisa desses recursos, use o método de importe uma folha de estilos ensinado acima.

Componentes Astro as vezes terão que analisar múltiplas fontes de CSS. Por exemplo, seu componente pode importar uma folha de estilos CSS, incluir sua própria tag <style> tag e ser renderizada dentro de um layout que importa CSS.

Quando regras conflitantes de CSS são aplicadas ao mesmo elemento, navegadores primeiro utilizam especificidade e depois ordem de aparecimento para determinar qual valor mostrar.

Se uma regra é mais específica que outra, não importa onde a regra de CSS aparece, seu valor terá precedência:

MeuComponente.astro
<style>
h1 { color: red }
div > h1 {
color: purple
}
</style>
<div>
<h1>
Esse título será roxo!
</h1>
</div>

Se duas regras tem a mesma especificidade, então a ordem de aparecimento é avaliada e o valor da última regra terá precedência:

MeuComponente.astro
<style>
h1 { color: purple }
h1 { color: red }
</style>
<div>
<h1>
Esse título será vermelho!
</h1>
</div>

As regras de CSS do Astro são avaliadas nessa ordem de aparecimento:

  • tags <link> na head (menor precedência)
  • estilos importados
  • estilos com escopo (maior precedência)

Utilizar estilos com escopo não aumenta a especificidade do seu CSS, porém eles sempre irão vir por último na ordem de aparecimento. Logo eles tomarão precedência sobre outros estilos de mesma especificidade. Por exemplo, se você importar uma folha de estilos que conflita com um estilo com escopo, o valor do estilo com escopo será aplicado:

o-faça-roxo.css
h1 {
color: purple;
}
MeuComponente.astro
---
import "./o-faça-roxo.css"
---
<style>
h1 { color: red }
</style>
<div>
<h1>
Esse título será vermelho!
</h1>
</div>

Se você fazer o estilo importado mais específico, ele terá uma maior precedência sobre o estilo com escopo:

o-faça-roxo.css
div > h1 {
color: purple;
}
MeuComponente.astro
---
import "./o-faça-roxo.css"
---
<style>
h1 { color: red }
</style>
<div>
<h1>
Esse título será roxo!
</h1>
</div>

Ao importar múltiplas folhas de estilo em um componente Astro, as regras de CSS são analisadas na ordem em que são importadas. Uma maior especificidade sempre irá determinar quais estilos serão mostrados, não importa onde o CSS é analisado. Porém, quando estilos conflitantes tem a mesma especificidade, o último a ser importado ganha:

o-faça-roxo.css
div > h1 {
color: purple;
}
o-faça-verde.css
div > h1 {
color: green;
}
MeuComponente.astro
---
import "./o-faça-verde.css"
import "./o-faça-roxo.css"
---
<style>
h1 { color: red }
</style>
<div>
<h1>
Esse título será roxo!
</h1>
</div>

Enquanto tags <style> possuem escopo e apenas é aplicada ao componente que a declara, CSS importado pode “vazar”. Importar um componente aplica qualquer CSS que ele importa, mesmo que o componente nunca seja utilizado:

ComponenteRoxo.astro
---
import "./o-faça-roxo.css"
---
<div>
<h1>Eu importo CSS roxo.</h1>
</div>
MeuComponente.astro
---
import "./o-faça-verde.css"
import ComponenteRoxo from "./ComponenteRoxo.astro";
---
<style>
h1 { color: red }
</style>
<div>
<h1>
Esse título será roxo!
</h1>
</div>

Folhas de estilo carregadas via tags link são analisadas em ordem, antes de quaisquer outros estilos em um arquivo Astro. Portanto, esses estilos terão menor precedência que folhas de estilo importadas e estilos com escopo:

index.astro
---
import "../components/o-faça-roxo.css"
---
<html lang="pt-BR">
<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/o-faça-azul.css" />
</head>
<body>
<div>
<h1>Isso será roxo</h1>
</div>
</body>
</html>

Astro vem com suporte para adicionar bibliotecas, ferramentas e frameworks CSS populares para seu projeto como Tailwind e mais!

Para usar o Tailwind no seu projeto, instale a integração para Tailwind oficial do Astro usando o comando astro add no seu gerenciador de pacotes:

Terminal window
npx astro add tailwind

📚 Veja o Guia de Integrações para instruções sobre instalação, importação, e configuração destas integrações.

Astro suporta pré-processadores tais como Sass, Stylus, e Less através de Vite.

Terminal window
npm install sass

Use <style lang="scss"> ou <style lang="sass"> em arquivos .astro.

Terminal window
npm install stylus

Use <style lang="styl"> ou <style lang="stylus"> em arquivos .astro.

Terminal window
npm install less

Use <style lang="less"> em arquivos .astro.

Você pode também usar todos os pré-processadores CSS listados acima dentro de frameworks JS também! Tenha certeza de seguir os padrões que cada framework recomenda:

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

Astro vem com PostCSS incluído como parte de Vite. E para configurar PostCSS para seu projeto, crie um arquivo postcss.config.cjs na raiz de seu projeto. Você pode importar plugins usando require() após os instalar (por exemplo npm install autoprefixer).

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

Arquivos .jsx suporta tanto CSS global quanto Módulos CSS. E para habilitar o segundo, use a extensão .module.css (ou .module.scss / .module.sass se você estiver usando Sass).

src/components/MeuComponenteReact.jsx
import './global.css'; // inclui CSS global
import Estilos from './estilos.module.css'; // Utiliza Módulos CSS (deve obrigatoriamente terminar em `.module.css`, `.module.scss`, ou `.module.sass`!)

Em Astro, Vue suporta os mesmos métodos que vue-loader suporta:

Em Astro, Svelte também funciona como esperado: Documentação de estilização no Svelte.

Quaisquer métodos de estilização no Astro estão disponíveis em um componente de layout Markdown, porém diferentes métodos terão diferentes efeitos na estilização da sua página.

Também é possível estilizar seu Markdown com as tags <style is:global> no componente de layout. Note que quaisquer estilos adicionados estão sujeitos à ordem de cascata do Astro, e você deve verificar sua página renderizada cuidadosamente para garantir que seus estilos estejam sendo aplicados conforme o desejado.

Você também pode adicionar integrações de CSS, incluindo o Tailwind. Se você estiver usando o Tailwind, o plugin de tipografia pode ser útil para estilizar o Markdown.

Quando o Astro faz a build do seu site para lançamento em produção, ele minifica e combina seu CSS em pedaços. Cada página no seu site ganha seu próprio pedaço, e adicionalmente, o CSS que é compartilhado entre múltiplas páginas é dividido em seus próprios pedaços para reutilização.

Contudo, quando você tem diversas páginas compartilhando estilos, alguns pedaços compartilhados podem se tornar realmente pequenos. Se todos eles fossem enviados separadamente, isso levaria a muitas requisições de folhas de estilo e afetaria a performance do site. Portanto, por padrão o Astro irá fazer link apenas daquelas no seu HTML acima de 4kB em tamanho como tags <link rel="stylesheet">, enquanto adiciona inline as menores como <style type="text/css">. Essa abordagem fornece um equilíbrio entre o número de requisições adicionais e o volume de CSS que pode ser cacheado entre páginas.

Você pode configurar o tamanho no qual folhas de estilo serão adicionadas com links externos (em bytes) utilizando a opção da build do vite assetsInlineLimit. Note que essa pção afeta a adição inline de scripts e imagens também.

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

Se você preferir que todos os estilos do projeto continuem externos, você pode configurar a opção da build inlineStylesheets.

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

Você também pode definir essa opção como 'always' que vai colocar em linha todas as folhas de estilo.

Para casos de uso avançado, CSS pode ser lido diretamente do disco sem passar por bundle ou ser otimizado por Astro. Isto pode ser útil quando você precisa de um controle completo sobre um pedaço de código CSS, e necessita contornar a manipulação de CSS automática do Astro.

Isto não é recomendável para a maioria dos usuários.

src/components/EstilosBrutosInline.astro
---
// Exemplo avançado! Não recomendável para a maioria dos usuários.
import estilosCSSBruto from '../estilos/principal.css?raw';
---
<style is:inline set:html={estilosCSSBruto}></style>

Veja a documentação do Vite para detalhes completos.

Para casos de uso avançado, você pode importar uma referência URL direta para um arquivo CSS dentro de seu projeto no diretório src/. Isto pode ser útil quando você necessita de controle completo sobre como um arquivo é incluído na página. Entretanto, isto vai prevenir a otimização desse arquivo CSS com o resto do CSS da sua página.

Isto não é recomendável para a maioria dos usuários. Em vez disso, coloque os arquivos CSS dentro de public/ para conseguir uma referência URL consistente.

src/components/UrlEstilosBrutos.astro
---
// Exemplo avançado! Não recomendável para a maioria dos usuários.
import urlEstilos from '../estilos/principal.css?url';
---
<link rel="preload" href={urlEstilos} as="style">
<link rel="stylesheet" href={urlEstilos}>

Veja a documentação do Vite para detalhes completos.