Micro-composants UI pour articles techniques : kbd, badges, tags, code inline et boutons Copier

Cet article vous a aidé ?

Les pannes en production commencent rarement par une grosse erreur unique. Elles résultent de milliers de petites coupures : une commande copiée avec un retour caché, un badge qui suggère « sécurisé », un tag qui ment, un raccourci clavier affiché de façon incorrecte, du code inline qui ressemble à du texte courant. Le lecteur fait ce que vous lui avez indiqué. Votre UI lui a appris à lui faire confiance.

Si vous publiez des articles techniques, de la documentation, des runbooks ou des playbooks internes, ces micro-composants ne sont pas une décoration. Ils font partie du plan de contrôle. Traitez-les comme votre monitoring : des valeurs par défaut tranchées, des résultats mesurables et zéro tolérance pour des états ambigus.

Pourquoi ces micro-composants comptent (et comment ils échouent)

Dans le monde SRE, nous obsédons sur les budgets d’erreur parce qu’ils imposent l’honnêteté. Les micro-composants UI exigent la même énergie. Si votre site de docs a un bouton Copier qui copie parfois des invites additionnelles, vous avez créé un budget d’erreur pour le temps de vos lecteurs, et vous le dépensez sans le mesurer.

Les micro-composants sont des « API comportementales »

Chaque composant enseigne un comportement à l’utilisateur :

  • <kbd> enseigne « appuyez sur cette séquence exacte de touches ». Si c’est erroné, vous cassez des flux et l’accessibilité.
  • Le code inline enseigne « ce jeton est exact ». S’il est stylé comme du texte normal, il devient « optionnel ».
  • Les badges enseignent « ceci est sûr/officiel/stable ». Si vous les utilisez comme décoration, vous créez des garanties implicites.
  • Les tags enseignent « ce contenu appartient à un cluster de sens ». Si les tags sont inconsistants, la recherche devient du folklore.
  • Les boutons Copier enseignent « vous pouvez faire confiance aux commandes copiées ». Si cette confiance est rompue une fois, elle est brisée pour toujours.

Modes de défaillance à considérer comme inévitables

Ce ne sont pas des théories. J’ai vu chacun coûter du temps d’incident réel :

  • Pollution par les invites : le bouton Copier inclut cr0x@server:~$ ; collé dans un script ; le script échoue ; l’on-call perd 20 minutes.
  • Caractères invisibles : espace insécable dans un jeton de code inline ; copie/coller échoue ; l’utilisateur blâme l’outil.
  • Mauvaises interprétations de badges : un badge « Recommended » interprété comme « Supported » ; des équipes déploient ; la sécurité plus tard déclare « nous n’avons jamais approuvé ça ».
  • Discordance clavier : afficher Ctrl pour macOS ; les lecteurs appuient la mauvaise touche ; ils supposent que la fonctionnalité est en panne.
  • Dérive de police de code : le code inline utilise une police proportionnelle ; l, I et 1 deviennent un jeu de devinettes.

Idée paraphrasée de Ben Treynor Sloss (Google SRE) : la fiabilité est une fonctionnalité, et vous devez la prioriser. Votre UI de docs fait partie de la fiabilité, car elle détermine si les humains peuvent exécuter les bonnes actions sous pression.

Blague #1 : Un bouton Copier qui copie l’invite, c’est comme une ceinture de sécurité qui devient parfois une écharpe. Techniquement du tissu, pratiquement le chaos.

Playbook de diagnostic rapide : trouver le goulot en quelques minutes

Vous avez des plaintes : « la copie ne fonctionne pas », « kbd a l’air bizarre », « les badges confondent les gens ». N’ouvrez pas Figma tout de suite. Diagnostiquez comme un SRE.

Première étape : confirmer l’échec réel

  1. Reproduire avec un seul chemin utilisateur réel : mobile Safari + desktop Chrome + une passe avec lecteur d’écran.
  2. Capturer la charge copiée : confirmer si des caractères invisibles, des invites ou des retours sont inclus.
  3. Vérifier la sémantique du DOM : utilisez-vous de vrais <kbd> et <code>, ou un <span class="code"> qui fait semblant ?

Deuxième étape : identifier si c’est un problème CSS/JS/build

  1. Problème CSS : le composant s’affiche mal mais le comportement fonctionne. Vérifiez les styles calculés, le mode sombre, le chargement des polices et les guerres de spécificité.
  2. Problème JS : le bouton Copier ne copie pas, copie un contenu périmé ou échoue sous CSP. Vérifiez les erreurs console, les permissions et le chemin de repli.
  3. Problème de build/contenu : le renderer Markdown enveloppe les invites, échappe ou normalise les espaces. Vérifiez la chaîne et les sanitizers.

