creating-streamlit-themes

Par streamlit · agent-skills

Créer et personnaliser des thèmes Streamlit. À utiliser pour modifier les couleurs, les polices ou l'apparence d'une application, ou pour l'aligner sur une charte graphique. Couvre la configuration via `config.toml`, les principes de design et l'évitement du CSS.

npx skills add https://github.com/streamlit/agent-skills --skill creating-streamlit-themes

Créer des thèmes Streamlit

Construisez des thèmes professionnels et alignés à votre marque en utilisant .streamlit/config.toml. Cette compétence couvre les principes de conception et la configuration complète pour des thèmes polis et cohérents.

Configuration du fichier de thème

Les options de thème vont dans config.toml de Streamlit sous la section [theme] :

Héritage de thème

Commencez par un thème intégré ou un fichier externe :

[theme]
base = "light"                         # ou "dark"
# base = "./my-base-theme.toml"        # Fichier local
# base = "https://example.com/theme.toml"  # URL distante

Avec base, vous ne devez surcharger que les valeurs que vous souhaitez modifier. Les fichiers de thème référencés via base ne peuvent contenir qu'une seule section [theme]—les variantes [theme.light] et [theme.dark] ne sont pas supportées dans les fichiers de thème externes.

Configuration des couleurs

Couleurs de thème

[theme]
primaryColor = "#0969da"           # Boutons, liens, éléments actifs
backgroundColor = "#ffffff"        # Arrière-plan du contenu principal
secondaryBackgroundColor = "#f6f8fa"  # Arrière-plans des widgets, blocs de code
textColor = "#1F2328"              # Texte du corps

# Raffinements optionnels
linkColor = "#0969da"              # Liens Markdown (par défaut primaryColor)
codeTextColor = "#1F2328"          # Texte du code en ligne
codeBackgroundColor = "#f6f8fa"    # Arrière-plan du bloc de code
borderColor = "#d0d7de"            # Bordures des widgets

Principe de conception : Choisissez une primaryColor suffisamment foncée pour contraster avec du texte blanc. Streamlit rend le texte des boutons primaires blanc sur la couleur primaire.

Palette de couleurs

Définissez des couleurs sémantiques pour les indicateurs de statut, la coloration du texte Markdown et les sparklines :

[theme]
redColor = "#cf222e"
orangeColor = "#bf8700"
yellowColor = "#dbab09"
greenColor = "#1a7f37"
blueColor = "#0969da"
violetColor = "#8250df"
grayColor = "#57606a"

Chaque couleur supporte des variantes d'arrière-plan et de texte (auto-dérivées si non défini) :

[theme]
greenColor = "#1a7f37"
greenBackgroundColor = "#dafbe1"   # Teinte légère pour les badges
greenTextColor = "#116329"         # Assombrie pour la lisibilité

Couleurs de graphiques

Définissez les couleurs pour les graphiques Plotly, Altair et Vega-Lite :

[theme]
# Données catégoriques (barres, tranches de camembert, séries)
chartCategoricalColors = ["#0969da", "#1a7f37", "#bf3989", "#8250df", "#cf222e", "#bf8700", "#57606a"]

# Données séquentielles/gradients (cartes thermiques) - exactement 10 couleurs requises
chartSequentialColors = ["#f0f6fc", "#c8e1ff", "#79c0ff", "#58a6ff", "#388bfd", "#1f6feb", "#1158c7", "#0d419d", "#0a3069", "#04244a"]

Style des dataframes

[theme]
dataframeBorderColor = "#d0d7de"
dataframeHeaderBackgroundColor = "#f6f8fa"

Assurez-vous que textColor est lisible sur dataframeHeaderBackgroundColor—les en-têtes utilisent la couleur de texte principale.

Typographie

Familles de polices

Utilisez les polices intégrées, chargez depuis Google Fonts, ou définissez des polices personnalisées à partir de fichiers (voir ci-dessous) :

[theme]
# Options intégrées
font = "sans-serif"  # ou "serif" ou "monospace"

# Google Fonts
font = "Inter:https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap"

# Police avec espaces dans le nom
font = "'IBM Plex Sans':https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@400;500;600&display=swap"

Auto-hébergement de polices personnalisées

Utilisez les tables [[theme.fontFaces]] pour charger les polices via le serveur de fichiers statiques de Streamlit. Les fichiers de police doivent être placés dans un répertoire static/ et servis via l'application—ils ne peuvent pas être des chemins locaux arbitraires.

