> ## 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.

# Styling Guide

> Learn about CSS options in Astro including scoped styles, global CSS, CSS modules, Tailwind, and more

## 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

```astro title="src/components/Button.astro" theme={null}
<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:

```html theme={null}
<!-- 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

<Steps>
  <Step title="Create a global CSS file">
    ```css title="src/styles/global.css" theme={null}
    :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;
    }
    ```
  </Step>

  <Step title="Import in a layout or component">
    ```astro title="src/components/BaseHead.astro" theme={null}
    ---
    import '../styles/global.css';
    ---

    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width,initial-scale=1" />
    ```
  </Step>
</Steps>

### Global Modifier

Use `:global()` to create unscoped styles within a scoped style block:

```astro title="src/layouts/BlogPost.astro" theme={null}
<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:

```astro title="src/layouts/Layout.astro" theme={null}
---
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.

<Accordion title="Using Sass/SCSS">
  Install Sass:

  ```bash theme={null}
  npm install sass
  ```

  Use in your components:

  ```astro title="src/components/Card.astro" theme={null}
  <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>
  ```
</Accordion>

<Accordion title="Importing SCSS Files">
  ```astro theme={null}
  ---
  import '../styles/components.scss';
  ---
  ```

  ```scss title="src/styles/components.scss" theme={null}
  @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);
  }
  ```
</Accordion>

## Tailwind CSS

Tailwind CSS is a popular utility-first CSS framework that works seamlessly with Astro.

### Installation

```bash theme={null}
npm install @tailwindcss/vite
```

### Configuration

```js title="astro.config.mjs" theme={null}
import { defineConfig } from 'astro/config';
import tailwindcss from '@tailwindcss/vite';

export default defineConfig({
  vite: {
    plugins: [tailwindcss()],
  },
});
```

### Usage

```astro title="src/components/Hero.astro" theme={null}
<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.

```css title="src/components/Card.module.css" theme={null}
.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;
}
```

```astro title="src/components/Card.astro" theme={null}
---
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.

<Accordion title="Styled Components with React">
  ```bash theme={null}
  npm install styled-components
  npm install @astrojs/react
  ```

  ```tsx title="src/components/StyledButton.tsx" theme={null}
  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>;
  }
  ```

  ```astro title="src/pages/index.astro" theme={null}
  ---
  import StyledButton from '../components/StyledButton';
  ---

  <StyledButton client:load>
    Click me
  </StyledButton>
  ```
</Accordion>

## PostCSS

Astro includes PostCSS support for autoprefixing and other transformations.

```js title="postcss.config.cjs" theme={null}
module.exports = {
  plugins: [
    require('autoprefixer'),
    require('postcss-nested'),
  ],
};
```

## Styling Strategies

<CardGroup cols={2}>
  <Card title="Component-First" icon="code">
    Use scoped styles for component-specific styling. Best for isolated, reusable components.
  </Card>

  <Card title="Utility-First" icon="wrench">
    Use Tailwind CSS for rapid development with utility classes. Best for prototyping and consistent design systems.
  </Card>

  <Card title="Semantic CSS" icon="file">
    Use global CSS or preprocessors for traditional semantic class names. Best for content-heavy sites.
  </Card>

  <Card title="Hybrid Approach" icon="layers">
    Combine multiple methods: global styles for resets, scoped styles for components, and utilities for layout.
  </Card>
</CardGroup>

## Advanced Patterns

### Conditional Styles

```astro title="src/components/Alert.astro" theme={null}
---
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>
```

### Media Queries

```astro title="src/components/Grid.astro" theme={null}
<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

```astro title="src/components/BaseHead.astro" theme={null}
<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

<Steps>
  <Step title="Prefer Scoped Styles">
    Use scoped styles by default for component isolation and avoiding naming conflicts.
  </Step>

  <Step title="Use CSS Variables for Theming">
    Define design tokens as CSS custom properties for consistent, maintainable themes.
  </Step>

  <Step title="Minimize Global Styles">
    Keep global CSS limited to resets, typography, and truly global styles.
  </Step>

  <Step title="Optimize for Performance">
    Preload critical fonts, use `font-display: swap`, and minimize unused CSS.
  </Step>
</Steps>