Troisième étape : décider la classe de correction

  • Hotfix quand les utilisateurs copient de mauvaises commandes : ajoutez un strip des invites, mettez à jour la logique du presse-papiers, shippez maintenant.
  • Renforcement quand c’est surtout esthétique mais source de confusion : unifier les jetons, ajouter des tests, imposer du linting.
  • Refonte quand la sémantique est fausse : passez à des éléments HTML natifs et des patterns accessibles.

L’élément <kbd> : le sérum de vérité du clavier

<kbd> est un de ces éléments HTML que l’on redécouvre tous les quelques années, comme un outil qu’on possède déjà mais qu’on continue à louer. Utilisez-le chaque fois que vous indiquez des appuis de touches. Il est sémantique, stylable et compatible avec les lecteurs d’écran lorsqu’il est employé correctement.

Quand utiliser <kbd> vs le code inline

  • Utilisez <kbd> pour les touches et raccourcis : Ctrl + C, Shift + ?.
  • Utilisez <code> pour les jetons littéraux : systemctl, --help, /etc/ssh/sshd_config.
  • N’utilisez pas le code inline pour les touches du clavier. Les lecteurs interprètent le code comme du texte à copier, pas comme une action à presser.

Comment <kbd> échoue dans la documentation réelle

  • Discordance de plateforme : afficher Ctrl sur macOS alors que les gens s’attendent à (Command). Correction : rendu conditionnel ou affichage double.
  • Raccourcis imbriqués : <kbd>Ctrl + C</kbd> est moins accessible que des touches séparées. Mieux : Ctrl+C.
  • Surtailoring : vous ajoutez de lourdes ombres et dégradés ; cela ressemble à un bouton cliquable ; les utilisateurs cliquent et rien ne se passe.

Règles opinionées

  • Gardez le style de kbd subtil : bord, fond, petit padding, monospace optionnel.
  • Utilisez des séparateurs cohérents : je préfère le + sans espaces avoisinants pour la compacité : Ctrl+C.
  • N’inventez pas de noms de touches : utilisez Esc et non « Touche Échap ». Utilisez Enter et non « Retour » sauf si c’est spécifique à la plateforme.

Code inline : typographie, sémantique et sécurité de la copie

Le code inline est l’endroit où l’écriture technique gagne ou perd la confiance. Il indique au lecteur : « cette chaîne exacte a de l’importance ». Si votre code inline est visuellement faible, il se lit comme de l’emphase. S’il est trop voyant, il se lit comme une erreur. Visez le « précis et calme ».

Le code inline doit se comporter comme une somme de contrôle

Le lecteur doit pouvoir jeter un coup d’œil à un jeton inline et savoir qu’il est exact. Cela signifie :

  • Une police monospace avec des glyphes clairs (1 vs l vs I).
  • Un fond et une bordure cohérents qui fonctionnent en mode sombre.
  • Pas de saut de ligne à l’intérieur des jetons à moins que vous n’autorisiez délibérément le wrapping (dans ce cas, ajoutez des règles word-break).

Échec typique : « ponctuation intelligente » et moteurs typographiques

Beaucoup de pipelines appliquent des substitutions typographiques : guillemets courbes, tirets longs, espaces insécables. En prose, c’est acceptable. Dans des commandes, c’est saboteur. Votre renderer devrait :

  • Désactiver la ponctuation intelligente à l’intérieur de <code> et <pre>.
  • Conserver exactement les caractères ASCII.
  • Normaliser les fins de ligne (LF) si votre bouton Copier cible des terminaux.

Badges : statut, risque et le danger des promesses implicites

Les badges sont de petites étiquettes avec une autorité disproportionnée. Ils ont l’air officiels même quand ils ne le sont pas. C’est pourquoi le marketing produit les adore — et pourquoi les équipes ops doivent se montrer suspicieuses.

Les bons badges répondent à une seule question chacun

  • Statut : Stable, Beta, Deprecated.
  • Portée : Linux-only, macOS-only, Kubernetes.
  • Risque : Destructive, Requires root.
  • Conformité : Approved, Needs review (attention : implique une gouvernance).

Badges à éviter

  • Badges d’ambiance : « Awesome », « Hot », « Trending ». Ça appartient aux réseaux sociaux, pas aux runbooks.
  • Badges ambigus : « Recommended » sans politique derrière. Recommandé par qui, sous quelles contraintes, avec quel plan de rollback ?
  • Sémantique basée uniquement sur la couleur : rouge/vert sans texte. L’accessibilité et les utilisateurs internationaux vous sanctionneront en silence.

Rendre la signification des badges vérifiable

