---
id: 672a54ce90c19e9038f481d7
title: What Is the aria-expanded Attribute, and How Does It Work?
challengeType: 19
dashedName: what-is-the-aria-expanded-attribute
---

# --interactive--

The `aria-expanded` attribute is used for accessibility purposes to indicate if a control is expanded or collapsed. It's used in conjunction with collapsible widgets like menus, accordions and other disclosure widgets that control the visibility of content. The `aria-expanded` attribute is set to `true` if the control is expanded, or `false` if it is collapsed.

The information provided by `aria-expanded` allows people using screen readers to understand the current state of the control (whether it is expanded or collapsed).

The `aria-expanded` attribute is applied to the interactive element that toggles the visibility of a collapsible widget. For example, if a button toggles an expandable menu, the `aria-expanded` attribute is placed on the button.

When the menu is expanded, the `aria-expanded` attribute should be set to `true` like in this example:

```html
<button aria-expanded="true">Menu</button>
```

When the menu is collapsed, it should be set to `false` instead.

```html
<button aria-expanded="false">Menu</button>
```

You must always have the `aria-expanded` attribute set to either `true` or `false` on the controlling element. For example, if a button toggles the visibility of a menu, the default value for `aria-expanded` should be  based on the default visibility of the menu.

If the menu is expanded by default, `aria-expanded` should initially be set to `true`. If the menu is collapsed by default, `aria-expanded` should initially be set of `false`.

The value of `aria-expanded` should be updated dynamically using JavaScript as the user interacts with the element.

Additionally, the properties, `aria-controls` and `aria-owns` can be used in combination with `aria-expanded` to establish a programmatic connection between the controlling element and the element it controls.

Let's start with `aria-controls`. When used with `aria-expanded`, the `aria-controls` attribute is used to specify the element being controlled. For example, a button might expand or collapse a list acting as a menu. The value of `aria-controls` will be the `id` of the controlled element (the menu list in this example).

:::interactive_editor

```html
<link rel="stylesheet" href="styles.css">

<button aria-expanded="false" aria-controls="menu1">Menu</button>
<ul id="menu1">
  <li>...</li>
  <li>...</li>
</ul>

<script src="index.js"></script>
```

```css
button {
  background-color: #0078d4;
  color: white;
  padding: 8px 12px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

button:hover {
  background-color: #005ea2;
}

ul {
  list-style: none;
  padding: 0;
  margin: 8px 0 0;
  border: 1px solid #ccc;
  border-radius: 4px;
  width: 150px;
  background: #fff;
}

li {
  padding: 8px;
  cursor: pointer;
}

li:hover {
  background-color: #f2f2f2;
}

```

```js
const button = document.querySelector('button');
const menu = document.getElementById(button.getAttribute('aria-controls'));

button.addEventListener('click', () => {
  const expanded = button.getAttribute('aria-expanded') === 'true';
  button.setAttribute('aria-expanded', String(!expanded));
  menu.hidden = expanded;
});

```

:::

Notice that the list immediately follows the controlling button. For expandable controls like this, it is best to have the expanded content immediately follow the element that controls it in the DOM. This prevents screen reader users from having to search for the expanded content, and makes it easier for keyboard users to navigate through any interactive controls in the expanded content.

If it is not possible to place the expanded content immediately after the controlling element, the `aria-owns` attribute allows you to virtually move it after the control in the accessibility tree. This allows assistive technology like screen readers to pretend the expanded content is placed directly after the control in the DOM.  

:::interactive_editor

```html
<link rel="stylesheet" href="styles.css">

<button aria-owns="menu1" aria-expanded="true">Menu</button>
<main>
  <!-- an entire page worth of content --->
</main>
<ul id="menu1">
  <li>...</li>
  <li>...</li>
</ul>

<script src="index.js"></script>
```

```css
button {
  background-color: #0078d4;
  color: white;
  padding: 8px 12px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  margin-bottom: 10px;
}

button:hover {
  background-color: #005ea2;
}

ul {
  list-style: none;
  padding: 0;
  margin: 8px 0;
  border: 1px solid #ccc;
  border-radius: 4px;
  width: 150px;
  background: #fff;
  position: absolute;
  z-index: 10;
}

li {
  padding: 8px;
  cursor: pointer;
}

li:hover {
  background-color: #f2f2f2;
}

```

```js
const button = document.querySelector('button');
const menu = document.getElementById(button.getAttribute('aria-owns'));

button.addEventListener('click', () => {
  const expanded = button.getAttribute('aria-expanded') === 'true';
  button.setAttribute('aria-expanded', String(!expanded));
  menu.hidden = expanded;
});

// Close the menu if user clicks outside
document.addEventListener('click', (e) => {
  if (!button.contains(e.target) && !menu.contains(e.target)) {
    button.setAttribute('aria-expanded', 'false');
    menu.hidden = true;
  }
});

```

:::

There are drawbacks to using the `aria-owns` attribute. It creates unnecessary verbosity for screen reader users since most screen readers will automatically read out the entire contents of the expanded element when first expanded. It also does not change the tab order, potentially forcing keyboard users to tab through all of the other interactive controls on the page before reaching the expanded content, unless you manage the tabbing order with JavaScript.

Ideally, the expandable content should be placed after the control element, and the `aria-owns` attribute should only be used in a worst case scenario when that is not possible. If it must be used, you will need to thoroughly test with a wide range of screen readers and browsers to ensure that your implementation is accessible for everyone.

And just a reminder, when you use either `aria-controls` or `aria-owns`, the value of `aria-expanded` must continue to be updated as the control is expanded and collapsed.

The `aria-expanded` attribute indicates whether a control  is expanded or collapsed. This information is essential for screen reader users, helping them understand the current state of collapsible elements like menus, accordions, and other similar disclosure widgets.

By using `aria-expanded` correctly, you can create an intuitive user experience for everyone.

# --questions--

## --text--

What is the primary purpose of the `aria-expanded` attribute?

## --answers--

To define the visual appearance of an element.

### --feedback--

Think about how `aria-expanded` provides information to assistive technologies.

---

To improve website performance.

### --feedback--

Think about how `aria-expanded` provides information to assistive technologies.

---

To indicate whether an element is expanded or collapsed.

---

To enhance browser compatibility.

### --feedback--

Think about how `aria-expanded` provides information to assistive technologies.

## --video-solution--

3

## --text--

When should the `aria-expanded` attribute be used?

## --answers--

For all elements on a web page.

### --feedback--

Consider the context in which `aria-expanded` is most useful.

---

For elements that are visually hidden.

### --feedback--

Consider the context in which `aria-expanded` is most useful.

---

For collapsible elements like menus and accordions.

---

For elements with dynamic content.

### --feedback--

Consider the context in which `aria-expanded` is most useful.

## --video-solution--

3

## --text--

What are the possible values for the `aria-expanded` attribute?

## --answers--

`true`, `false`, `yes`, `no`.

### --feedback--

Think about the states an element can be in regarding expansion or collapse.

---

`open`, `closed`, `expanded`, `collapsed`.

### --feedback--

Think about the states an element can be in regarding expansion or collapse.

---

`show`, `hide`, `visible`, `invisible`.

### --feedback--

Think about the states an element can be in regarding expansion or collapse.

---

`true`, `false`.

## --video-solution--

4
