Retour au Centre de connaissances
Plateforme

CSS Highlight API : peinture et accessibilité

Utilisez des surbrillances personnalisées avec texte sémantique, plages bornées, focus clavier, contraste et repli accessible.

BotBrowser Team

Documentation

Vous voulez la documentation structurée pour Plateforme ?

Cet article fait partie de la bibliothèque éditoriale. Pour les étapes de configuration, la référence et les mises à jour continues, passez directement à la section docs.

CSS Highlight API peut styliser les correspondances de recherche, les annotations et les sélections sans modifier le DOM, mais un surlignage est une présentation, pas un sens. BotBrowser peut rejouer un fixture de surlignage appartenant à la page et inspecter les replis visibles ; il ne peut pas certifier la parole d’une technologie d’assistance, l’intention de lecture d’une personne ni l’implémentation complète du rendu du navigateur. Gardez le contrat étroit : exposez le texte dans le DOM, enregistrez des plages bornées, peignez une couche distincte et conservez un repli sémantique utilisable au clavier.

CSS Highlight API transforme le texte DOM en plages bornées et en couche peinte, tout en conservant le focus clavier, les couleurs forcées et le repli DOM

TL;DR

  • CSS.highlights.set('search-hit', new Highlight(range)) applique un style à un Range ; il n’ajoute ni texte, ni libellé, ni sémantique accessible.
  • Un pseudo-élément de surlignage comme ::highlight(search-hit) doit utiliser une paire de couleurs au contraste sûr et ne jamais être l’unique indice.
  • Gardez le texte source et un compteur de résultats annoncé dans le DOM ; testez séparément le focus clavier, la sélection, les couleurs forcées, le zoom et la réduction des mouvements.
  • Reconstruisez les plages après les changements de contenu, limitez leur nombre et leur longueur, puis supprimez les entrées obsolètes avec CSS.highlights.delete(name).
  • BotBrowser peut vérifier l’état propre à la page et le repli ; les recommandations viennent des sources et aucune exécution BotBrowser n’est déclarée.

Sommaire

Garder le sens dans le DOM

L’API de surlignage change la façon dont le texte existant est peint. Un Range pointe vers des nœuds déjà présents ; un lecteur d’écran, une copie, une recherche textuelle et un rendu sans CSS ont donc besoin du même contenu source. Placez le compteur de résultats dans une région aria-live="polite", gardez la requête dans un champ libellé et exposez une liste ou un paragraphe ordinaire pour les annotations. N’encodez pas un avertissement uniquement avec un fond jaune ou un effet de peinture personnalisé.

L’API est distincte de la Selection API. Une sélection utilisateur peut être visible via ::selection ; un surlignage personnalisé nommé est un objet Highlight géré par l’application. Donnez à chaque état un nom stable comme search-hit ou current-hit et supprimez-le lorsque la requête est vide. Le nom est un hook CSS, pas un libellé qu’une technologie d’assistance annoncera.

Pour une limite connexe de l’identité visuelle, gestion des couleurs CSS et accessibilité de l’affichage explique comment séparer un résultat de style visible dans le navigateur d’une revendication de capacité. Pour l’interaction clavier, paramètres régionaux et confidentialité de Keyboard Layout API montre pourquoi un libellé visuel ne doit pas devenir une inférence sur la personne qui l’utilise. La revue de compatibilité des Web Components ajoute une matrice qui sépare détection de fonction et promesse faite au lecteur.

Enregistrer des plages bornées

Créez les plages à partir des nœuds de texte rendus, pas d’une chaîne HTML non fiable. Un fixture simple peut parcourir les nœuds de texte, trouver une requête insensible à la casse et appeler range.setStart() et range.setEnd() pour chaque correspondance. Limitez MAX_HIGHLIGHTS et MAX_MATCH_CHARS ; la page doit rester réactive lorsqu’une requête correspond à des milliers de mots.

const MAX_HIGHLIGHTS = 100;
const MAX_MATCH_CHARS = 120;