Un badge doit correspondre à une règle testable. Exemple : « Deprecated » signifie que la page inclut un lien de remplacement et une date de dépréciation (ou au moins une version). « Destructive » signifie que le bloc de commande inclut une ligne « ce que cela change » et une alternative en dry-run.

Tags : navigation, intention de recherche et ne pas mentir au lecteur

Les tags sont soit un système d’indexation calme, soit un tiroir à bazar. La plupart des sites choisissent le tiroir à bazar et se demandent ensuite pourquoi la recherche et la découverte sont misérables.

Les tags doivent correspondre à la façon dont les gens cherchent

Les utilisateurs ne cherchent pas « observability ». Ils cherchent « pourquoi kubectl port-forward bloque » ou « bouton copier ne marche pas safari ». Utilisez des tags en plusieurs mots qui ressemblent à des requêtes, et gardez un vocabulaire contrôlé.

Deux choses différentes que l’on appelle « tags »

  • Tags de taxonomie de contenu : utilisés pour la navigation, les posts associés, le filtrage. Nécessitent une gouvernance.
  • Pastilles/labels inline : utilisés à l’intérieur de la page comme métadonnées. Nécessitent de la clarté, pas du volume.

Règle opérationnelle : garder l’ensemble de tags petit et soigné

Si n’importe qui peut inventer des tags, il le fera. Et alors vos tags « Kubernetes », « k8s », « kube » et « K8s » auront chacun cinq posts, aucun trouvé par le lecteur. Canonicalisez les tags au moment du build. Si vous ne pouvez pas imposer, ne faites pas semblant.

Boutons Copier : le couteau le plus tranchant dans votre tiroir

Le bouton Copier est un multiplicateur de force. Il fait gagner du temps et réduit les erreurs de transcription. Il permet aussi aux gens d’exécuter des commandes qu’ils ne comprennent pas plus vite qu’ils ne peuvent le regretter. Votre travail est donc de rendre la charge copiée correcte, sûre et explicite.

Ce qu’un bon bouton Copier garantit

  • Contenu exact : pas d’invites, pas de numéros de ligne, pas de caractères cachés.
  • Périmètre clair : copie un seul bloc de code, pas le texte environnant.
  • Retour visuel : état « Copié » qui n’est pas seulement basé sur la couleur et qui ne change pas la mise en page.
  • Fallback : fonctionne sans Clipboard API quand il est bloqué ; au minimum propose la sélection manuelle à copier.
  • Télémétrie : vous pouvez mesurer l’usage et les échecs sans journaliser la commande elle-même.

Gestion des invites : décidez votre politique

Choisissez-en une. Documentez-la. Faites-la respecter.

  • Pas d’invites dans les blocs copiables : affichez les invites visuellement via des pseudo-éléments CSS, pas dans le texte. Meilleur pour la fiabilité.
  • Invites autorisées mais retirées à la copie : la logique de copie supprime les $, # et motifs d’invite courants. Plus complexe, plus fragile.
  • Invites incluses : acceptable seulement pour des « terminaux pédagogiques » où l’invite fait partie de la leçon, et vous le signalez clairement (« pas directement copiable »).

Sécurité du presse-papiers : ne soyez pas intrusif

Copier dans le presse-papiers est une action privilégiée en pratique. Les navigateurs la restreignent derrière des gestes utilisateurs pour une raison. Votre code de copie doit :

  • Ne s’exécuter que sur un clic/tap, pas au chargement de la page ou au survol.
  • Ne jamais réécrire le presse-papiers au défilement ou lors des changements de sélection.
  • Éviter de copier des secrets. Si votre documentation contient des tokens, vous avez déjà un problème plus large ; n’empirez pas la situation.

Blague #2 : Un bouton Copier qui échoue silencieusement est l’équivalent UI d’un contrôleur RAID qui clignote « trust me ». Tout va bien jusqu’à ce que ce ne soit pas du tout le cas.

