Markdown source
Astro Styling Markdown source
Readable source view for humans. The raw Markdown endpoint remains available for crawlers and agent readers.
---
title: "Astro Styling"
description: "Scoped CSS, global styles, design tokens, and how Catppuccin theming works."
kind: guide
maturity: evergreen
confidence: high
origin: ai-drafted
author: "Agent"
directedBy: "krow"
tags: [astro, fundamentals]
published: 2026-03-15
modified: 2026-06-13
wordCount: 745
readingTime: 4
series: "learn-astro"
series_order: 7
prerequisites: [astro-components]
url: https://krowdev.com/guide/astro-styling/
---
## Agent Context
- Canonical: https://krowdev.com/guide/astro-styling/
- Markdown: https://krowdev.com/guide/astro-styling.md
- Full corpus: https://krowdev.com/llms-full.txt
- Kind: guide
- Maturity: evergreen
- Confidence: high
- Origin: ai-drafted
- Author: Agent
- Directed by: krow
- Published: 2026-03-15
- Modified: 2026-06-13
- Words: 745 (4 min read)
- Tags: astro, fundamentals
- Series: learn-astro (#7)
- Prerequisites: astro-components
- Content map:
- h2: Three Levels of CSS in Astro
- h2: Scoped Styles (Default)
- h2: Global Styles
- h2: CSS Custom Properties (Design Tokens)
- h2: How the Theme Toggle Works
- h2: Semantic Token Pattern
- h2: Fonts
- h2: Sources
- Crawl policy: same canonical content is exposed through HTML, Markdown, and llms-full; no crawler-specific content gate.
## Three Levels of CSS in Astro
This assumes you understand [components](/guide/astro-components/). For the design-token philosophy see the [mental model](/guide/astro-mental-model/). Companion entries: [.astro files](/guide/astro-files/) and [layouts](/guide/astro-layouts/) — the surfaces where styles get scoped.
| Level | Scope | Where | When to Use |
|---|---|---|---|
| **Scoped** | One component | `<style>` in `.astro` file | Component-specific styles |
| **Global** | Entire site | Imported `.css` file | Design tokens, typography, resets |
| **Inline** | One element | `style=""` attribute | Rare, dynamic values |
## Scoped Styles (Default)
A `<style>` tag in an `.astro` file is automatically scoped:
```astro
<!-- Component A -->
<h1>Title A</h1>
<style>
h1 { color: red; } /* Only affects THIS h1 */
</style>
<!-- Component B -->
<h1>Title B</h1>
<style>
h1 { color: blue; } /* Only affects THIS h1 */
</style>
```
No conflicts. Astro adds data attributes behind the scenes to isolate selectors. You write simple CSS, Astro handles namespacing.
## Global Styles
For site-wide styles (fonts, colors, resets), import a CSS file in a layout:
```astro
---
// src/layouts/Base.astro
import '../styles/global.css'; // applies to every page
---
```
krowdev's `global.css` contains:
1. **CSS custom properties** (design tokens) — Catppuccin color values
2. **Reset** — box-sizing, margins
3. **Typography** — heading sizes, paragraph max-width, link styles
4. **Code blocks** — syntax highlighting integration
5. **Tables** — border, padding, hover states
6. **Interactive elements** — callout boxes, challenge blocks (used in this course)
## CSS Custom Properties (Design Tokens)
Custom properties are variables that CSS can reference. krowdev uses them for theming:
```css
[data-theme='dark'] {
--bg: #1e1e2e; /* Catppuccin Mocha base */
--text: #cdd6f4; /* Catppuccin Mocha text */
--accent: #cba6f7; /* Catppuccin Mocha mauve */
}
[data-theme='light'] {
--bg: #eff1f5; /* Catppuccin Latte base */
--text: #4c4f69; /* Catppuccin Latte text */
--accent: #8839ef; /* Catppuccin Latte mauve */
}
```
Then everything references these variables:
```css
body { background: var(--bg); color: var(--text); }
a { color: var(--accent); }
```
:::analogy
CSS custom properties are like constants in a Python config file:
```python
# config.py
BG_COLOR = "#1e1e2e"
TEXT_COLOR = "#cdd6f4"
ACCENT_COLOR = "#cba6f7"
# usage.py
from config import BG_COLOR
set_background(BG_COLOR)
```
Change the config, everything updates. Same idea — change `--accent` and every link, button, and highlight changes.
:::
## How the Theme Toggle Works
The toggle script (in `ThemeToggle.astro`) does one thing:
```js
// Toggle data-theme attribute on <html>
const next = current === 'dark' ? 'light' : 'dark';
document.documentElement.setAttribute('data-theme', next);
localStorage.setItem('theme', next);
```
The CSS selector `[data-theme='dark']` or `[data-theme='light']` activates the right set of variables. Everything repaints instantly — no page reload.
:::key
The theme toggle is the *only* JavaScript on the site. Everything else — fonts, colors, layout — is pure CSS. The `is:inline` script in `Base.astro`'s `<head>` sets the theme before first paint to prevent a flash of wrong colors.
:::
## Semantic Token Pattern
krowdev uses a two-layer token system:
```
Layer 1: Raw palette Layer 2: Semantic aliases
--ctp-base: #1e1e2e → --bg: var(--ctp-base)
--ctp-mauve: #cba6f7 → --accent: var(--ctp-mauve)
--ctp-blue: #89b4fa → --link: var(--ctp-blue)
```
Why two layers? If you later want `--accent` to be blue instead of mauve, you change one line. Everything using `--accent` updates. The raw palette stays stable.
## Fonts
Astro 6's Fonts API downloads fonts at build time and creates CSS variables:
```js
// astro.config.mjs
fonts: [
{
name: 'Inter',
cssVariable: '--font-body', // use this in CSS
provider: fontProviders.fontsource(),
weights: [400, 500, 600, 700],
},
]
```
Then in CSS:
```css
html { font-family: var(--font-body), system-ui, sans-serif; }
code { font-family: var(--font-mono), monospace; }
```
:::analogy
`fontsource` is like `conda install` for fonts. The files are downloaded at build time, bundled into your `dist/`, and served locally. No runtime dependency on Google's CDN. GDPR-friendly.
:::
**Challenge: Change the accent color**
1. Open `src/styles/global.css`
2. Find the line `--accent: var(--ctp-mauve);`
3. Change it to `--accent: var(--ctp-blue);`
4. Run `npm run dev` and see every accent (links, buttons, highlights, badges) turn blue
5. Change it back to mauve when you're done
This demonstrates the power of the token system — one variable controls the entire color story.
---
Previous: [Content Collections](/guide/astro-content-collections/) | Next: [Markdown & Code Blocks](/guide/astro-markdown-and-code/)
## Sources
- Astro Docs, [Styles and CSS](https://docs.astro.build/en/guides/styling/)
- MDN, [CSS custom properties](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties)
- Catppuccin, [Palette spec](https://github.com/catppuccin/catppuccin/blob/main/docs/style-guide.md)