Strings, Expressions, and `class:list`
Attributes
Attribute syntax in Astro matches HTML, with `{ }` for dynamic values and a handy `class:list` directive for conditional classes.
What you'll learn
- Pass dynamic attributes
- Build conditional class lists
- Spread arbitrary attributes
Attributes look like HTML. Use { } for dynamic values.
String vs Expression
<a href="/about">About</a> {/* string literal */}
<a href={url}>About</a> {/* expression */}
<a href={`/users/${id}`}>View</a> {/* template literal */} Boolean Attributes
A JS boolean adds or omits the attribute:
<input disabled={loading} />
<!-- when loading is true: <input disabled> -->
<!-- when loading is false: <input> --> class:list — Conditional Classes
Astro’s nicest little ergonomic. Pass an array, an object, or a mix — it joins everything truthy.
<button
class:list={[
"btn",
"btn--lg",
{ "btn--primary": kind === "primary" },
isActive && "is-active",
]}
>
OK
</button> Output: class="btn btn--lg btn--primary is-active" (or similar
depending on values).
Standard class={...} works too, but class:list is built for the
“conditional pile of classes” use case.
Spreading Attributes
Spread an object of attributes with {...obj}:
---
const linkProps = { href: "/about", target: "_blank", rel: "noopener" };
---
<a {...linkProps}>About</a> Useful for wrapper components that forward unknown attributes.
Multiple Attribute Directives
Astro has a few special kind:value directives that change
behavior:
| Directive | What it does |
|---|---|
class:list={...} | Smart class joining |
set:html={...} | Render raw HTML (dangerous — escape it!) |
set:text={...} | Render text without parsing as HTML |
is:global | On <style>, opt out of scoping |
is:inline | On <script>, keep the script untouched |
client:load | (Islands) hydrate on page load |
You’ll meet the rest as we go.
Up Next
Children — how a component’s caller passes content in.
Slots →