Faits & contexte historique utilisables

  • HTML inclut <kbd> depuis les premières spécifications, destiné aux exemples d’entrée utilisateur ; ce n’est pas une invention moderne, juste un élément souvent ignoré.
  • « Copier dans le presse-papiers » était auparavant un bricolage à l’époque Flash sur de nombreux sites ; la Clipboard API moderne a remplacé un tas de contournements peu sûrs.
  • Les polices monospace varient énormément en clarté de glyphes ; certaines polices populaires pour développeurs rendent encore O et 0 trop similaires, ce qui importe pour le code inline.
  • Les terminaux ont normalisé l’idée d’invites ($ pour l’utilisateur, # pour root), mais il n’existe pas de format d’invite universel, donc supprimer les invites est par nature heuristique.
  • Les espaces insécables ont été introduits pour la typographie, pas pour le code ; ils s’infiltrent régulièrement dans le code inline via des éditeurs WYSIWYG et peuvent casser l’analyse shell.
  • Les blocs de code délimités en Markdown ont popularisé le pattern du « snippet copiable », mais les renderers Markdown diffèrent sur la préservation des espaces et l’échappement HTML.
  • Les badges ont explosé avec la culture README ; avec le temps ils sont passés de signaux de statut à décoration, réduisant la confiance dans le signal.
  • La notation des raccourcis clavier est culturellement inconsistante : macOS utilise des symboles (⌘, ⌥), Windows utilise des mots (Ctrl, Alt). Vos docs ont besoin d’une politique, pas d’espoir.

Trois mini-histoires d’entreprise (comment cela tourne mal en vrai)

1) Incident causé par une mauvaise hypothèse : « copier copie la commande »

Une entreprise SaaS de taille moyenne a déployé un nouveau portail interne de runbooks. Il avait un composant de bloc de code élégant avec un bouton Copier et un style d’invite « shell ». La direction engineering était satisfaite : moins de fautes de frappe, mitigation plus rapide, moins de temps de formation.

L’hypothèse erronée était subtile : l’équipe UI a supposé que l’invite était « présentation », alors ils l’ont mise directement dans le texte du bloc de code. Ça s’affichait magnifiquement. Et le bouton Copier a copié tout le bloc, invites incluses.

Pendant un incident, un ingénieur on-call a copié une commande de mitigation dans un shell root sur un hôte production. La ligne collée commençait par cr0x@server:~$, que le shell a interprété comme un nom de commande. La mitigation a échoué. Ils ont réessayé, même échec, et ont commencé à déboguer le service au lieu du runbook.

Pendant ce temps, le timer d’incident s’en fichait. L’équipe a perdu des minutes précieuses, escaladé inutilement, et n’a remarqué le déchet d’invite dans l’historique du terminal que plus tard. Le postmortem a été gênant parce que personne ne voulait admettre « l’UI docs a cassé la prod ». Pourtant c’est ce qui s’est passé.

La correction a été ennuyeuse et immédiate : les invites sont devenues des pseudo-éléments CSS ; la charge copiée est devenue le texte brut de la commande uniquement ; et chaque bloc de code a gagné une ligne « Tested on: bash ». La correction plus vaste a été culturelle : l’UI de runbook a été traitée comme un système de production avec des tests de régression.

2) Optimisation contre-productive : « livrer moins d’octets, livrer moins de confiance »

Une grande plateforme documentaire d’entreprise a décidé d’optimiser les performances. Ils ont remplacé les blocs de code rendus côté serveur par un composant client qui s’hydrate après le chargement de la page. Objectif : HTML plus léger, premier rendu plus rapide, blocs de code interactifs avec badges et actions Copier.

Ça avait l’air bien dans les tests synthétiques. Le problème était la réalité utilisateur : navigateurs d’entreprise avec une Content Security Policy stricte, permissions presse-papiers verrouillées et bloqueurs de scripts agressifs. L’hydratation échouait fréquemment ou était retardée.

Les utilisateurs voyaient des blocs de code sans bouton Copier, puis des boutons apparaissaient tard, puis disparaissaient à la navigation parce que le routeur SPA réutilisait mal les nœuds. Certains ont copié des commandes obsolètes d’une page précédente parce que le handler de copie référençait un ancien id DOM. C’est le genre de bug qui n’apparaît pas dans les tests unitaires ; il apparaît dans « pourquoi avons-nous exécuté cette commande sur le mauvais cluster ».

Finalement la plateforme est revenue à des blocs de code rendus serveur avec amélioration progressive : le code est toujours présent, toujours sélectionnable, et le bouton Copier est une amélioration, pas une dépendance. L’« optimisation » a économisé des kilo-octets et dépensé de la crédibilité. Ce n’est pas un échange que vous pouvez gagner.

3) Pratique ennuyeuse mais correcte qui a sauvé la mise : règles de lint et tests dorés

Une petite équipe maintenait des runbooks pour une plateforme de stockage. Ce n’était pas tape-à-l’œil. L’UI était sobre. Mais ils avaient une pipeline de build impitoyable : chaque pull request lançait un linter qui rejetait le code inline contenant des espaces non-ASCII et rejetait les blocs de code commençant par des invites sauf s’ils étaient explicitement marqués « terminal transcript ».

Les gens se sont plaints au début. Les rédacteurs voulaient coller depuis les terminaux. Les ingénieurs voulaient aller vite. Le linter était l’ami agaçant qui vérifie toujours votre travail.

