Documentation Index
Fetch the complete documentation index at: https://mintlify.com/withastro/astro/llms.txt
Use this file to discover all available pages before exploring further.
Overview
Astro provides multiple approaches to styling your components and pages. Choose the method that best fits your project needs and team preferences.
Scoped Styles
Astro components support scoped CSS out of the box. Styles defined in a <style> tag are automatically scoped to that component.
Basic Scoped Styles
src/components/Button.astro
<button class="primary">Click me</button>
<style>
.primary {
background: #2337ff;
color: white;
padding: 0.75rem 1.5rem;
border: none;
border-radius: 0.375rem;
font-weight: 600;
cursor: pointer;
}
.primary:hover {
background: #000d8a;
}
</style>
The .primary class is scoped to this component and won’t affect other components with the same class name.
How Scoping Works
Astro adds unique data attributes to your elements and styles:
<!-- Output -->
<button class="primary" data-astro-cid-abc123>Click me</button>
<style>
.primary[data-astro-cid-abc123] {
background: #2337ff;
/* ... */
}
</style>
Global Styles
Use global styles for site-wide CSS like resets, typography, and design tokens.
Creating Global Styles
Create a global CSS file
:root {
--accent: #2337ff;
--accent-dark: #000d8a;
--black: 15, 18, 25;
--gray: 96, 115, 159;
}
body {
font-family: system-ui, sans-serif;
margin: 0;
padding: 0;
color: rgb(var(--black));
line-height: 1.7;
}
h1, h2, h3, h4, h5, h6 {
margin: 0 0 0.5rem 0;
line-height: 1.2;
}
Import in a layout or component
src/components/BaseHead.astro
---
import '../styles/global.css';
---
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
Global Modifier
Use :global() to create unscoped styles within a scoped style block:
src/layouts/BlogPost.astro
<article class="prose">
<slot />
</article>
<style>
.prose {
max-width: 720px;
margin: 0 auto;
}
/* Style all links within .prose globally */
.prose :global(a) {
color: var(--accent);
text-decoration: none;
}
.prose :global(a:hover) {
text-decoration: underline;
}
</style>
CSS Variables
Define CSS custom properties for consistent theming:
---
const { theme = 'light' } = Astro.props;
---
<div class={`theme-${theme}`}>
<slot />
</div>
<style>
.theme-light {
--bg-color: #ffffff;
--text-color: #1a1a1a;
--accent: #2337ff;
}
.theme-dark {
--bg-color: #1a1a1a;
--text-color: #ffffff;
--accent: #4d7fff;
}
.theme-light,
.theme-dark {
background: var(--bg-color);
color: var(--text-color);
}
</style>
CSS Preprocessors
Astro supports CSS preprocessors like Sass and Less out of the box.
Install Sass:Use in your components:src/components/Card.astro
<div class="card">
<slot />
</div>
<style lang="scss">
$border-radius: 0.5rem;
$shadow-color: rgba(0, 0, 0, 0.1);
.card {
border-radius: $border-radius;
box-shadow: 0 2px 8px $shadow-color;
padding: 1.5rem;
&:hover {
box-shadow: 0 4px 16px $shadow-color;
}
}
</style>
---
import '../styles/components.scss';
---
src/styles/components.scss
@mixin button-variant($bg, $color) {
background: $bg;
color: $color;
padding: 0.75rem 1.5rem;
border-radius: 0.375rem;
}
.btn-primary {
@include button-variant(#2337ff, white);
}
.btn-secondary {
@include button-variant(#6c757d, white);
}
Tailwind CSS
Tailwind CSS is a popular utility-first CSS framework that works seamlessly with Astro.
Installation
npm install @tailwindcss/vite
Configuration
import { defineConfig } from 'astro/config';
import tailwindcss from '@tailwindcss/vite';
export default defineConfig({
vite: {
plugins: [tailwindcss()],
},
});
Usage
src/components/Hero.astro
<section class="bg-gradient-to-r from-blue-500 to-purple-600 text-white py-20">
<div class="container mx-auto px-4">
<h1 class="text-5xl font-bold mb-4">Welcome to My Site</h1>
<p class="text-xl mb-8">Build faster with Astro and Tailwind CSS</p>
<button class="bg-white text-blue-600 px-6 py-3 rounded-lg font-semibold hover:bg-gray-100 transition">
Get Started
</button>
</div>
</section>
CSS Modules
CSS Modules provide scoped styles with explicit imports.
src/components/Card.module.css
.card {
background: white;
border-radius: 0.5rem;
padding: 1.5rem;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.title {
font-size: 1.5rem;
font-weight: bold;
margin-bottom: 0.5rem;
}
src/components/Card.astro
---
import styles from './Card.module.css';
---
<div class={styles.card}>
<h2 class={styles.title}>
<slot name="title" />
</h2>
<div>
<slot />
</div>
</div>
Styled Components (CSS-in-JS)
Use CSS-in-JS libraries with framework components.
Styled Components with React
npm install styled-components
npm install @astrojs/react
src/components/StyledButton.tsx
import styled from 'styled-components';
const Button = styled.button`
background: #2337ff;
color: white;
padding: 0.75rem 1.5rem;
border: none;
border-radius: 0.375rem;
font-weight: 600;
cursor: pointer;
&:hover {
background: #000d8a;
}
`;
export default function StyledButton({ children }) {
return <Button>{children}</Button>;
}
---
import StyledButton from '../components/StyledButton';
---
<StyledButton client:load>
Click me
</StyledButton>
PostCSS
Astro includes PostCSS support for autoprefixing and other transformations.
module.exports = {
plugins: [
require('autoprefixer'),
require('postcss-nested'),
],
};
Styling Strategies
Component-First
Use scoped styles for component-specific styling. Best for isolated, reusable components.
Utility-First
Use Tailwind CSS for rapid development with utility classes. Best for prototyping and consistent design systems.
Semantic CSS
Use global CSS or preprocessors for traditional semantic class names. Best for content-heavy sites.
Hybrid Approach
Combine multiple methods: global styles for resets, scoped styles for components, and utilities for layout.
Advanced Patterns
Conditional Styles
src/components/Alert.astro
---
const { variant = 'info' } = Astro.props;
---
<div class={`alert alert-${variant}`}>
<slot />
</div>
<style>
.alert {
padding: 1rem;
border-radius: 0.375rem;
border: 1px solid;
}
.alert-info {
background: #e3f2fd;
border-color: #2196f3;
color: #0d47a1;
}
.alert-success {
background: #e8f5e9;
border-color: #4caf50;
color: #1b5e20;
}
.alert-error {
background: #ffebee;
border-color: #f44336;
color: #b71c1c;
}
</style>
src/components/Grid.astro
<div class="grid">
<slot />
</div>
<style>
.grid {
display: grid;
gap: 1rem;
grid-template-columns: 1fr;
}
@media (min-width: 640px) {
.grid {
grid-template-columns: repeat(2, 1fr);
}
}
@media (min-width: 1024px) {
.grid {
grid-template-columns: repeat(3, 1fr);
}
}
</style>
Font Loading
src/components/BaseHead.astro
<head>
<!-- Preload fonts for better performance -->
<link
rel="preload"
href="/fonts/inter-var.woff2"
as="font"
type="font/woff2"
crossorigin
/>
</head>
<style is:global>
@font-face {
font-family: 'Inter';
src: url('/fonts/inter-var.woff2') format('woff2');
font-weight: 100 900;
font-display: swap;
}
body {
font-family: 'Inter', system-ui, sans-serif;
}
</style>
Best Practices
Prefer Scoped Styles
Use scoped styles by default for component isolation and avoiding naming conflicts.
Use CSS Variables for Theming
Define design tokens as CSS custom properties for consistent, maintainable themes.
Minimize Global Styles
Keep global CSS limited to resets, typography, and truly global styles.
Optimize for Performance
Preload critical fonts, use font-display: swap, and minimize unused CSS.