---
title: "Writing blocks"
description: "Lists, groups, comments, and the YAML a block accepts."
canonical_url: "https://vue-tailwind-block.netlify.app/guide/writing-blocks"
---
# Writing blocks

> Lists, groups, comments, and the YAML a block accepts.

## Keys

Each key names a part of the component, and its value holds the classes
for that part. The template reads them from `classes`:

```vue [Button.vue]
<template>
  <button :class="classes.root">
    <slot />
  </button>
</template>

<tailwind lang="yaml">
root: inline-flex items-center gap-2 rounded-md px-4 py-2 text-sm
</tailwind>
```

<note>

`lang` can be `yaml`, `yml` or left out. Prefer `yaml`, because VS Code
highlights the block as YAML only then. A component holds one block.

</note>

## Lists

A list is joined into one class string, with each entry trimmed. Use one
when the classes no longer fit on a line:

<code-group>

```yaml [Button.vue]
root:
  - inline-flex items-center gap-2 rounded-md px-4 py-2 text-sm
  - disabled:pointer-events-none disabled:opacity-50
  - focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-sky-500
```

```ts [Compiled]
classes.root
// 'inline-flex items-center gap-2 rounded-md px-4 py-2 text-sm disabled:pointer-events-none disabled:opacity-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-sky-500'
```

</code-group>

## Comments

A `#` after a space starts a comment, on its own line or after an entry:

```yaml [Button.vue]
root:
  - inline-flex items-center gap-2 rounded-md px-4 py-2 text-sm
  # without pointer-events-none, a disabled button still shows hover styles
  - disabled:pointer-events-none disabled:opacity-50
```

A `#` written without a preceding space is treated as part of the class name.
This means arbitrary hex values like `bg-[#1da1f2]` or `text-[#333]` work
unquoted without being parsed as comments.

## Groups

A key can hold other keys instead of classes, to any depth. The template
picks an entry from each group with its props:

```vue [Button.vue]
<script setup lang="ts">
defineProps<{
  variant: 'solid' | 'outline'
  size: 'sm' | 'lg'
  disabled?: boolean
}>()
</script>

<template>
  <button
    :class="[
      classes.root,
      classes.variants[variant],
      classes.sizes[size],
      disabled && classes.states.disabled,
    ]"
  >
    <slot />
  </button>
</template>

<tailwind lang="yaml">
root: inline-flex items-center gap-2 rounded-md text-sm
variants:
  solid: bg-sky-600 text-white hover:bg-sky-500
  outline: border border-zinc-300 hover:bg-zinc-50
sizes:
  sm: h-8 px-3
  lg: h-10 px-6
states:
  disabled: pointer-events-none opacity-50
</tailwind>
```

`root`, `variants`, `sizes`, and `states` are arbitrary names you choose.
Name the groups after the visual parts or states of your component.

## Reading classes in `<script setup>`

`classes` is available in `<script setup>` just like in the template. You
can pass it to child components or use it in `computed` properties:

```vue [Button.vue]
<script setup lang="ts">
import { computed } from 'vue'

const props = defineProps<{ fullWidth?: boolean }>()

const buttonClasses = computed(() => [
  classes.root,
  props.fullWidth && classes.fullWidth,
])
</script>
```

## Quoting

Classes need no quotes, even with characters YAML treats as syntax, such
as `!`, `@`, `*`, `[` and `&`:

```yaml
root:
  - "!bg-red-500 *:rounded-md"
  - @container/card:p-4
  - [&>svg]:size-4 w-[calc(100%-1rem)]
  - bg-[color:var(--brand)]/10
```

Quoted entries work too.

<warning>

Quote an entry only if it contains a space before `#` (` #`), such as
`content-['hello # world']`. Otherwise, YAML treats the `#` as the start
of a comment.

</warning>

Stick to standard key-value mappings and bulleted lists. Advanced YAML
features like flow lists (`[a, b]`) or anchors and aliases are treated as
plain text strings.

## Errors

Every value must be a string, a list of strings or a group of keys.
Anything else fails the build with an error that names the key:

<code-group>

```yaml [Button.vue]
variants:
  solid:
  outline: border border-zinc-300 hover:bg-zinc-50
```

```text [Build error]
Expected a class string, list or group at variants.solid, got null
```

</code-group>

YAML syntax errors and a `lang` other than `yaml` or `yml` fail the build
too.


## Sitemap

See the full [sitemap](https://vue-tailwind-block.netlify.app/sitemap.md) for all pages.