Puis un vrai incident a frappé : une panne étendue avec des dizaines de répondants sur différents fuseaux horaires. Ils copiaient des commandes de mitigation sous stress. Les runbooks ont fonctionné : les boutons Copier ont copié exactement les commandes, pas d’invites, pas de surprises de formatage, pas de « pourquoi ça a inséré un guillemet courbe ».

L’équipe a réalisé plus tard qu’elle avait évité toute une classe d’échecs non pas parce qu’elle était plus intelligente, mais parce qu’elle avait des garde-fous. La pratique était ennuyeuse. Elle était aussi correcte. En ops, l’ennuyeux est une réussite.

Tâches pratiques : 14 vérifications avec commandes, sorties et décisions

Ces tâches supposent que vous exploitez un site de docs ou un blog en production (générateur de site statique, CDN, peut-être un service Node). L’objectif n’est pas la pile exacte. L’objectif est : vous pouvez vérifier le comportement des micro-composants de la même façon que vous vérifiez la latence de stockage — en observant de vrais artefacts.

Task 1: Confirm the copy payload contains no prompt markers

cr0x@server:~$ node -e 'const s="cr0x@server:~$ sudo systemctl restart nginx\n"; console.log(s.replace(/^.*\$\s+/gm,""))'
sudo systemctl restart nginx

Ce que signifie la sortie : L’expression régulière de suppression d’invite a enlevé tout jusqu’à $ en début de ligne.

Décision : Si votre UI inclut des invites dans le texte du code, implémentez une politique fiable « strip on copy » ou cessez d’embarquer les invites dans la source copiée.

Task 2: Detect non-breaking spaces in exported HTML

cr0x@server:~$ grep -RIn --binary-files=without-match $'\xC2\xA0' public/ | head
public/posts/storage-runbook/index.html:842:Use zpool status before changes.

Ce que signifie la sortie : La sortie montre un espace insécable dans un jeton de code inline.

Décision : Corrigez le pipeline de contenu : remplacez NBSP par un espace ASCII à l’intérieur du code, et ajoutez une porte de build qui échoue sur ce motif.

Task 3: Verify that inline code is actually <code> elements

cr0x@server:~$ rg -n "kubectl get pods

Ce que signifie la sortie : Votre renderer produit de faux spans de code.

Décision : Passez à des <code> sémantiques afin que les outils d’accessibilité et le CSS puissent les traiter correctement. Les faux spans de code favorisent les incohérences.

Task 4: Ensure code blocks keep whitespace exactly

cr0x@server:~$ python3 - <<'PY'
s = "echo one\n\tprintf 'two'\n"
print(repr(s))
PY
"echo one\n\tprintf 'two'\n"

Ce que signifie la sortie : Les tabulations et retours sont explicites. Votre composant de bloc de code doit les préserver ; certains renderers convertissent les tabulations en espaces de façon inconsistante.

Décision : Si vous voyez des tabulations dans des exemples de code, imposez des espaces ou assurez-vous que votre renderer et la logique de copie préservent exactement les tabulations.

Task 5: Check for curly quotes and en-dashes in code samples

cr0x@server:~$ rg -n "[\u2018\u2019\u201C\u201D\u2013\u2014]" content/ | head
content/posts/ssh-hardening.md:57:Run: `ssh –V` and verify output

Ce que signifie la sortie : Ce tiret est un en-dash, pas un trait d’union. Les flags shell échoueront.

Décision : Ajoutez une règle de linter : rejetez la ponctuation intelligente à l’intérieur des backticks et des fenced blocks. Corrigez le contenu source.

Task 6: Validate that copy buttons exist only where intended

cr0x@server:~$ rg -n "data-copy-button" public/ | wc -l
128

Ce que signifie la sortie : Vous avez 128 instances. C’est votre inventaire.

Décision : Si ce nombre augmente de façon inattendue lors d’une release, vous avez probablement modifié un template et ajouté des boutons Copier à des snippets non destinés (fragments JSON, traces de stack, etc.). Décidez si c’est souhaitable.

Task 7: Confirm Clipboard API usage is gated behind user gesture

cr0x@server:~$ rg -n "navigator\.clipboard\.writeText" assets/ | head
assets/js/copy.js:41:await navigator.clipboard.writeText(text)

Ce que signifie la sortie : Vous avez trouvé le site d’appel.

Décision : Inspectez ce handler : il doit être dans un callback de clic/tap. S’il est dans un événement load, vous aurez des échecs et possiblement des avertissements de sécurité.

Task 8: Check CSP headers for clipboard compatibility and inline script breakage

