Manipuler SVG avec Claude Code : guide pratique
Guide SVG avec Claude Code : viewBox, ic?nes accessibles, currentColor, animations, optimisation SVGO et pi?ges de s?curit?.
Avant de demander un SVG ? Claude Code
SVG est pratique pour les ic?nes, les logos, les schemas et les petites visualisations de donn?es. Le format reste net ? toutes les tailles et peut heriter des couleurs CSS. Claude Code peut lire le d?p?t, modifier les fichiers et lancer des contr?les, ce qui en fait un bon outil pour transformer des exports SVG en composants fiables.
Le risque vient des demandes trop vagues. “Fais-moi une ic?ne SVG” peut produire un r?sultat joli mais fragile: pas de viewBox, couleurs codees en dur, nom accessible absent, animation trop agressive ou optimisation qui casse le redimensionnement. Masa l’a constate dans une petite interface de test ClaudeCodeLab: l’ic?ne ?tait correcte visuellement, mais elle devait ?tre modifiee a la main pour un bouton texte, un bouton ic?ne seul et le mode sombre.
Ce guide propose une base plus robuste: garder viewBox, utiliser currentColor, separer les ic?nes d?coratives des ic?nes porteuses de sens, ajouter une animation l?g?re et optimiser avec SVGO sans supprimer les attributs utiles. Les references officielles ? garder sous la main sont MDN <svg>, MDN viewBox, MDN role ARIA img, MDN aria-hidden, SVGO et la documentation Claude Code.
Le flux de travail
Un SVG de production n’est pas seulement un dessin. Il touche au syst?me de design, a l’accessibilit?, au poids de page, a la s?curit? et a la revue de code.
flowchart LR
A["D?finir le but"] --> B["Fixer viewBox"]
B --> C["Utiliser currentColor"]
C --> D["Choisir aria-label ou aria-hidden"]
D --> E["Int?grer en HTML ou React"]
E --> F["Optimiser avec SVGO"]
F --> G["V?rifier mise en page et s?curit?"]
Un bon prompt est concret: “Cr?e un composant d’ic?nes SVG avec viewBox="0 0 24 24", stroke="currentColor", ic?nes d?coratives avec aria-hidden, ic?nes seules avec role="img" et title, puis ajoute une configuration SVGO qui conserve viewBox.”
Inline SVG et viewBox
Inline SVG signifie que le balisage <svg> est place directement dans HTML ou JSX, au lieu d’?tre charge avec img. C’est utile quand l’ic?ne doit suivre une couleur, reagir au survol, recevoir des props React ou s’animer l?g?rement.
viewBox definit le syst?me de coordonn?es interne. MDN le decrit avec quatre nombres: min-x min-y width height. En version simple, viewBox="0 0 24 24" veut dire que le dessin est construit sur une grille de 24 par 24, m?me s’il est affiche en 16px, 24px ou 48px.
<button class="icon-button" type="button" aria-label="Rechercher">
<svg
class="icon"
viewBox="0 0 24 24"
width="24"
height="24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
aria-hidden="true"
focusable="false"
>
<circle cx="11" cy="11" r="7" />
<path d="M20 20l-4.5-4.5" />
</svg>
</button>
Ici, le bouton porte d?j? le nom accessible. Le SVG est donc d?coratif. Si le bouton ne contenait que l’ic?ne visible, le nom devrait ?tre sur le bouton. Si le SVG est une image autonome, le SVG doit recevoir son propre nom.
Theming avec currentColor et variables CSS
Les couleurs fixes dans le SVG compliquent la maintenance. Si un chemin contient fill="#111827", Claude Code devra modifier le SVG a chaque changement de theme. Pour les ic?nes d’interface, mieux vaut heriter de la couleur CSS.
:root {
--color-text: #172033;
--color-muted: #667085;
--color-accent: #0f766e;
--color-danger: #b42318;
}
[data-theme="dark"] {
--color-text: #eef2f7;
--color-muted: #a9b4c3;
--color-accent: #2dd4bf;
--color-danger: #f97066;
}
.icon {
color: var(--icon-color, var(--color-text));
display: inline-block;
inline-size: 1.25rem;
block-size: 1.25rem;
flex: 0 0 auto;
}
.icon-button {
color: var(--color-muted);
}
.icon-button:hover {
color: var(--color-accent);
}
.icon-button[data-variant="danger"] {
--icon-color: var(--color-danger);
}
<button class="icon-button" type="button" aria-label="Supprimer" data-variant="danger">
<svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" aria-hidden="true">
<path d="M4 7h16" />
<path d="M10 11v6" />
<path d="M14 11v6" />
<path d="M6 7l1 14h10l1-14" />
<path d="M9 7V4h6v3" />
</svg>
</button>
Apr?s la modification, demande ? Claude Code de lancer rg "fill=\"#|stroke=\"#" dans les composants et les assets. Les logos peuvent garder une couleur de marque, mais les ic?nes d’interface devraient utiliser currentColor.
Composant React accessible
Un SVG porteur de sens doit avoir un nom accessible. Un SVG d?coratif doit ?tre cache de l’arbre d’accessibilit?. MDN recommande role="img" avec un libelle pour les SVG embarques qui agissent comme une image, et aria-hidden="true" pour du contenu d?coratif non interactif.
import { useId } from "react";
type IconName = "search" | "check" | "close";
const paths: Record<IconName, string> = {
search: "M10.5 18a7.5 7.5 0 1 1 5.3-12.8 7.5 7.5 0 0 1-5.3 12.8Zm5.3-2.2L21 21",
check: "M5 12.5l4.5 4.5L19 7",
close: "M6 6l12 12M18 6L6 18",
};
type SvgIconProps = {
name: IconName;
title?: string;
d?corative?: boolean;
size?: number;
className?: string;
};
export function SvgIcon({
name,
title,
d?corative = false,
size = 24,
className,
}: SvgIconProps) {
const titleId = useId();
const isMeaningful = !d?corative && Boolean(title);
return (
<svg
className={className}
width={size}
height={size}
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth={2}
strokeLinecap="round"
strokeLinejoin="round"
role={isMeaningful ? "img" : undefined}
aria-labelledby={isMeaningful ? titleId : undefined}
aria-hidden={d?corative ? true : undefined}
focusable="false"
>
{isMeaningful ? <title id={titleId}>{title}</title> : null}
<path d={paths[name]} />
</svg>
);
}
<button type="button">
<SvgIcon name="check" d?corative />
Enregistrer
</button>
<SvgIcon name="search" title="Rechercher" />
Ne place pas aria-hidden="true" sur un ?l?ment qui peut recevoir le focus. Pour un bouton uniquement compose d’une ic?ne, nomme le bouton ou ajoute un texte visible.
Animation simple et stable
L’animation SVG doit rester discr?t?: chargement, validation, accent sur une valeur. Elle ne doit pas deplacer la mise en page et doit respecter prefers-reduced-motion.
<svg class="spinner" viewBox="0 0 48 48" width="48" height="48" role="img" aria-label="Chargement">
<circle class="spinner-track" cx="24" cy="24" r="20" />
<circle class="spinner-head" cx="24" cy="24" r="20" />
</svg>
.spinner {
color: #0f766e;
animation: spin 900ms linear infinite;
}
.spinner-track,
.spinner-head {
fill: none;
stroke-width: 4;
}
.spinner-track {
stroke: #d0d5dd;
}
.spinner-head {
stroke: currentColor;
stroke-linecap: round;
stroke-dasharray: 80 45;
}
@keyframes spin {
to {
transform: rotate(360deg);
}
}
@media (prefers-reduced-motion: reduce) {
.spinner {
animation: none;
}
}
Pour aller plus loin sur les mouvements CSS, lis aussi les animations CSS avancees avec Claude Code. SVG definit la forme; CSS definit l’?tat et le mouvement.
Petit graphique SVG
SVG peut g?n?rer un petit graphique sans biblioth?que lourde. Si les libelles viennent de donn?es externes, il faut les ?chapper avant de les placer dans <text>.
type BarDatum = {
label: string;
value: number;
};
function escapeXml(value: string): string {
return value.replace(/[<>&"']/g, (char) => {
const entities: Record<string, string> = {
"<": "<",
">": ">",
"&": "&",
'"': """,
"'": "'",
};
return entities[char];
});
}
export function createMiniBarChart(data: BarDatum[]): string {
const width = 420;
const height = 180;
const padding = 32;
const gap = 12;
const maxValue = Math.max(...data.map((item) => item.value), 1);
const barWidth = (width - padding * 2 - gap * (data.length - 1)) / data.length;
const bars = data
.map((item, index) => {
const barHeight = (item.value / maxValue) * 100;
const x = padding + index * (barWidth + gap);
const y = height - padding - barHeight;
return `
<rect x="${x}" y="${y}" width="${barWidth}" height="${barHeight}" rx="6" fill="currentColor" />
<text x="${x + barWidth / 2}" y="${height - 10}" text-anchor="middle" font-size="12">
${escapeXml(item.label)}
</text>`;
})
.join("");
return `<svg viewBox="0 0 ${width} ${height}" role="img" aria-label="Demandes mensuelles" xmlns="http://www.w3.org/2000/svg">
<g color="#0f766e">${bars}</g>
</svg>`;
}
Ce format convient a un mini tableau de bord, une illustration d’article ou une preuve sociale dans une page de vente. Pour axes, l?gendes, infobulles, zoom ou gros volumes, prends une biblioth?que de graphiques.
Optimisation avec SVGO
Les exports Figma ou Illustrator contiennent souvent des metadonn?es et des attributs inutiles. SVGO nettoie ces fichiers. Commence par une configuration prudente et inspecte les changements.
// svgo.config.mjs
export default {
multipass: true,
plugins: [
{
name: "preset-default",
params: {
overrides: {
cleanupIds: false
}
}
},
"removeDimensions",
{
name: "removeAttrs",
params: {
attrs: ["data-name"]
}
}
]
};
{
"scripts": {
"svg:optimize": "svgo --config svgo.config.mjs --folder src/assets/icons"
},
"devDependencies": {
"svgo": "^4.0.0"
}
}
SVGO documente preset-default, removeDimensions et les autres plugins. Attention ? removeViewBox: la documentation indique que ce plugin peut empecher le SVG de s’adapter a son conteneur et provoquer du rognage.
Cas d’usage et pieges
Les cas utiles sont nombreux: syst?me d’ic?nes produit, schemas pour articles techniques, visuels pres des prix et boutons d’achat, petits graphiques pour taux de lecture, clics CTA ou volume de demandes.
| Piege | Consequence | Correction |
|---|---|---|
Supprimer viewBox | Icone rognee ou non responsive | Le conserver dans SVGO |
| Couleurs fixes | Theme sombre et hover cassent | Utiliser currentColor |
| Cacher une ic?ne utile | Le lecteur d’?cran perd l’action | Nommer le bouton ou le SVG |
| Lire une ic?ne d?corative | Redondance vocale | Utiliser aria-hidden="true" |
| Inline d’un SVG uploadé | Risque de scripts ou evenements | Inline seulement pour SVG fiables |
| Ignorer reduced motion | Mouvement inconfortable | Utiliser prefers-reduced-motion |
MDN documente l’?l?ment SVG <script>, donc un SVG fourni par un utilisateur ne doit pas ?tre traite comme une simple image innocente. Claude Code peut aider a revoir le diff, mais limite le dossier cible et inspecte les changements. Pour les permissions et les commandes, consulte aussi la s?curit? Claude Code.
Prompt r?utilisable
Cr?e un syst?me d'ic?nes SVG pour ce d?p?t.
Contraintes:
- Conserver viewBox="0 0 24 24"
- Utiliser currentColor pour fill ou stroke
- Cacher les ic?nes d?coratives avec aria-hidden=true
- Utiliser role=img et title pour les ic?nes autonomes utiles
- Ajouter un SVG de chargement compatible prefers-reduced-motion
- Ajouter une configuration SVGO qui ne supprime pas viewBox
- Rapporter risques, fichiers modifies et commandes de verification
Pour la suite, relie ce travail ? l’optimisation de performance avec Claude Code, car chaque ic?ne, schema et animation finit par compter dans le poids de page.
CTA et r?sultat v?rifi?
Si tu veux un socle r?utilisable, regarde les produits et templates ClaudeCodeLab ou apporte un d?p?t reel en formation et conseil Claude Code. SVG est un bon premier chantier, car le perim?tre est petit mais touche design, accessibilit?, performance et revue.
Dans l’interface de test de Masa, passer les couleurs fixes a currentColor a permis d’utiliser les m?mes ic?nes en theme clair, theme sombre et boutons destructifs. Le vrai bug ?tait l’accessibilit?: un bouton de recherche uniquement compose d’une ic?ne a perdu son nom quand aria-hidden a ?t? applique partout. La regle finale est simple: nommer le bouton, et cacher seulement les ic?nes d?coratives.
PDF gratuit: cheatsheet Claude Code
Saisissez votre email et téléchargez une page avec commandes, habitudes de review et workflow sûr.
Nous protégeons vos données et n'envoyons pas de spam.
À propos de l'auteur
Masa
Ingénieur spécialisé dans les workflows pratiques avec Claude Code.
Articles liés
Échelle de sécurité des permissions Claude Code
Passer du read-only aux éditions limitées, preuves et checks de déploiement sans perdre le contrôle.
Claude Code Small PR Proof Pack : rendre les petits changements reviewables
Un pack de preuve pour PR Claude Code : diff, vérifications, URL publique, CTA et rollback.
Gate de review avant commit avec Claude Code
Review avant commit avec Claude Code : diff, build, URL publique, liens Gumroad, CTA consultation, tests manquants et fichiers hors scope.