# Bad value “aria-expanded” for attribute “aria-expanded” on element “button”.

> Canonical HTML version: https://rocketvalidator.com/html-validation/bad-value-aria-expanded-for-attribute-aria-expanded-on-element-button
> Attribution: Rocket Validator (https://rocketvalidator.com)
> License: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)

The `aria-expanded` attribute communicates to assistive technologies whether a related grouping element (such as a dropdown menu, accordion panel, or collapsible section) is currently expanded or collapsed. It accepts only three valid values:

- `"true"` — the controlled element is expanded and visible.
- `"false"` — the controlled element is collapsed and hidden.
- `"undefined"` — the element has no expandable relationship (this is also the implicit default when the attribute is omitted entirely).

This validation error typically occurs when the attribute is accidentally set to a non-boolean value. A common mistake is writing `aria-expanded="aria-expanded"`, which mimics the old HTML4 pattern for boolean attributes like `checked="checked"`. However, `aria-expanded` is **not** a standard HTML boolean attribute — it is an ARIA state attribute that requires an explicit string value of `"true"` or `"false"`.

Setting an invalid value means assistive technologies like screen readers cannot correctly interpret the state of the control. A screen reader user may not know whether a menu is open or closed, leading to a confusing and inaccessible experience. Browsers may also handle the invalid value unpredictably, potentially treating it as truthy or ignoring it altogether.

## How to fix it

1. Identify the element with the invalid `aria-expanded` value.
2. Replace the value with `"true"` if the associated content is currently expanded, or `"false"` if it is collapsed.
3. If the button has no expand/collapse relationship at all, remove the `aria-expanded` attribute entirely.
4. Ensure that JavaScript toggling logic updates the attribute to `"true"` or `"false"` — never to any other string.

## Examples

### ❌ Invalid: attribute set to a non-boolean string

```html
<button aria-expanded="aria-expanded" aria-controls="menu">
  Toggle Menu
</button>
<ul id="menu">
  <li>Option 1</li>
  <li>Option 2</li>
</ul>
```

The value `"aria-expanded"` is not a recognized value and triggers the validation error.

### ✅ Fixed: attribute set to `"false"` (collapsed state)

```html
<button aria-expanded="false" aria-controls="menu">
  Toggle Menu
</button>
<ul id="menu" hidden>
  <li>Option 1</li>
  <li>Option 2</li>
</ul>
```

### ✅ Fixed: attribute set to `"true"` (expanded state)

```html
<button aria-expanded="true" aria-controls="menu">
  Toggle Menu
</button>
<ul id="menu">
  <li>Option 1</li>
  <li>Option 2</li>
</ul>
```

### ❌ Invalid: other common incorrect values

```html
<!-- Using "yes" instead of "true" -->
<button aria-expanded="yes">Details</button>

<!-- Using "1" instead of "true" -->
<button aria-expanded="1">Details</button>

<!-- Empty value -->
<button aria-expanded="">Details</button>
```

All of these are invalid. The only accepted values are `"true"`, `"false"`, and `"undefined"`.

### ✅ Toggling with JavaScript

When toggling `aria-expanded` dynamically, make sure the value is always set to the correct string:

```html
<button aria-expanded="false" aria-controls="panel" onclick="togglePanel(this)">
  Show details
</button>
<div id="panel" hidden>
  <p>Additional details here.</p>
</div>

<script>
  function togglePanel(button) {
    const expanded = button.getAttribute("aria-expanded") === "true";
    button.setAttribute("aria-expanded", String(!expanded));
    const panel = document.getElementById(button.getAttribute("aria-controls"));
    panel.hidden = expanded;
  }
</script>
```

This ensures the attribute always toggles between `"true"` and `"false"`, keeping the markup valid and the experience accessible for all users.