cr0x@server:~$ curl -sI https://docs.example.internal | sed -n '1,20p'
HTTP/2 200
content-security-policy: default-src 'self'; script-src 'self'; object-src 'none'; base-uri 'self'
content-type: text/html; charset=utf-8

Ce que signifie la sortie : Les scripts ne peuvent charger que depuis self. Les scripts inline seront bloqués sauf si vous utilisez des nonces/hashes.

Décision : Si votre bouton Copier dépend d’un JS inline, il cassera dans cet environnement. Livrez la logique de copie comme un fichier externe ou utilisez des nonces CSP.

Task 9: Verify your site serves the correct code font assets (and doesn’t 404)

cr0x@server:~$ curl -sI https://docs.example.internal/assets/fonts/JetBrainsMono.woff2 | head -n 5
HTTP/2 200
content-type: font/woff2
cache-control: public, max-age=31536000, immutable

Ce que signifie la sortie : La police se charge et est cacheable.

Décision : Si vous voyez 404 ou de mauvais types MIME, votre code inline retombera sur des polices système de façon imprévisible. Corrigez le build ou la configuration CDN.

Task 10: Measure whether your copy script is a performance anchor

cr0x@server:~$ ls -lh public/assets/js/ | rg "copy|code|highlight"
-rw-r--r--  1 cr0x cr0x  3.2K Jan 10 12:11 copy.js
-rw-r--r--  1 cr0x cr0x  188K Jan 10 12:11 highlight.js

Ce que signifie la sortie : Le highlighting fait 188K ; la logique de copie fait 3.2K.

Décision : N’imbriquez pas la logique de copie dans un gros runtime de highlighting si vous pouvez l’éviter. Livrez la copie comme une petite amélioration progressive, et chargez le highlighting seulement quand nécessaire.

Task 11: Catch duplicate or inconsistent tags in your taxonomy

cr0x@server:~$ jq -r '.posts[].tags[]' public/search-index.json | sort | uniq -c | sort -nr | head
  42 kubernetes troubleshooting
  17 k8s troubleshooting
  11 Kubernetes troubleshooting

Ce que signifie la sortie : Vous avez trois variantes pour le même concept, y compris des différences de casse.

Décision : Canonicalisez les tags au moment du build. Choisissez une forme (minuscules, tags multi-mots ressemblant à des requêtes) et réécrivez les autres.

Task 12: Confirm badges map to known states (not free text)

cr0x@server:~$ jq -r '.posts[].badges[]?' public/search-index.json | sort | uniq -c | sort -nr
  59 stable
  14 beta
   7 recommended
   3 Stable
   2 hot

Ce que signifie la sortie : « Stable » duplique « stable », et vous avez « hot », qui n’est pas un état, c’est une humeur.

Décision : Verrouillez les valeurs de badge dans une énumération. Si quelqu’un veut un nouveau badge, il le propose comme un changement de schéma, pas comme un tweet.

Task 13: Verify that terminal transcript blocks are labeled and not copyable by default

cr0x@server:~$ rg -n "terminal-transcript" public/ | head
public/posts/mysql-recovery/index.html:411:
cr0x@server:~$ tail -n 50 /var/log/mysql/error.log
...

Ce que signifie la sortie : Les blocs de transcript sont classifiés.

Décision : Si c’est une transcription, envisagez de désactiver la copie ou de copier uniquement les lignes de commande (pas la sortie). Rendre l’UI explicite.

Task 14: Spot prompt strings inside code blocks that claim to be copyable

cr0x@server:~$ rg -n "^\w+@[^:]+:.*\\$ " content/ | head
content/runbooks/restart-nginx.md:12:cr0x@server:~$ sudo systemctl restart nginx

Ce que signifie la sortie : Le runbook inclut une ligne d’invite littérale dans le contenu source.

Décision : Convertissez-la en code sans invite (préféré) ou marquez le bloc comme transcript et ajustez le comportement de copie. Ne laissez pas cela ambigu.

Erreurs courantes : symptômes → cause racine → correction

1) Symptom: Users paste commands and get “command not found” with their username

Cause racine : Le texte d’invite est inclus dans la charge copiée (soit parce que les invites sont du texte littéral, soit parce que les numéros de ligne sont copiés).

Correction : Rendre les invites via des pseudo-éléments CSS, ou supprimer les invites à la copie avec des règles conservatrices. Ajoutez un test qui simule la copie et affirme que la charge commence par la commande.

2) Symptom: Copy works in Chrome but not in locked-down corporate browsers

Cause racine : CSP bloque les scripts inline ou les appels clipboard ; ou les permissions clipboard exigent HTTPS et un geste utilisateur.

Correction : Livrez la logique de copie comme un JS externe autorisé par la CSP ; assurez-vous que la copie ne se déclenche que sur clic ; implémentez un fallback : sélectionner le texte + indiquer à l’utilisateur d’appuyer sur Ctrl+C.

