Day6 - Astro Series: Style

A pretty gradient background with a heading: "Style"

Introduction

Previously we covered the basic knowledge you need to write Astro components. In this chapter we’ll go further and explain how to add styles to components.

Styling in Astro

Writing styles in Astro is very easy, and there are many options to choose from. You can use preprocessors like Sass or Less, integrate Tailwind via plugins, or write scoped CSS.

Scoped styles

You can add a <style> tag inside the client template portion of a component or page template to add styles. By default these styles are automatically scoped to the component. For example, the following component styles:

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

will automatically render like this so the styles only apply within the component:

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

This scoping keeps boundaries between components, allowing you to freely write styles inside a component without worrying about style collisions.

Global styles

You can still write global CSS inside a component, but it is not recommended because scattered components containing global styles can make debugging difficult. There are three ways to write global styles:

<style is:global>
/* Apply directly to all <h1> tags on the site */
h1 { color: red; }
</style>

Or use :global() to achieve the same:

<style>
:global(h1) {
color: red;
}
</style>

You can also create separate CSS files inside the src folder and import them as needed:

import '../styles/global.css';
import 'package-name/styles.css';

Combining classes with class:list

If you need to combine classes dynamically you can use the [class:list](https://docs.astro.build/zh-cn/reference/directives-reference/#classlist) directive attribute:

---
const { isRed } = Astro.props;
---
<!-- If `isRed` is truthy, class will be "box red" -->
<!-- If `isRed` is falsy, class will be "box" -->
<div class:list={['box', { red: isRed }]}><slot /></div>

Using define:vars for CSS variables

In addition to reading CSS variables that exist on the page, the <style> tag can also create component CSS variables using the define:vars directive attribute.

---
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>Hello</h1>

Specifically, Astro will automatically add inline CSS variables to the outermost element of the component, allowing the entire element to use those variables.

Passing the class attribute

When passing a class attribute via props, note that class is a reserved word🔗 in JavaScript, so you should rename the variable appropriately.

---
const { class: className } = Astro.props;
---
<div class={className}>
<slot/>
</div>

Other CSS options

That covers the basic ways to use styles in Astro! Other options like CSS preprocessors🔗 or integrations such as Tailwind🔗 are documented as well. I’ll cover integrating Tailwind into an Astro project in more detail in later chapters.

Summary

Overall, Astro lets you write CSS the way you prefer—whether via import, <link>, scoped CSS, preprocessors, or frameworks. The precedence when combining imports is:

  • <link> tags in the <head> (lowest precedence)
  • imported styles
  • Scoped styles (highest precedence)

Further reading