WCAG 1.4.13 · Level AA · EN 301 549 9.1.4.13

Content on Hover or Focus

Requires that tooltips and popups shown on hover or focus can be dismissed, hovered over and stay visible until the user is done.

In brief

Tooltips, dropdowns and popovers that appear when you hover or focus an element are convenient, but they can also be a trap. A magnifier user may move the pointer and make the tooltip disappear before they can read it, or it may cover the very content they need.

This criterion requires that when extra content appears on pointer hover or keyboard focus and then goes away again, it is dismissible (without moving hover or focus), hoverable (the pointer can move onto it without it disappearing) and persistent (it stays until the user removes the trigger, dismisses it or the information is no longer valid).

What does it cover?

  • Dismissible: A mechanism, usually the Escape key, closes the content without moving pointer hover or keyboard focus. Exception: the content only shows an input error or does not hide or replace other content.
  • Hoverable: If hover triggers it, the pointer can move over the new content without it disappearing.
  • Persistent: It stays visible until the user moves hover or focus away, dismisses it, or the information is no longer valid.
  • What counts: Custom tooltips, popovers, hover menus and any content that is shown only on hover or focus.
  • Exceptions: Content controlled by the browser, such as the native title tooltip, where the author does not change its presentation.
  • Out of scope: Reaching the content by keyboard is 2.1.1. Focus order is 2.4.3. A tooltip that appears on focus must also not cause a change of context (3.2.1).

Who does it affect?

People who use screen magnifiers and see only part of the screen. People with tremors or low dexterity who cannot hold the pointer steady. Keyboard users. People with cognitive differences who need more time to read.

In the EAA and EN 301 549

The European Accessibility Act (Directive (EU) 2019/882) applies to in-scope products and services placed on the market after 28 June 2025. Recital 47 names four principles for websites and mobile applications: perceivable, operable, understandable and robust. Predictable, controllable pop-up content is part of "perceivable" and "operable".

The technical counterpart is the standard EN 301 549, which incorporates WCAG 1.4.13 by reference and turns it into separate clauses for each kind of ICT.

Where WCAG 1.4.13 appears in EN 301 549
ClauseType of ICTWhat it requires
9.1.4.13Web pagesWeb content must satisfy WCAG success criterion 1.4.13.
11.1.4.13Non-web software (native mobile apps)Software must satisfy the criterion for content that appears on pointer hover or keyboard focus.

Whether and how the criterion applies to non-web documents is stated in clause 10 of the standard. Clause numbers follow the "9. + WCAG number" pattern of EN 301 549. In V3.2.1 the software clause is divided into further subclauses for open and closed functionality. Check the exact numbers in the standard when you cite them.

Standard version: EN 301 549 V4.1.1 (September 2026) is based on WCAG 2.2 and is the first version prepared specifically for the EAA. It has not yet been cited in the Official Journal of the European Union, so for now it is best treated as a voluntary technical route to the EAA's requirements. Once cited, it will give a presumption of conformity. The text of criterion 1.4.13 is the same in WCAG 2.1 and 2.2. It is a Level AA criterion.

A note on EAA scope: Article 2(4) of the Directive excludes certain content from the requirements, for example office file formats published before 28 June 2025 and archives that are not updated after that date. Content you publish or change after that date is not covered by these exclusions.

Directive (EU) 2019/882, EUR-Lex, opens in a new tab

Code examples for the web

1. A tooltip that can be dismissed

Close the tooltip with Escape, even while the trigger keeps focus.

Incorrect
<button onmouseover="show()" onmouseout="hide()">Info</button>
Correct
<button aria-describedby="tip">Info</button>
<div id="tip" role="tooltip" hidden>Extra detail</div>

<script>
const b = document.querySelector("button");
const t = document.getElementById("tip");
b.addEventListener("focus", () => t.hidden = false);
b.addEventListener("blur",  () => t.hidden = true);
b.addEventListener("keydown", e => { if (e.key === "Escape") t.hidden = true; });
</script>

2. Keep the pointer path open

A gap between the trigger and the popup makes it vanish when the pointer crosses it. Keep them adjacent or treat both as the hover area.

Incorrect
.wrap:hover .pop { display: block; }
.pop { margin-top: 20px; } /* pointer leaves .wrap while crossing the gap */
Correct
.wrap:hover .pop, .wrap:focus-within .pop { display: block; }
.pop { margin-top: 0; padding-top: 8px; } /* no gap to cross */

