---
title: "Checkbox"
description: "A control that allows the user to toggle between checked and not checked."
canonical_url: "https://vinicunca.dev/akar/components/checkbox"
---
# Checkbox

> A control that allows the user to toggle between checked and not checked.

```vue [index.vue]
<script setup lang="ts">
import { CheckboxIndicator, CheckboxRoot } from 'akar'
import { ref } from 'vue'
import './styles.css'

const checkboxOne = ref(true)
</script>

<template>
  <div class="akar-demo akar-demo-Checkbox">
    <div :style="{ display: 'flex', alignItems: 'center' }">
        <label>
          <CheckboxRoot
            v-model="checkboxOne"
            class="CheckboxRoot"
          >
            <CheckboxIndicator class="CheckboxIndicator">
              <PIcon name="i-lucide-check" />
            </CheckboxIndicator>
          </CheckboxRoot>
          <span class="Label">Accept terms and conditions.</span>
        </label>
      </div>
  </div>
</template>
```

```css [styles.css]
@import '../_colors/black-alpha.css';
@import '../_colors/grass.css';

@scope (.akar-demo-Checkbox) {
/* reset */
button {
  all: unset;
}

.CheckboxRoot {
  background-color: white;
  width: 25px;
  height: 25px;
  border-radius: 4px;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 2px 10px var(--black-a7);
}
.CheckboxRoot:hover {
  background-color: var(--grass-3);
}
.CheckboxRoot:focus {
  box-shadow: 0 0 0 2px black;
}

.CheckboxIndicator {
  color: var(--grass-11);
}

.Label {
  color: white;
  padding-left: 15px;
  font-size: 15px;
  line-height: 1;
}
}
```

## Features

- Supports indeterminate state.
- Full keyboard navigation.
- Can be controlled or uncontrolled.
- Supports custom true/false values.

## Installation

Install the component from your command line.

```bash [pnpm]
pnpm add akar
```

```bash [yarn]
yarn add akar
```

```bash [npm]
npm install akar
```

```bash [bun]
bun add akar
```

## Anatomy

Import all parts and piece them together.

```vue
<script setup>
import { CheckboxGroupRoot, CheckboxIndicator, CheckboxRoot } from 'akar';
</script>

<template>
  <CheckboxRoot>
    <CheckboxIndicator />
  </CheckboxRoot>

  <!-- or with array support -->
  <CheckboxGroupRoot>
    <CheckboxRoot>
      <CheckboxIndicator />
    </CheckboxRoot>
  </CheckboxGroupRoot>
</template>
```

## API Reference

### Root

Contains all the parts of a checkbox. An `input` will also render when used within a `form` to ensure events propagate correctly.

**Props**

| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| `as` | `"button"` | `AsTag \| Component` | The element or component this component should render as. Can be overwritten by `asChild`. |
| `asChild` |  | `boolean` | Change the default rendered element for the one passed as a child, merging their props and behavior.<br><br>Read our [Composition](https://vinicunca.dev/akar/guides/composition) guide for more details. |
| `defaultValue` |  | `T \| "indeterminate"` | The value of the checkbox when it is initially rendered. Use when you do not need to control its value. |
| `disabled` |  | `boolean` | When `true`, prevents the user from interacting with the checkbox |
| `falseValue` | `(() => false) as unknown as undefined` | `T` | The value used when the checkbox is unchecked. Defaults to `false`. |
| `id` |  | `string` | Id of the element |
| `modelValue` |  | `null \| T \| "indeterminate"` | The controlled value of the checkbox. Can be binded with v-model. |
| `name` |  | `string` | The name of the field. Submitted with its owning form as part of a name/value pair. |
| `required` |  | `boolean` | When `true`, indicates that the user must set the value before the owning form can be submitted. |
| `trueValue` | `(() => true) as unknown as undefined` | `T` | The value used when the checkbox is checked. Defaults to `true`. |
| `value` | `"on"` | `AcceptableValue` | The value given as data when submitted with a `name`. |

**Events**

| Event | Payload | Description |
| --- | --- | --- |
| `update:modelValue` | `value: T \| "indeterminate"` | Event handler called when the value of the checkbox changes. |

**Slots**

| Slot | Payload | Description |
| --- | --- | --- |
| `modelValue` | `T \| "indeterminate"` | Current value |
| `state` | `false \| true \| "indeterminate"` | Current state |

[CheckboxRoot.vue source](https://github.com/vinicunca/akar/blob/v2.0.20/packages/core/src/Checkbox/CheckboxRoot.vue)

| Data attribute | Value |
| --- | --- |
| `[data-state]` | "checked" \\| "unchecked" \\| "indeterminate" |
| `[data-disabled]` | Present when disabled |

### Indicator

Renders when the checkbox is in a checked or indeterminate state. You can style this element directly, or you can use it as a wrapper to put an icon into, or both.

> [!NOTE]
> 
> Defer mounting with `forceMount` / [`Presence`](https://vinicunca.dev/akar/utilities/presence). See the [animation guide](https://vinicunca.dev/akar/guides/animation).

**Props**

| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| `as` | `"span"` | `AsTag \| Component` | The element or component this component should render as. Can be overwritten by `asChild`. |
| `asChild` |  | `boolean` | Change the default rendered element for the one passed as a child, merging their props and behavior.<br><br>Read our [Composition](https://vinicunca.dev/akar/guides/composition) guide for more details. |
| `forceMount` |  | `boolean` | Used to force mounting when more control is needed. Useful when<br>controlling animation with Vue animation libraries. |

[CheckboxIndicator.vue source](https://github.com/vinicunca/akar/blob/v2.0.20/packages/core/src/Checkbox/CheckboxIndicator.vue)

| Data attribute | Value |
| --- | --- |
| `[data-state]` | "checked" \\| "unchecked" \\| "indeterminate" |
| `[data-disabled]` | Present when disabled |

### Group Root

Wrapper around `CheckboxRoot` to support array of `modelValue`

**Props**

| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| `as` | `"div"` | `AsTag \| Component` | The element or component this component should render as. Can be overwritten by `asChild`. |
| `asChild` |  | `boolean` | Change the default rendered element for the one passed as a child, merging their props and behavior.<br><br>Read our [Composition](https://vinicunca.dev/akar/guides/composition) guide for more details. |
| `defaultValue` |  | `T[]` | The value of the checkbox when it is initially rendered. Use when you do not need to control its value. |
| `dir` |  | `"ltr" \| "rtl"` | The direction of navigation between items. |
| `disabled` |  | `boolean` | When `true`, prevents the user from interacting with the checkboxes |
| `loop` | `false` | `boolean` | Whether keyboard navigation should loop around |
| `max` |  | `number \| null` | The maximum number of values that can be selected. Once reached, the unchecked<br>checkboxes get `aria-disabled` but stay focusable, so consider telling users<br>about the limit. Style them with `[aria-disabled="true"]`. |
| `modelValue` |  | `T[]` | The controlled value of the checkbox. Can be binded with v-model. |
| `name` |  | `string` | The name of the field. Submitted with its owning form as part of a name/value pair. |
| `orientation` |  | `"vertical" \| "horizontal"` | The orientation of the group.<br>Mainly so arrow navigation is done accordingly (left & right vs. up & down) |
| `required` |  | `boolean` | When `true`, indicates that the user must set the value before the owning form can be submitted. |
| `rovingFocus` | `true` | `boolean` | When `false`, navigating through the items using arrow keys will be disabled. |

**Events**

| Event | Payload | Description |
| --- | --- | --- |
| `update:modelValue` | `value: T[]` | Event handler called when the value of the checkbox changes. |

[CheckboxGroupRoot.vue source](https://github.com/vinicunca/akar/blob/v2.0.20/packages/core/src/Checkbox/CheckboxGroupRoot.vue)

## Examples

### Custom Values

Use the `trueValue` and `falseValue` props to specify custom values for the checked and unchecked states instead of the default `true`/`false`.

```vue
<script setup>
import { Icon } from '@iconify/vue'
import { CheckboxIndicator, CheckboxRoot } from 'akar'
import { ref } from 'vue'

// With string values
const acceptTerms = ref('no')

// With number values
const permission = ref(0)
</script>

<template>
  <!-- String values -->
  <CheckboxRoot v-model="acceptTerms" true-value="yes" false-value="no">
    <CheckboxIndicator>
      <Icon icon="radix-icons:check" />
    </CheckboxIndicator>
  </CheckboxRoot>
  Value: {{ acceptTerms }} <!-- "yes" or "no" -->

  <!-- Number values -->
  <CheckboxRoot v-model="permission" :true-value="1" :false-value="0">
    <CheckboxIndicator>
      <Icon icon="radix-icons:check" />
    </CheckboxIndicator>
  </CheckboxRoot>
  Value: {{ permission }} <!-- 1 or 0 -->
</template>
```

### Indeterminate

You can set the checkbox to `indeterminate` by taking control of its state.

```vue
<script setup>
import { Icon } from '@iconify/vue'
import { CheckboxIndicator, CheckboxRoot } from 'akar'

const checked = ref('indeterminate')
</script>

<template>
  <CheckboxRoot v-model="checked">
    <CheckboxIndicator>
      <Icon
        v-if="checked === 'indeterminate'"
        icon="radix-icons:divider-horizontal"
      />
      <Icon
        v-if="checked"
        icon="radix-icons:check"
      />
    </CheckboxIndicator>
  </CheckboxRoot>

  <button
    type="button"
    @click="() => (checked === 'indeterminate' ? (checked = false) : (checked = 'indeterminate'))"
  >
    Toggle indeterminate
  </button>
</template>
```

## Accessibility

Adheres to the [tri-state Checkbox WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/checkbox).

### Keyboard Interactions

| Key | Description |
| --- | --- |
| <kbd>Space</kbd> | Checks/unchecks the checkbox |

---

- [ARIA](https://www.w3.org/WAI/ARIA/apg/patterns/checkbox)
- [GitHub](https://github.com/vinicunca/akar/blob/v2.0.20/packages/core/src/Checkbox)
- [npm](https://www.npmjs.com/package/akar)


## Sitemap

See the full [sitemap](https://vinicunca.dev/sitemap.md) for all pages.
