aller au contenu principal
Parcourir la documentation

CSS personnalisé

L'issue de secours : restylez n'importe quelle surface du widget en CSS brut lorsque les contrôles de jetons du studio ne suffisent pas.

Les contrôles de jetons du Widget Design Studio couvrent l'essentiel des besoins de marque — ils restent conformes AA et survivent aux mises à jour du widget. Lorsqu'ils ne suffisent pas, chaque design comporte un champ CSS personnalisé (étape Général) : du CSS brut injecté dans le Shadow DOM du widget, ciblant les sélecteurs stables et les propriétés personnalisées --syncanix-* documentés sur cette page.

Comment il s'applique

Le CSS est validé pendant la saisie et revalidé côté serveur à l'enregistrement. Il prend effet lorsque vous enregistrez le design ; si ce design est celui en usage, les widgets intégrés récupèrent le changement lors de leur prochain chargement de configuration — en quelques minutes.

Une seule chaîne CSS par design : elle s'applique à toutes les tailles du widget et aux deux jeux de couleurs (délimitez les règles sombres avec le sélecteur ci-dessous), et les règles de thème par page ne portent jamais leur propre CSS personnalisé.

Votre CSS gagne la cascade

Le widget injecte votre CSS comme la dernière feuille de styles de son Shadow DOM, après tous les styles intégrés. Une règle de spécificité égale l'emporte donc sur celle du widget — pas besoin de !important pour un restylage ordinaire.

/* Does NOT work — tokens are applied inline on the host element,
   which beats any :host rule: */
:host { --syncanix-primary: #0f766e; }

/* Works — re-declare the variable on a descendant instead: */
.syncanix-panel { --syncanix-primary: #0f766e; }

Sélecteurs stables

Ces sélecteurs forment un contrat documenté et stable — verrouillé par des tests, si bien qu'une version du widget ne peut pas les renommer en silence.

/* Launcher (the closed floating button — an attribute, not a class) */
[data-syncanix='launcher']
.syncanix-launcher-avatar
.syncanix-launcher-brand

/* Panel chrome */
.syncanix-panel
.syncanix-panel-header

/* Messages */
.syncanix-panel-item-user
.syncanix-panel-item-assistant
.syncanix-msg-body

/* Composer */
.syncanix-panel-composer
.syncanix-panel-composer-form
.syncanix-panel-composer-input
.syncanix-panel-composer-submit
.syncanix-panel-composer-stop
.syncanix-panel-composer-limit

/* Rich primitives — each renders with its type on the root */
.syncanix-card
.syncanix-confirm-card
[data-syncanix-primitive='list' | 'table' | 'card' | 'markdown' | 'button'
  | 'detail' | 'form' | 'status' | 'empty-state' | 'confirm-card' | 'navigate'
  | 'component' | 'iframe' | 'action-plan' | 'action-in-progress'
  | 'action-result' | 'chart' | 'embed' | 'metric' | 'funnel' | 'flow'
  | 'sign-in-card' | 'onboarding-checklist']

Propriétés personnalisées

Chaque surface du widget se peint à partir de propriétés personnalisées --syncanix-* à espace de noms : redéclarer l'une d'elles sur un sous-arbre ne restyle que ce sous-arbre. L'attribut d'intégration data-theme accepte les mêmes noms de jetons — voir Thémer le widget pour la composition des couches de thème.

/* Colour */
--syncanix-primary            --syncanix-primary-foreground
--syncanix-background         --syncanix-foreground
--syncanix-muted              --syncanix-muted-foreground
--syncanix-border             --syncanix-ring
--syncanix-destructive        --syncanix-destructive-foreground
--syncanix-link

/* Typography */
--syncanix-font-family        --syncanix-font-family-heading
--syncanix-line-height-base   --syncanix-letter-spacing-base
--syncanix-measure

/* Shape */
--syncanix-radius             --syncanix-radius-sm
--syncanix-radius-md          --syncanix-radius-lg
--syncanix-radius-full        --syncanix-avatar-radius

/* Elevation, spacing, motion, icons */
--syncanix-shadow-lg          --syncanix-shadow-xl
--syncanix-spacing            --syncanix-spacing-sm
--syncanix-motion-duration    --syncanix-motion-easing
--syncanix-icon-stroke-width

/* Per-element studio overrides (set on a descendant to override locally) */
--syncanix-launcher-bg        --syncanix-launcher-fg
--syncanix-header-bg          --syncanix-header-fg
--syncanix-user-bubble-bg     --syncanix-user-bubble-fg
--syncanix-assistant-bubble-bg  --syncanix-assistant-bubble-fg
--syncanix-composer-bg        --syncanix-pane-bg
--syncanix-ai-font-family     --syncanix-user-font-family

Clair et sombre

Le jeu de couleurs résolu est estampillé sur l'hôte du widget en data-color-scheme. Votre CSS s'applique dans les deux jeux — délimitez les règles sombres avec :host([data-color-scheme='dark']).

.syncanix-panel-header { background: #f8fafc; }

:host([data-color-scheme='dark']) .syncanix-panel-header {
  background: #1e293b;
}

Ce qui est bloqué

Le CSS personnalisé est validé dans l'éditeur, à l'enregistrement, puis à nouveau dans le widget avant injection. Le validateur refuse :

  • @import — récupération ou exfiltration de CSS externe.
  • expression(), les URL javascript: et data:text/html, behavior:, -moz-binding — vecteurs hérités d'injection de script.
  • Les références url() externes — un vecteur de balise réseau / fuite de données. Intégrez les ressources (y compris les fichiers de polices) en URI data:.
  • Une balise de fermeture </style> — une échappée du Shadow DOM.
  • Masquer ou restyler la mention « réalisé avec l'IA » (sélecteurs syncanix-ai-* / syncanix-first-message-*) — une surface réglementaire verrouillée.
  • Plus de 64 Ko de CSS par design.

Exemples

/* A gradient panel header with a hairline divider */
.syncanix-panel-header {
  background: linear-gradient(135deg, #0f766e, #134e4a);
  border-block-end: 1px solid rgba(255, 255, 255, 0.12);
}
Restyler l'en-tête du panneau
/* Round only the cards, and give tables a tighter radius */
[data-syncanix-primitive='card'] { --syncanix-radius: 1rem; }
[data-syncanix-primitive='table'] { --syncanix-radius: 0.25rem; }
Surcharger un jeton pour une seule primitive
/* Slow the widget's motion down, and switch it off for
   reduced-motion visitors */
.syncanix-panel { --syncanix-motion-duration: 300ms; }

@media (prefers-reduced-motion: reduce) {
  .syncanix-panel { --syncanix-motion-duration: 0ms; }
}
Régler le mouvement en respectant reduced-motion

Étapes suivantes