3. Do not hide on a timer

A tooltip that disappears after a few seconds is not persistent.

Incorrect
setTimeout(() => tip.hidden = true, 3000);
Correct
// Hide only on blur, mouse leave of both trigger and tip, or Escape

4. Hoverable popup stays open over itself

Make the pointer-leave logic cover both the trigger and the popup.

Incorrect
trigger.addEventListener("mouseleave", () => pop.hidden = true);
Correct
function maybeHide(e) {
  if (!trigger.contains(e.relatedTarget) && !pop.contains(e.relatedTarget)) {
    pop.hidden = true;
  }
}
trigger.addEventListener("mouseleave", maybeHide);
pop.addEventListener("mouseleave", maybeHide);

5. Hover-only menus

A menu that only opens on hover is also not reachable by keyboard. Open on focus and click too.

Incorrect
.nav li:hover > ul { display: block; }
Correct
.nav li:hover > ul,
.nav li:focus-within > ul { display: block; }

6. Do not cover other content

A popup that hides what the user needs while it is open must be dismissible and should not cover the trigger.

Incorrect
.tip { position: absolute; top: 0; left: 0; /* covers the trigger */ }
Correct
.tip { position: absolute; top: 100%; left: 0; }

Code examples for mobile

Native apps have no hover, but the rule applies to focus on a keyboard, switch or external pointer. Provide a way to dismiss and keep popovers open until the user acts.

iOS (SwiftUI)

import SwiftUI

struct InfoButton: View {
    @State private var showInfo = false

    var body: some View {
        Button("Info") { showInfo.toggle() }
            // The popover stays until the user dismisses it (tap outside or Escape on a keyboard)
            .popover(isPresented: $showInfo) {
                Text("Extra detail")
                    .padding()
                    .presentationCompactAdaptation(.popover)
            }
            // Avoid: closing it automatically after a timer
    }
}

Android (Jetpack Compose)

import androidx.compose.foundation.layout.Column
import androidx.compose.material3.*
import androidx.compose.runtime.*

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun InfoButton() {
    val tooltipState = rememberTooltipState(isPersistent = true) // stays until dismissed
    TooltipBox(
        positionProvider = TooltipDefaults.rememberPlainTooltipPositionProvider(),
        tooltip = { PlainTooltip { Text("Extra detail") } },
        state = tooltipState
    ) {
        IconButton(onClick = { /* action */ }) {
            Icon(androidx.compose.material.icons.Icons.Filled.Info, contentDescription = "Info")
        }
    }
}

How to test

  • Hover over every trigger: Move the pointer slowly onto the trigger and then onto the new content. Does the content stay open while the pointer is over it?
  • Press Escape: With the content open, press Escape. Does it close without moving focus?
  • Wait: Leave the content open without moving. Does it stay until you dismiss it or move away?
  • Use the keyboard: Tab to the trigger. Does the same content appear on focus, and can you dismiss it?
  • Test with a magnifier: At high zoom, can you move to the popup and read it before it disappears?
  • Check for covered content: Does the new content hide something that the user still needs?
  • Use a checker as a starting point: Automated tools cannot test dismissal, hover and persistence. A person has to try each pattern.

Common mistakes

  • Tooltips that vanish when the pointer moves toward them: Not hoverable.
  • No way to dismiss with Escape: Fails the dismissible requirement.
  • Auto-hide timers: Fails persistent.
  • Gaps between trigger and popup: The popup disappears when the pointer crosses the gap.
  • Hover-only menus: Keyboard users cannot open them.
  • Popups that cover the trigger or nearby text: Users cannot read what they were looking at.
  • Closing on blur too early: Moving focus into the popup closes it.
  • Treating native title tooltips as custom: Native browser tooltips are an exception, but they are also poorly accessible.

Sources

Standard version: EN 301 549 V4.1.1 (2026-09), WCAG 2.2. This page is for informational purposes only and is not legal advice. For binding requirements, refer to the official texts of the European Accessibility Act (Directive (EU) 2019/882) and EN 301 549.

Corpowid is recognized by Gartner

Corpowid has been recognized by Gartner, a leading global research and advisory firm, for our innovation and performance in digital accessibility. These badges reflect our commitment to creating inclusive, AI-powered web experiences.

Have questions about Corpowid?

Let’s connect.

We will get back to you as soon as possible.