function showMatches(root, query) {
  CSS.highlights.delete('search-hit');
  if (!query || !window.Highlight) return 0;
  const ranges = [];
  for (const node of root.querySelectorAll('[data-search-text]')) {
    const text = node.textContent || '';
    let offset = 0;
    while (offset < text.length && ranges.length < MAX_HIGHLIGHTS) {
      const start = text.toLocaleLowerCase().indexOf(query.toLocaleLowerCase(), offset);
      if (start < 0) break;
      if (query.length <= MAX_MATCH_CHARS) {
        const range = new Range();
        range.setStart(node.firstChild, start);
        range.setEnd(node.firstChild, start + query.length);
        ranges.push(range);
      }
      offset = start + Math.max(query.length, 1);
    }
  }
  CSS.highlights.set('search-hit', new Highlight(...ranges));
  return ranges.length;
}

Le fixture exact dépend des limites des nœuds de texte ; le code de production doit gérer sans risque les nœuds imbriqués et un firstChild vide. Recalculez après le rendu, la localisation, le filtrage ou le recyclage d’une liste virtuelle. Une plage qui pointe vers du contenu supprimé est un état obsolète, pas une raison de conserver un ancien objet de surlignage.

Peindre une couche visible et accessible

Utilisez le pseudo-élément ::highlight(search-hit) pour la couche nommée et gardez des déclarations courtes. Le style de CSS Highlight API est volontairement limité par rapport aux éléments ordinaires ; le navigateur peut ignorer les propriétés non prises en charge. Choisissez un premier plan et un arrière-plan qui atteignent la cible de contraste du produit, puis ajoutez un indice non chromatique, comme un contour, une icône ou un compteur dans l’interface voisine.

::highlight(search-hit) {
  color: #111827;
  background-color: #fde68a;
  text-decoration: underline 0.12em solid #92400e;
}

@media (forced-colors: active) {
  ::highlight(search-hit) {
    color: CanvasText;
    background-color: Highlight;
    text-decoration: underline;
  }
}

Ne supposez pas qu’un surlignage personnalisé est peint de façon identique dans chaque moteur ou contexte intégré. Détectez CSS.highlights, Highlight et le sélecteur utilisé, puis affichez la classe de repli ou le marqueur en ligne si un prérequis manque. Un résultat de peinture visible dans le navigateur ne prouve pas qu’un lecteur d’écran annoncera « correspondance » ni qu’un mode à contraste élevé conservera vos couleurs.

Gérer la sélection, le focus et le repli

La recherche doit déplacer le focus vers un vrai contrôle de résultat, pas vers une plage peinte. Fournissez des boutons Précédent et Suivant dotés d’un nom accessible, conservez la requête dans le champ et faites défiler le résultat sélectionné sans piéger le focus clavier. Si l’utilisateur sélectionne du texte, ne remplacez pas ::selection par le surlignage de recherche ; les deux couches expriment des états différents.

Lorsque les surlignages ne sont pas pris en charge, ajoutez un élément mark temporaire ou une classe CSS autour d’un nœud de texte fiable et exposez le même compteur et la même navigation. Supprimez ce repli avant d’appliquer une nouvelle requête afin d’éviter l’accumulation d’enveloppes imbriquées. Pour les annotations en lecture seule, une note adjacente avec aria-describedby est plus sûre qu’un patch de couleur qui disparaît à l’impression ou en mode couleurs forcées.

Vérifiez le zoom à 200 %, l’espacement du texte, la navigation au clavier seul, prefers-reduced-motion et un lecteur d’écran. Le surlignage ne doit pas masquer les contours du focus, couper les jambages descendants ni créer une animation qui clignote pour chaque résultat. Si la requête est vide ou sans correspondance, effacez le surlignage nommé et annoncez « 0 résultat » dans la région active.

Classer les résultats avec une table de décision