3) Symptom: Inline flags like --max-time render as –max–time

Cause racine : Le moteur de ponctuation intelligente transforme les tirets en en-dashes et les doubles tirets en em-dash dans certains éditeurs.

Correction : Désactivez les substitutions typographiques à l’intérieur des spans et fences de code ; ajoutez des règles de lint pour rejeter les caractères unicode de tiret dans les contextes de code.

4) Symptom: Keyboard shortcuts are misunderstood across OSes

Cause racine : Une seule notation de raccourci est utilisée universellement ; les utilisateurs macOS attendent des symboles, Windows/Linux des mots.

Correction : Fournissez un rendu spécifique à l’OS ou une notation double : Ctrl (Windows/Linux) / (macOS). Si vous ne pouvez pas, au moins étiquetez la plateforme explicitement.

5) Symptom: Badges create escalation loops (“security approved this, right?”)

Cause racine : Les badges impliquent une gouvernance sans politique solide. Les lecteurs interprètent l’autorité de l’UI comme une autorité organisationnelle.

Correction : Utilisez des badges uniquement pour des états que vous pouvez appliquer et expliquer. Ajoutez un tooltip ou une légende qui définit chaque badge en langage clair.

6) Symptom: Tags don’t improve discovery; they fragment it

Cause racine : Tags en libre-service, casse inconsistante, synonymes et quasi-duplicatas.

Correction : Dictionnaire de tags canonical, appliqué au build ; migrez les anciens tags ; traitez les changements de taxonomie comme des migrations de schéma.

7) Symptom: Copying multi-line commands breaks because line continuations get lost

Cause racine : Le renderer enveloppe les lignes visuellement mais altère les espaces, ou copie des artefacts de soft-wrap, ou insère des retours au milieu des jetons.

Correction : Assurez-vous que <pre> utilise de vrais retours à la ligne ; évitez d’insérer des <br> dans le code ; copiez depuis le textContent de l’élément <code>, pas depuis un clone stylé.

8) Symptom: Dark mode makes inline code unreadable

Cause racine : Les couleurs de fond/bordure du code inline sont réglées uniquement pour le thème clair ; le contraste est insuffisant.

Correction : Définissez des tokens de thème pour le fond, la bordure et le texte du code ; exécutez des vérifications de contraste ; gardez le code inline subtil mais lisible.

Listes de contrôle / plan étape par étape

Étape par étape : livrer des « blocs de code de confiance » en une semaine

  1. Choisir une politique pour les invites : pas d’invites dans la source copiée (recommandé) ou strip-on-copy (acceptable avec des tests).
  2. Standardiser la sémantique : les jetons inline utilisent <code> ; les raccourcis utilisent <kbd> ; les blocs de code utilisent <pre><code>.
  3. Implémenter le comportement de copie :
    • Copier depuis le textContent brut de l’élément <code>.
    • Normaliser les fins de ligne vers \n.
    • Éventuellement supprimer une seule newline finale (être cohérent).
  4. Ajouter une affordance UI : bouton « Copier » avec un état « Copié » qui ne shift pas la mise en page et un feed aria-live.
  5. Ajouter un fallback : comportement de sélectionner-tout ou instruction affichant Ctrl+C / +C.
  6. Télémétrie, mais pas intrusive : logger « copy attempted », « copy succeeded », « copy failed », par page et id de bloc — pas le contenu de la commande.
  7. Lint du contenu :
    • Rejeter NBSP et guillemets/tirets intelligents à l’intérieur des contextes de code.
    • Rejeter les invites dans les fenced blocks non marqués comme transcript.
  8. Tests de régression : tests dorés sur le HTML rendu pour des pages représentatives ; un test navigateur qui clique sur Copier et vérifie la charge du presse-papiers.
  9. Rédiger une légende pour les badges et la politique de tags : ce que signifie chaque badge, qui en est responsable, et ce que « Deprecated » exige.

Checklist : badges et tags que vous pouvez défendre en postmortem

  • Chaque valeur de badge est dans une liste contrôlée.
  • Chaque badge a une signification définie et un propriétaire.
  • « Deprecated » exige une référence de remplacement et une déclaration de calendrier.
  • Les tags sont canonicalisés (casse, espacement) et mappés depuis des synonymes.
  • Le jeu de tags est suffisamment petit pour qu’un humain puisse reconnaître les doublons.