Avant d'ajouter des polices à config.toml : Vérifiez que les fichiers de police existent dans le répertoire statique.

[[theme.fontFaces]]
family = "CustomFont"
url = "app/static/CustomFont-Regular.woff2"
weight = 400

[[theme.fontFaces]]
family = "CustomFont"
url = "app/static/CustomFont-Bold.woff2"
weight = 700

[theme]
font = "CustomFont"

Attributs : family (nom), url (chemin vers OTF/TTF/WOFF/WOFF2), weight (400, "200 800", ou "bold"), style ("normal"/"italic"/"oblique"), unicodeRange (ex. "U+0000-00FF").

Les modifications apportées à fontFaces nécessitent un redémarrage du serveur.

Polices de titres et de code

[theme]
headingFont = "Inter:https://fonts.googleapis.com/css2?family=Inter:wght@600;700&display=swap"
codeFont = "'JetBrains Mono':https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500&display=swap"

Taille et poids des polices

[theme]
baseFontSize = 14                  # Taille racine en pixels (défaut : 16)
baseFontWeight = 400               # Poids normal
codeFontSize = "0.875rem"          # Relatif à la base, ou utiliser "13px"
codeFontWeight = 400

# Hiérarchie des titres (h1 à h6), ou utiliser une seule valeur pour tous
headingFontSizes = ["32px", "24px", "20px", "16px", "14px", "12px"]
headingFontWeights = [600, 600, 600, 500, 500, 500]

Style des liens

[theme]
linkUnderline = false              # Supprimer les soulignements pour un look plus épuré

Bordure et rayon

[theme]
baseRadius = "8px"                 # Tous les composants (none/small/medium/large/full/px/rem)
buttonRadius = "8px"               # Boutons spécifiquement (par défaut baseRadius)
showWidgetBorder = true            # Afficher les bordures sur les widgets non-actifs
showSidebarBorder = true           # Afficher un séparateur entre la barre latérale et le contenu

Mots-clés de rayon : "none" (0), "small" (4px), "medium" (8px), "large" (12px), "full" (forme de pilule).

Personnalisation de la barre latérale

Stylisez la barre latérale indépendamment :

[theme.sidebar]
backgroundColor = "#f6f8fa"
secondaryBackgroundColor = "#eaeef2"
codeBackgroundColor = "#eaeef2"
textColor = "#1F2328"
borderColor = "#d0d7de"
primaryColor = "#0969da"           # Éléments actifs dans la barre latérale

Modes clair et sombre

Définissez des thèmes séparés pour chaque mode :

[theme.light]
primaryColor = "#0969da"
backgroundColor = "#ffffff"
secondaryBackgroundColor = "#f6f8fa"
textColor = "#1F2328"

[theme.dark]
primaryColor = "#58a6ff"
backgroundColor = "#0d1117"
secondaryBackgroundColor = "#161b22"
textColor = "#e6edf3"

[theme.light.sidebar]
backgroundColor = "#f6f8fa"

[theme.dark.sidebar]
backgroundColor = "#010409"

Les utilisateurs peuvent basculer entre les modes dans le menu des paramètres de l'application uniquement si [theme.light] et [theme.dark] sont tous deux définis. Un thème personnalisé avec seulement [theme] verrouille l'application sur un seul mode.

Détecter le thème actuel

Utilisez st.context.theme.base pour adapter votre application au thème actif. Utile pour :

  • Ajuster les couleurs de graphiques spécifiques pour un meilleur contraste
  • Permuter les logos ou images (ex. logo sombre sur clair, logo clair sur sombre)
  • Styliser les composants tiers qui ne s'auto-adaptent pas
  • Appliquer du CSS ou du style personnalisé conditionnel
if st.context.theme.base == "dark":
    # Faire quelque chose pour le mode sombre

Principes de conception

Contraste des couleurs

