Focus du style

L'indicateur de focus (souvent représenté par un "anneau de focus") identifie l'élément actuellement sélectionné sur votre page. Pour les utilisateurs qui ne peuvent pas utiliser de souris, cet indicateur est extrêmement important, car il remplace leur pointeur de souris.

Si l'indicateur de focus par défaut du navigateur est en conflit avec votre conception, vous pouvez le restyler à l'aide du CSS. N'oubliez pas de garder à l'esprit les utilisateurs de clavier.

La pseudo-classe :focus est appliquée chaque fois qu'un élément est sélectionné, quel que soit le périphérique d'entrée (souris, clavier, stylet, etc.) ou la méthode utilisée pour le sélectionner. Par exemple, l'élément <div> ci-dessous possède un tabindex, ce qui le rend sélectionnable. Il dispose également d'un style personnalisé pour son état :focus:

div[tabindex="0"]:focus {
  outline: 4px dashed orange;
}

Que vous utilisiez une souris pour cliquer dessus ou un clavier pour y accéder par tabulation, l'<div> reste toujours identique.

Malheureusement, les navigateurs peuvent être incohérents dans la façon dont ils appliquent la sélection. La sélection d'un élément peut dépendre du navigateur et du système d'exploitation.

Par exemple, le <button> ci-dessous comporte également un style personnalisé pour son état :focus.

button:focus {
  outline: 4px dashed orange;
}

Si vous cliquez sur <button> avec une souris dans Chrome sur macOS, vous devriez voir son style de mise au point personnalisé. Toutefois, le style de focus personnalisé ne s'affiche pas si vous cliquez sur <button> dans Safari sur macOS. En effet, dans Safari, l'élément ne reçoit pas la sélection lorsque vous cliquez dessus.

Étant donné que le comportement de la sélection n'est pas cohérent, vous devrez peut-être effectuer quelques tests sur différents appareils pour vous assurer que vos styles de sélection sont acceptables pour vos utilisateurs.

Utiliser :focus-visible pour afficher sélectivement un indicateur de focus

La nouvelle pseudo-classe :focus-visible est appliquée chaque fois qu'un élément reçoit la sélection et que le navigateur détermine par heuristique que l'affichage d'un indicateur de sélection serait bénéfique pour l'utilisateur. Plus précisément, si l'interaction utilisateur la plus récente a été effectuée via le clavier et que la pression sur la touche n'incluait pas de touche méta, ALT / OPTION ou CONTROL, :focus-visible correspondra.

Le bouton de l'exemple ci-dessous affiche un indicateur de focus sélectivement. Si vous utilisez une souris pour cliquer dessus, les résultats sont différents que si vous utilisez d'abord un clavier pour y accéder par tabulation.

button:focus-visible {
  outline: 4px dashed orange;
}

Utiliser :focus-within pour styliser le parent d'un élément sélectionné

La pseudo-classe :focus-within est appliquée à un élément lorsque l'élément lui-même reçoit la sélection ou lorsqu'un autre élément de cet élément reçoit la sélection.

Il peut être utilisé pour mettre en évidence une région de la page afin d'attirer l'attention de l'utilisateur sur cette zone. Par exemple, le formulaire ci-dessous reçoit la sélection à la fois lorsque le formulaire lui-même est sélectionné et lorsqu'une de ses cases d'option est sélectionnée.

form:focus-within {
  background: #ffecb3;
}

Quand afficher un indicateur de sélection

Une bonne règle d'or est de vous demander : "Si vous avez cliqué sur ce contrôle lorsque vous utilisiez un appareil mobile, vous attendez-vous à ce qu'un clavier s'affiche ?"

Si la réponse est "oui", le contrôle doit probablement toujours afficher un indicateur de mise au point, quel que soit le périphérique d'entrée utilisé pour le mettre au point. L'élément <input type="text"> en est un bon exemple. L'utilisateur doit envoyer une entrée à l'élément via le clavier, quel que soit le mode d'initialisation de la sélection de l'élément de saisie. Il est donc utile d'afficher toujours un indicateur de sélection.

Si la réponse est "non", le contrôle peut choisir d'afficher sélectivement un indicateur de focus. L'élément <button> en est un bon exemple. Si un utilisateur clique dessus avec une souris ou un écran tactile, l'action est terminée et un indicateur de focus n'est peut-être pas nécessaire. Toutefois, si l'utilisateur naviguera avec un clavier, il est utile d'afficher un indicateur de sélection afin qu'il puisse décider s'il souhaite ou non cliquer sur le contrôle à l'aide des touches ENTER ou SPACE.

Éviter la requête outline: none

La façon dont les navigateurs décident de dessiner un indicateur de focus est, franchement, très déroutante. Modifier l'apparence d'un élément <button> avec CSS ou attribuer un tabindex à un élément déclenche le comportement par défaut de l'anneau de sélection du navigateur.

Un antimodèle très courant consiste à supprimer l'indicateur de focus à l'aide de CSS, par exemple:

/* Don't do this!!! */
:focus {
  outline: none;
}

Le meilleur moyen de contourner ce problème consiste à utiliser une combinaison de :focus et du polyfill :focus-visible. Le premier bloc de code ci-dessous montre comment fonctionne le polyfill, et l'application exemple en dessous fournit un exemple d'utilisation du polyfill pour modifier l'indicateur de focus d'un bouton.

/*
  This will hide the focus indicator if the element receives focus via the
  mouse, but it will still show up on keyboard focus.
*/
.js-focus-visible :focus:not(.focus-visible) {
  outline: none;
}

/*
  Optionally: Define a strong focus indicator for keyboard focus.
  If you choose to skip this step, then the browser's default focus
  indicator will be displayed instead.
*/
.js-focus-visible .focus-visible {
  
}