Observed stageWhat it establishesSafe next action
CSS.highlights or Highlight absentNamed highlights cannot start in this contextUse semantic mark or plain text and keep navigation usable
API present, query emptyThere is no range to paintDelete search-hit, announce the cleared state, and retain focus
Ranges created, paint visibleThe page applied one browser-visible style layerVerify contrast, focus, forced colors, and accessible result text
Content or locale changedExisting offsets may be staleRebuild ranges from current text nodes and discard the old object
Match count exceeds 100The fixture hit its bounded workloadShow a capped result state and offer narrower search, not unbounded work
Forced colors or print differsPresentation changed by user agent or mediumKeep the DOM result and a non-color cue as the source of meaning

Chaque ligne décrit une condition observable, pas une promesse universelle. Notez l’état visible, la longueur de la requête, le nombre de plages et le repli choisi ; ne conservez pas le document entier et n’inférez pas le comportement de lecture.

Point de contrôleTraceCe que cela ne prouve pas
Détection APICSS.highlights=true, Highlight=trueLa parole d’un lecteur d’écran
Cycle de plagerangeCount=3, longueur et nœudsUne identité liée au texte
Replifallback=mark et raisonUne panne générale d’accessibilité
FocusfocusTarget=result-2 et ordre clavierL’intention de la personne
Nettoyageancien surlignage suppriméLa suppression d’un état distant
VérificationTrace minimaleNe pas déduire
Compatibilité APIwindow.CSS, CSS.highlights, window.HighlightQue toutes les propriétés CSS sont prises en charge
Limites de requêteMAX_HIGHLIGHTS=100, MAX_MATCH_CHARS=120Que le document entier peut être conservé
Plage actuellenœud source et rangeCountQue le texte soit lié à une identité
FocusfocusTarget=result-2Que la personne souhaite lire ce résultat
Mode visuelnormal, couleurs forcées ou impressionQue l’écran physique utilise les mêmes couleurs
Nettoyagenom supprimé avant un nouveau renduQu’un état distant a été supprimé

Capacité et limites de BotBrowser

BotBrowser peut exécuter un fixture de page autorisé et vérifier le compteur DOM, le nombre de plages et le chemin de repli. Il ne peut pas certifier la lecture par un lecteur d’écran ni garantir que chaque moteur peigne ::highlight() de la même façon.

BotBrowser peut rejouer un fixture autorisé qui enregistre des plages Highlight, applique ::highlight() et vérifie le repli visible ; les recommandations viennent des sources et aucune exécution BotBrowser n’est déclarée, pas plus qu’une certification de la parole d’un lecteur d’écran ou de la perception des couleurs.

{
  "api": "CSS.highlights",
  "highlightName": "search-hit",
  "rangeCount": 3,
  "maxHighlights": 100,
  "domResultText": "3 matches",
  "assistiveTechnologySpeech": "not-asserted"
}

Répétez le fixture après une version du navigateur, un changement de localisation, une liste virtuelle ou un nouveau token de contraste. Comparez la première différence visible et conservez le repli DOM dans le dossier d’acceptation.

Sources publiques

Conclusion pratique

Utilisez la peinture personnalisée de CSS Highlight API pour souligner un texte qui porte déjà un sens sémantique. Bornez et reconstruisez les plages, gardez l’état et la navigation dans le DOM et fournissez un repli sans couleur au contraste sûr. Considérez la sortie BotBrowser comme une preuve du comportement de la page, pas comme une preuve de parole assistive ni de l’interprétation d’une personne. BotBrowser peut rejouer un fixture autorisé qui enregistre des plages Highlight, applique ::highlight() et vérifie le repli visible ; cet article ne revendique aucune exécution BotBrowser et ne certifie ni la parole d’un lecteur d’écran ni la perception des couleurs.

#CSS Highlight API#CSS Custom Highlight API#Accessibility#CSS Painting#BotBrowser

Cet article fait partie du guide : Surfaces de la plateforme web : carte de revue

Faites passer BotBrowser de la recherche à la production

Utilisez ces guides pour comprendre le modèle, puis passez à la validation multi-plateforme, aux contextes isolés et au déploiement navigateur prêt pour l'échelle.