Attributes

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.

3 min read Level 1/5 #astro#attributes#class
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:

DirectiveWhat it does
class:list={...}Smart class joining
set:html={...}Render raw HTML (dangerous — escape it!)
set:text={...}Render text without parsing as HTML
is:globalOn <style>, opt out of scoping
is:inlineOn <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 →