Assurez la conformité WCAG AA (ratio 4.5:1 pour le texte) :

  • Thèmes clairs : Texte foncé (#1F2328) sur arrière-plans clairs (#ffffff)
  • Thèmes sombres : Texte clair (#e6edf3) sur arrière-plans sombres (#0d1117)
  • Les couleurs primaires doivent contraster avec le texte blanc des boutons

Harmonie des couleurs

Construisez des palettes cohérentes en utilisant ces approches :

Monochromatique : Une seule teinte avec clarté variable (ex. gris zinc de shadcn)

primaryColor = "#18181B"
textColor = "#09090B"
borderColor = "#E4E4E7"
grayColor = "#71717A"

Accent de marque : Base neutre avec une couleur de marque (ex. pourpre de Stripe)

primaryColor = "#635bff"           # Pourpre de marque
backgroundColor = "#ffffff"
textColor = "#425466"              # Gris neutre

Complémentaire : Primaire de marque avec couleurs d'accent de soutien

primaryColor = "#29B5E8"           # Bleu de marque (Snowflake)
textColor = "#11567F"              # Bleu plus foncé pour le texte
greenColor = "#36B37E"             # États de succès
redColor = "#DE350B"               # États d'erreur

Directives typographiques

  • Texte du corps : 14-16px, poids 400
  • Titres : Échelle décroissante de h1 (28-40px) à h6 (12-14px)
  • Code : Police monospace, légèrement plus petite que le corps (0,85-0,875rem)
  • Appairage de polices : Utilisez la même police pour le corps et les titres pour la cohérence, ou associez des polices complémentaires (ex. titres serif avec corps sans-serif). Le code doit toujours utiliser une police monospace distincte.

Hiérarchie visuelle

Créez de la profondeur avec des couches d'arrière-plan :

Contenu principal :        #ffffff (le plus clair)
Éléments secondaires :     #f6f8fa (légèrement plus foncé)
Barre latérale :           #f6f8fa ou couleur de marque contrastée
Blocs de code :            #f6f8fa (correspond au secondaire ou distinct)

Exemple : Thème de marque Snowflake

Thème propre et professionnel avec accents bleus de marque :

[theme]
primaryColor = "#29B5E8"
backgroundColor = "#ffffff"
secondaryBackgroundColor = "#f4f9fc"
codeBackgroundColor = "#e8f4f8"
textColor = "#11567F"
linkColor = "#29B5E8"
borderColor = "#d0e8f2"
showWidgetBorder = true
showSidebarBorder = true
baseRadius = "8px"
buttonRadius = "8px"

font = "'Inter':https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap"
codeFont = "'JetBrains Mono':https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500&display=swap"
codeFontSize = "13px"
codeTextColor = "#11567F"
baseFontSize = 14
baseFontWeight = 400
headingFontSizes = ["32px", "24px", "20px", "16px", "14px", "12px"]
headingFontWeights = [600, 600, 600, 500, 500, 500]
linkUnderline = false

chartCategoricalColors = ["#29B5E8", "#11567F", "#71C8E5", "#174D6A", "#A5DDF2", "#0E4D6B", "#52B8D9"]

blueColor = "#29B5E8"
greenColor = "#36B37E"
yellowColor = "#FFAB00"
redColor = "#DE350B"
violetColor = "#6554C0"

dataframeBorderColor = "#d0e8f2"
dataframeHeaderBackgroundColor = "#e8f4f8"

[theme.sidebar]
backgroundColor = "#11567F"
secondaryBackgroundColor = "#174D6A"
codeBackgroundColor = "#0E4D6B"
textColor = "#ffffff"
borderColor = "#1E6D94"

Exemple : Thème sombre VS Code

Thème sombre axé sur les développeurs avec couleurs inspirées de la syntaxe :

[theme]
base = "dark"
primaryColor = "#0078d4"
backgroundColor = "#1e1e1e"
secondaryBackgroundColor = "#252526"
codeBackgroundColor = "#1e1e1e"
textColor = "#cccccc"
linkColor = "#3794ff"
borderColor = "#3c3c3c"
showWidgetBorder = true
showSidebarBorder = true
baseRadius = "4px"
buttonRadius = "4px"

font = "'Segoe UI', 'Open Sans':https://fonts.googleapis.com/css2?family=Open+Sans:wght@300;400;500;600;700&display=swap"
codeFont = "'Fira Code':https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500&display=swap"
codeFontSize = "13px"
codeTextColor = "#d4d4d4"
baseFontSize = 14
baseFontWeight = 400
headingFontSizes = ["28px", "22px", "18px", "16px", "14px", "12px"]
headingFontWeights = [600, 600, 600, 600, 600, 600]
linkUnderline = false

chartCategoricalColors = ["#0078d4", "#4ec9b0", "#dcdcaa", "#ce9178", "#c586c0", "#569cd6", "#6a9955"]

blueColor = "#569cd6"
greenColor = "#6a9955"
yellowColor = "#dcdcaa"
orangeColor = "#ce9178"
violetColor = "#c586c0"

[theme.sidebar]
backgroundColor = "#252526"
secondaryBackgroundColor = "#333333"
codeBackgroundColor = "#1e1e1e"
borderColor = "#3c3c3c"

Erreurs courantes

Couleur primaire trop claire

# MAUVAIS : Texte blanc sur jaune illisible
primaryColor = "#FFEB3B"

# BON : Utiliser une teinte plus foncée
primaryColor = "#F59E0B"

Contraste insuffisant

# MAUVAIS : Texte gris clair sur blanc
textColor = "#CCCCCC"
backgroundColor = "#FFFFFF"

# BON : Texte foncé sur arrière-plan clair
textColor = "#1F2328"
backgroundColor = "#FFFFFF"

Arrière-plans mal assortis

# MAUVAIS : Secondaire plus clair que primaire
backgroundColor = "#f6f8fa"
secondaryBackgroundColor = "#ffffff"

# BON : Secondaire doit être plus foncé/distinct
backgroundColor = "#ffffff"
secondaryBackgroundColor = "#f6f8fa"

Oublier le contraste de la barre latérale

Quand vous utilisez une barre latérale sombre avec une section principale claire, ajustez toutes les couleurs de la barre latérale—pas seulement textColor :

# MAUVAIS : Seulement backgroundColor modifié
[theme.sidebar]
backgroundColor = "#11567F"

# BON : Ajuster toutes les couleurs pour une barre latérale sombre
[theme.sidebar]
backgroundColor = "#11567F"
secondaryBackgroundColor = "#174D6A"
textColor = "#ffffff"
borderColor = "#1E6D94"
...

IMPORTANT : Pas de CSS personnalisé sauf si explicitement demandé

N'UTILISEZ PAS de CSS personnalisé ou HTML pour les thèmes. Cela inclut :

  • st.markdown(..., unsafe_allow_html=True) avec <style> ou styles en ligne
  • st.html() avec blocs <style>
  • Tout HTML/CSS pour les couleurs, arrière-plans, polices ou style visuel

N'utilisez du CSS que si l'utilisateur le demande explicitement (ex. « ajouter du CSS personnalisé », « utiliser st.html pour styliser »). Pour les couleurs de marque, les thèmes et l'identité visuelle—utilisez toujours config.toml.

Le thème natif est plus propre, plus maintenable et ne cassera pas avec les mises à jour de Streamlit.

Si l'utilisateur demande explicitement du CSS, utilisez key= pour créer des classes ciblables :

st.button("Submit", key="submit")
# Génère : .st-key-submit

st.html("""<style>.st-key-submit button { width: 100%; }</style>""")

Ne jamais utiliser CSS pour les thèmes (couleurs, arrière-plans, polices) sauf explicitement demandé. Utilisez config.toml à la place.

Flux de travail de développement

La plupart des options de thème se mettent à jour en direct après l'enregistrement de config.toml et le redémarrage. Les options liées aux polices (fontFaces) nécessitent un redémarrage du serveur.

Testez votre thème avec : boutons (contraste primaire), formulaires (bordures, focus), dataframes (en-têtes), blocs de code, graphiques et barre latérale.

Modèles de thème

Des thèmes prêts à l'emploi avec polices incluses sont disponibles dans templates/themes/ :

Thème Base Couleur primaire Polices
snowflake Clair #29B5E8 (cyan) Inter, JetBrains Mono
dracula Sombre #BD93F9 (violet) Fira Sans, JetBrains Mono
nord Sombre #88C0D0 (bleu givre) Inter, JetBrains Mono
stripe Clair #635BFF (indigo) Inter, Source Code Pro
solarized-light Clair #268BD2 (bleu) Source Sans 3, Source Code Pro
spotify Sombre #1DB954 (vert) Inter, Fira Code
github Clair #0969DA (bleu) Inter, JetBrains Mono
minimal Sombre #6366f1 (indigo) Inter, JetBrains Mono

Chaque thème utilise Google Fonts pour une configuration facile. Voir templates/themes/README.md.

Compétences liées

Références

Skills similaires