# Element “button” is missing one or more of the following attributes: “aria-checked”, “role”, “type”.

> Canonical HTML version: https://rocketvalidator.com/html-validation/element-button-is-missing-one-or-more-of-the-following-attributes-aria-checked-role-type
> Attribution: Rocket Validator (https://rocketvalidator.com)
> License: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)

The HTML specification defines `<button>` as a versatile interactive element, but its behavior changes depending on context. When a `<button>` is placed inside a `<form>` without a `type` attribute, it defaults to `type="submit"`, which can cause unexpected form submissions. The validator flags this because relying on the implicit default is ambiguous and error-prone. Explicitly setting the `type` attribute makes the button's intent clear to both developers and browsers.

The three valid values for the `type` attribute are:

- `submit` — submits the parent form's data to the server.
- `reset` — resets all form controls to their initial values.
- `button` — performs no default action; behavior is defined via JavaScript.

When a `<button>` is given an ARIA `role` of `checkbox`, `switch`, or `menuitemcheckbox`, the validator expects an `aria-checked` attribute to accompany it. These roles describe toggle controls that have a checked or unchecked state, so assistive technologies need to know the current state. Without `aria-checked`, screen readers cannot communicate whether the control is on or off, making the interface inaccessible.

The `aria-checked` attribute accepts the following values:

- `true` — the control is checked or on.
- `false` — the control is unchecked or off.
- `mixed` — the control is in an indeterminate state (valid for `checkbox` and `menuitemcheckbox` roles only).

## How to fix it

**For standard buttons**, add the `type` attribute with the appropriate value. If the button triggers JavaScript behavior and is not meant to submit a form, use `type="button"`. If it submits a form, use `type="submit"` explicitly to make the intent clear.

**For toggle buttons**, ensure the `<button>` has both a `role` attribute (such as `checkbox` or `switch`) and an `aria-checked` attribute that reflects the current state. You should also include `type="button"` to prevent unintended form submission. Use JavaScript to toggle the `aria-checked` value when the user interacts with the button.

## Examples

### Missing `type` attribute

This triggers the validator warning because the `type` is not specified:

```html
<form action="/search">
  <input type="text" name="q">
  <button>Search</button>
</form>
```

Fixed by adding an explicit `type`:

```html
<form action="/search">
  <input type="text" name="q">
  <button type="submit">Search</button>
</form>
```

### Button used outside a form without `type`

```html
<button onclick="openMenu()">Menu</button>
```

Fixed by specifying `type="button"`:

```html
<button type="button" onclick="openMenu()">Menu</button>
```

### Toggle button missing `aria-checked`

A button with `role="switch"` but no `aria-checked` attribute:

```html
<button type="button" role="switch">Dark Mode</button>
```

Fixed by adding `aria-checked`:

```html
<button type="button" role="switch" aria-checked="false">Dark Mode</button>
```

### Checkbox-style toggle button

A button acting as a checkbox must include both `role="checkbox"` and `aria-checked`:

```html
<button type="button" role="checkbox" aria-checked="false">
  Enable notifications
</button>
```

### Complete toggle example with all required attributes

```html
<button type="button" role="switch" aria-checked="false" id="wifi-toggle">
  Wi-Fi
</button>
<script>
  document.getElementById("wifi-toggle").addEventListener("click", function () {
    const isChecked = this.getAttribute("aria-checked") === "true";
    this.setAttribute("aria-checked", String(!isChecked));
  });
</script>
```

In this example, the `type="button"` prevents form submission, the `role="switch"` tells assistive technologies this is a toggle, and `aria-checked` is updated dynamically to reflect the current state. This ensures the button is fully accessible and passes validation.