Checklist : vérifications d’accessibilité

  • <kbd> n’est pas utilisé pour des choses qui ne sont pas des touches.
  • Le bouton Copier est accessible au clavier et possède un état de focus visible.
  • La confirmation de copie est annoncée via aria-live et pas seulement par la couleur.
  • Les badges ne sont pas communiqués par la couleur seule ; du texte est présent.
  • Le code inline a un contraste suffisant en mode clair et sombre.

FAQ

1) Dois-je utiliser <kbd> pour les touches simples et les raccourcis ?

Oui. Utilisez <kbd> pour les touches, et composez des raccourcis avec plusieurs éléments <kbd> : Ctrl+C. C’est plus clair et plus accessible.

2) Est-il acceptable d’afficher des invites dans les blocs de code ?

Seulement si vous traitez le bloc comme une transcription et le marquez comme tel. Pour les snippets de commande copiables, les invites doivent être uniquement de présentation (CSS) ou supprimées à la copie avec des tests.

3) Pourquoi ne pas toujours supprimer les invites à la copie ?

Parce que les formats d’invite varient et que les heuristiques finiront par mâcher une commande légitime (surtout quand des commandes commencent par $ dans des exemples, ou quand la sortie contient des motifs similaires). Si vous pouvez éviter les invites dans la source, faites-le.

4) Le code inline doit-il se couper sur les petits écrans ?

Parfois. Les chemins et flags longs peuvent déborder. Utilisez du CSS pour autoriser un wrapping sûr pour les jetons longs tout en préservant la correction de copie. Si le wrapping risque de casser le sens, empêchez-le et autorisez le scroll horizontal.

5) Les boutons Copier ont-ils besoin de télémétrie ?

Si vous vous souciez de la fiabilité, oui. Mesurez tentatives/succès/échecs par page et par bloc. Ne journalisez pas la chaîne copiée. Vous voulez des taux et des modes d’échec, pas le contenu.

6) Quel est le caractère invisible le plus courant qui casse les commandes ?

L’espace insécable. Il ressemble à un espace, mais les shells ne le traitent pas comme un séparateur. Les tirets intelligents et les guillemets courbes sont de bons candidats proches.

7) Combien de badges, c’est trop ?

Si une page a plus de deux ou trois badges, vous encodez probablement un paragraphe de nuance en confettis. Mettez la nuance dans le texte ; réservez les badges aux états à fort signal.

8) Les tags valent-ils encore la peine quand la recherche full-text existe ?

Oui, si vous les gouvernez. Les tags sont un index opinionné ; la recherche est une supposition. Les tags aident les utilisateurs à restreindre le périmètre (« commandes uniquement linux ») et à trouver des contextes opérationnels liés.

9) Ai-je besoin d’une notation différente pour les raccourcis clavier sur macOS ?

Idéalement oui. À minima, étiquetez la plateforme. Le mieux est une notation double ou un rendu adapté à l’OS pour que l’utilisateur n’ait pas à traduire mentalement.

10) Dois-je utiliser le highlighting syntaxique partout ?

Non. Le highlighting est coûteux et souvent inutile pour des commandes sur une seule ligne. Utilisez-le là où il ajoute du sens (configs, code), et gardez les commandes shell propres et copiables.

Conclusion : étapes suivantes à livrer cette semaine

Les micro-composants ne ressemblent pas à « la production », ce qui explique précisément pourquoi ils causent silencieusement des problèmes en production. Les corriger n’est pas un projet de redesign. C’est du travail de fiabilité : resserrer la sémantique, supprimer l’ambiguïté, ajouter des garde-fous, mesurer les résultats.

  1. Auditer le comportement de copie sur vos 20 pages principales : confirmez que la charge du presse-papiers est sans invite et que les espaces sont corrects.
  2. Imposer du linting de contenu pour NBSP et la ponctuation intelligente dans les contextes de code. Faites échouer les builds. Oui, des gens se plaindront. Laissez-les se plaindre maintenant plutôt que pendant un incident.
  3. Définir la gouvernance des badges et tags : vocabulaires contrôlés, propriétaires et significations. Si vous ne pouvez pas définir la signification, supprimez le badge.
  4. Rendre l’accessibilité non-optionnelle : vrai <kbd>, vrai <code>, boutons Copier accessibles au clavier et états de focus visibles.
  5. Ajouter un test navigateur qui clique sur Copier et vérifie la chaîne du presse-papiers. C’est l’assurance la moins chère que vous achèterez ce trimestre.

Faites cela, et vos docs cesseront d’être « du joli texte sur Internet » pour devenir ce qu’elles devraient être : un panneau de commande opérationnel qui ne ment pas quand la salle est en feu.

← Précédent
CLUF que personne ne lit : le contrat que tout le monde signe
Suivant →
Modifications DNS non visibles : quels caches vider (et lesquels ne pas toucher

Laisser un commentaire