Ce guide documente l'utilisation des composants du Système de Design de l'État (DSFR) dans le projet SPAN SG avec le thème mkdocs-dsfr v0.17.0.
Version: 1.0.0 Date: 2025-10-14 Auteur: Équipe technique SPAN SG
- Introduction
- Cards - Cartes de navigation
- Callouts - Encadrés informatifs
- Badges - Indicateurs d'état
- Alerts - Notifications
- Grid - Grilles responsives
- Tables - Tableaux accessibles
- Accordions - Accordéons pliables
- Tabs - Onglets
- Snippets réutilisables
Le thème mkdocs-dsfr utilise l'extension dsfr_structure.extension.all_extensions qui permet d'écrire des composants DSFR en syntaxe Markdown simplifiée.
- Documentation DSFR : https://www.systeme-de-design.gouv.fr/
- mkdocs-dsfr : https://pub.gitlab-pages.din.developpement-durable.gouv.fr/numeco/mkdocs-dsfr-doc/
- Composants disponibles : Cards, Callouts, Badges, Alerts, Grid, Accordions, Tabs, etc.
Dans mkdocs-dsfr.yml :
markdown_extensions:
- dsfr_structure.extension.all_extensions # Active tous composants DSFR
- pymdownx.superfences # Support syntaxe ///
- attr_list # Support attributs HTML
- def_list # Support listes définitionsLes cards DSFR sont utilisées pour créer des cartes de navigation visuelles avec badges et liens.
/// card | Titre de la card
target: chemin/vers/page.md
badge: Texte badge | type
Description de la card affichée en bas
///| Paramètre | Obligatoire | Description | Exemple |
|---|---|---|---|
title |
Oui | Titre (1ère ligne après card) |
SIRCOM |
target |
Oui | Lien destination | modules/sircom.md |
badge |
Non | Badge avec type | Validé | success |
description |
Non | Texte explicatif | Service de la Communication |
success: Vert (validé, conforme)warning: Orange (brouillon, en cours)error: Rouge (bloqué, non conforme)info: Bleu (information)
/// card | SIRCOM
target: modules/sircom.md
badge: Validé | success
Service de la Communication - Portails ministériels, sites internet/intranet
///<div class="fr-card fr-enlarge-link" id="card-0">
<div class="fr-card__body">
<div class="fr-card__content">
<h5 class="fr-card__title" id="sircom">
<a href="modules/sircom/">SIRCOM</a>
</h5>
<div class="fr-card__start">
<p class="fr-badge fr-badge--success">Validé</p>
</div>
<div class="fr-card__end">
<p class="fr-card__detail">Service de la Communication...</p>
</div>
</div>
</div>
</div>Navigation homepage vers modules de services (docs/index.md:119-167)
Les callouts sont des encadrés visuels pour mettre en avant des informations importantes.
/// callout | Titre du callout
icon: nom-icon-remixicon
color: couleur-dsfr
link_label: Texte lien
link_url: https://example.com
Contenu du callout en Markdown
///| Paramètre | Obligatoire | Description | Exemple |
|---|---|---|---|
title |
Oui | Titre | Besoin d'aide ? |
icon |
Non | Icône Remix Icon | question-line |
color |
Non | Couleur DSFR | blue-france |
link_label |
Non | Texte bouton | En savoir plus |
link_url |
Non | URL bouton | https://... |
blue-france: Bleu France (défaut, informatif)orange-terre-battue: Orange (alerte, attention)green-menthe: Vert menthe (positif, financement)red-marianne: Rouge (critique, urgent)purple-glycine: Violet (spécial)
Liste complète : https://remixicon.com/
Exemples courants :
question-line: Point d'interrogationalert-line: Triangle alertemoney-euro-circle-line: Euro (financement)building-line: Bâtimentuser-line: Utilisateur
/// callout | Besoin d'aide ?
icon: question-line
color: blue-france
link_label: Contacter la MiWeb
link_url: mailto:accessibilite.miweb@finances.gouv.fr
La MiWeb accompagne les référents de service dans la complétion de leur SPAN.
////// callout | Actions critiques pour le succès
icon: alert-line
color: orange-terre-battue
Ces 6 actions préalables conditionnent la réussite de votre SPAN. Ne pas les réaliser expose à l'échec du projet, à des sanctions financières (jusqu'à 75K€/site) et à un risque réputationnel important.
////// callout | Financement FIPHFP disponible
icon: money-euro-circle-line
color: green-menthe
link_label: En savoir plus sur le FIPHFP
link_url: https://www.fiphfp.fr/
Le FIPHFP peut financer jusqu'à 10 000€ par an pendant 3 ans (30 000€ total) pour vos actions d'accessibilité : formations, audits RGAA, outils spécialisés.
////// callout | Échéance légale imminente
icon: time-line
color: red-marianne
link_label: Voir le calendrier
link_url: /processus/#calendrier
Tous les services publics doivent publier leur SPAN avant le 31 décembre 2025 sous peine de sanctions Arcom.
///| Callouts | Alerts |
|---|---|
| Contenu éditorial | Messages système |
| Personnalisables (icon, color) | Types fixes (info, warning, error) |
| Peuvent avoir bouton CTA | Pas de bouton |
| Usage : mise en avant contenu | Usage : notifications utilisateur |
Les badges DSFR sont utilisés pour indiquer l'état ou le statut d'un élément.
Contexte (ADR-002) : La syntaxe Markdown /// badge ne fonctionne pas dans les tableaux HTML. Le projet utilise donc la syntaxe HTML DSFR native pour les badges dans les tableaux.
<p class="fr-badge fr-badge--{type}">{Texte}</p>| Type | Classe CSS | Couleur | Usage |
|---|---|---|---|
success |
fr-badge--success |
Vert | Validé, conforme, actif |
warning |
fr-badge--warning |
Orange | Brouillon, en cours |
error |
fr-badge--error |
Rouge | Bloqué, non conforme |
info |
fr-badge--info |
Bleu | Informatif, en cours |
<td>
<p class="fr-badge fr-badge--success">Validé</p>
</td><p class="fr-badge fr-badge--warning">Brouillon</p><p class="fr-badge fr-badge--error">Non renseigné</p><p class="fr-badge fr-badge--info">En cours</p>def generate_status_badge(checked: int, total: int) -> str:
"""Génère badge HTML DSFR selon score."""
if total == 0:
return '<p class="fr-badge fr-badge--error">Non renseigné</p>'
elif checked == total:
return '<p class="fr-badge fr-badge--success">Conforme</p>'
elif checked > 0:
return '<p class="fr-badge fr-badge--info">En cours</p>'
else:
return '<p class="fr-badge fr-badge--warning">À démarrer</p>'Dans les cards, utiliser la syntaxe Markdown simplifiée :
/// card | Titre
badge: Validé | success
///Le type success, warning, error, info sera converti en classe CSS fr-badge--{type}.
Les alerts DSFR sont des notifications système pour informer l'utilisateur.
/// alert | Titre de l'alerte
type: info
Contenu de l'alerte en Markdown
///| Type | Couleur | Icône | Usage |
|---|---|---|---|
info |
Bleu | ℹ️ | Information générale |
warning |
Orange | Avertissement | |
error |
Rouge | ❌ | Erreur, action requise |
success |
Vert | ✅ | Succès, confirmation |
/// alert | Information
type: info
Le site est accessible en mode prévisualisation pendant les travaux.
////// alert | Attention
type: warning
Cette page sera archivée le 31 décembre 2025. Consultez la nouvelle version.
////// alert | Erreur de configuration
type: error
Le fichier `mkdocs.yml` contient des erreurs. Corrigez-les avant de continuer.
////// alert | Validation réussie
type: success
Votre SPAN a été validé par le comité de pilotage. Publication prévue le 15/11/2025.
///| Critère | Alert | Callout |
|---|---|---|
| Nature | Message système | Contenu éditorial |
| Durée | Temporaire | Permanent |
| Style | Types fixes | Personnalisable |
| Exemple | "Maintenance en cours" | "Financement FIPHFP disponible" |
Le système de grille DSFR permet de créer des layouts responsives sur 12 colonnes.
/// row | fr-grid-row--gutters
/// col | 12 md-6 lg-4
Contenu colonne 1
///
/// col | 12 md-6 lg-4
Contenu colonne 2
///
/// col | 12 md-6 lg-4
Contenu colonne 3
///
///- Ligne :
/// row | fr-grid-row--gutters - Colonnes :
/// col | breakpoints - Fermeture : Trois
///pour fermer row
| Classe | Résolution | Colonnes | Usage |
|---|---|---|---|
12 |
Mobile (<768px) | 12/12 (pleine largeur) | Défaut |
md-6 |
Tablette (≥768px) | 6/12 (2 colonnes) | Medium |
lg-4 |
Desktop (≥1024px) | 4/12 (3 colonnes) | Large |
/// row | fr-grid-row--gutters
/// col | 12 md-6 lg-4
/// card | SIRCOM
target: modules/sircom.md
badge: Validé | success
Service de la Communication
///
///
/// col | 12 md-6 lg-4
/// card | SNUM
target: modules/snum.md
badge: Brouillon | warning
Service du Numérique
///
///
/// col | 12 md-6 lg-4
/// card | SRH
target: modules/srh.md
badge: Brouillon | warning
Service des Ressources Humaines
///
///
///- Mobile : 3 cards empilées verticalement (12/12)
- Tablette : 2 cards par ligne (6/12 + 6/12)
- Desktop : 3 cards par ligne (4/12 + 4/12 + 4/12)
| Classe | Description |
|---|---|
fr-grid-row |
Grille sans espacement |
fr-grid-row--gutters |
Grille avec gouttières (recommandé) |
fr-grid-row--center |
Alignement centré |
fr-grid-row--middle |
Alignement vertical milieu |
/// row | fr-grid-row--gutters
/// col | 12 md-6
Colonne gauche (50% tablette+)
///
/// col | 12 md-6
Colonne droite (50% tablette+)
///
////// row | fr-grid-row--gutters
/// col | 12 sm-6 lg-3
Colonne 1 (25% desktop)
///
/// col | 12 sm-6 lg-3
Colonne 2 (25% desktop)
///
/// col | 12 sm-6 lg-3
Colonne 3 (25% desktop)
///
/// col | 12 sm-6 lg-3
Colonne 4 (25% desktop)
///
///Le projet utilise un hook Python pour rendre automatiquement les tableaux Markdown accessibles RGAA.
def on_page_content(html, page, **kwargs):
"""Encapsule les tableaux Markdown dans divs DSFR."""
return wrap_tables_dsfr(html)Transforme :
<table>...</table>En :
<div class="fr-table fr-table--bordered">
<div class="fr-table__wrapper">
<div class="fr-table__container">
<div class="fr-table__content">
<table>...</table>
</div>
</div>
</div>
</div>| Colonne 1 | Colonne 2 | Colonne 3 |
|-----------|-----------|-----------|
| Ligne 1 | Donnée 1 | Donnée 2 |
| Ligne 2 | Donnée 3 | Donnée 4 |Le wrapper DSFR est ajouté automatiquement par le hook.
Pour les tableaux de données, ajouter un caption HTML :
<table id="table-span-modules">
<caption>
Synthèse des modules SPAN par direction
</caption>
<thead>
...
</thead>
</table><div class="fr-table fr-table--bordered" id="table-synthese-span">
<div class="fr-table__wrapper">
<div class="fr-table__container">
<div class="fr-table__content">
<table id="table-span-modules">
<caption>
Synthèse des modules SPAN par direction
</caption>
<thead>
<tr>
<th scope="col">Direction</th>
<th scope="col">Score</th>
<th scope="col">Statut</th>
</tr>
</thead>
<tbody>
<tr id="table-span-row-sircom">
<td>SIRCOM</td>
<td>24/33 (72.7%)</td>
<td>
<p class="fr-badge fr-badge--success">Validé</p>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>| Attribut | Élément | Valeur | Obligatoire |
|---|---|---|---|
id |
<table> |
Unique | Oui |
scope |
<th> |
col ou row |
Oui |
<caption> |
Dans <table> |
Texte descriptif | Oui (tableaux données) |
Le wrapper DSFR rend le tableau scrollable horizontalement sur mobile si nécessaire.
Bibliothèque de composants DSFR prêts à l'emploi.
/// card | [NOM_SERVICE]
target: modules/[service].md
badge: Brouillon | warning
[Description du service]
////// callout | Besoin d'aide ?
icon: question-line
color: blue-france
link_label: Contacter le support
link_url: mailto:support@example.com
Pour toute question sur ce contenu, contactez notre équipe support.
////// callout | Attention
icon: alert-line
color: orange-terre-battue
Cette information est critique pour la conformité de votre service.
////// callout | Financement disponible
icon: money-euro-circle-line
color: green-menthe
link_label: Demander un financement
link_url: https://fiphfp.fr/
Des aides financières sont disponibles pour vos actions d'accessibilité.
////// alert | Maintenance programmée
type: warning
Le site sera indisponible le [DATE] de [HEURE] à [HEURE] pour maintenance.
////// alert | Validation réussie
type: success
Votre module a été validé par le comité de pilotage.
///<p class="fr-badge fr-badge--info">Nouveau</p>/// row | fr-grid-row--gutters
/// col | 12 md-6 lg-4
/// card | Card 1
target: page1.md
badge: Type | success
Description card 1
///
///
/// col | 12 md-6 lg-4
/// card | Card 2
target: page2.md
badge: Type | warning
Description card 2
///
///
/// col | 12 md-6 lg-4
/// card | Card 3
target: page3.md
badge: Type | error
Description card 3
///
///
///<div class="fr-table fr-table--bordered">
<div class="fr-table__wrapper">
<div class="fr-table__container">
<div class="fr-table__content">
<table>
<caption>Titre du tableau</caption>
<thead>
<tr>
<th scope="col">Colonne 1</th>
<th scope="col">Colonne 2</th>
</tr>
</thead>
<tbody>
<tr>
<td>Donnée 1</td>
<td>
<p class="fr-badge fr-badge--success">Badge</p>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>Les accordéons permettent de masquer/afficher du contenu de manière interactive. Idéal pour FAQ, sections longues ou documentation technique.
/// accordion | Titre de l'accordéon
Contenu masqué par défaut
///| Paramètre | Description | Valeurs | Défaut |
|---|---|---|---|
title |
Titre de l'accordéon | Texte | Requis |
expanded |
État initial | true/false |
false |
id |
ID HTML unique | string | auto |
/// accordion | Comment contribuer au projet ?
Consultez le [Guide contributeur](../contributing.md) pour les instructions détaillées.
Processus en 3 étapes :
1. Fork du dépôt
2. Créer une branche feature
3. Ouvrir une Pull Request
///
/// accordion | Où trouver la documentation API ?
expanded: true
La documentation complète est disponible dans [API Reference](api-reference.md).
////// accordion | Détails techniques du hook dsfr_table_wrapper.py
**Fonction** : Encapsule automatiquement les tableaux Markdown dans `<div class="fr-table">`.
**Code source** :
```python
def on_page_content(html, page, config, files):
soup = BeautifulSoup(html, 'html.parser')
for table in soup.find_all('table'):
wrapper = soup.new_tag('div', **{'class': 'fr-table'})
table.wrap(wrapper)
return str(soup)Tests : Voir tests/test_hooks_dsfr_table_wrapper.py (100% coverage).
///
### Exemple 3 : Sections multiples (groupe)
```markdown
/// accordion | SIRCOM - Service de la Communication
**Score** : 24/33 (72.7%)
**Référent** : Équipe Communication
Plan d'action 2025 : 9 actions en cours.
///
/// accordion | SNUM - Service du Numérique
**Score** : 21/33 (63.6%)
**Référent** : Chef de mission numérique
Plan d'action 2025 : 12 actions prioritaires.
///
- Accordions : Syntaxe markdown, intégration native mkdocs-dsfr
- Collapsible HTML :
<details><summary>HTML natif
Privilégier les accordions pour cohérence DSFR.
Les accordions génèrent automatiquement :
role="button"sur le titrearia-expanded="true/false"selon l'état- Navigation clavier (Entrée/Espace pour toggle)
Les onglets permettent d'organiser du contenu alternatif (exemples multi-langages, configurations alternatives).
/// tabs
/// tab | Python
```python
print("Hello SPAN")///
/// tab | Bash
echo "Hello SPAN"/// ///
### Exemple 1 : Exemples multi-langages
```markdown
/// tabs
/// tab | Python
```python
import yaml
with open('mkdocs-dsfr.yml') as f:
config = yaml.safe_load(f)
print(config['site_name'])
///
/// tab | JavaScript
const fs = require('fs');
const yaml = require('js-yaml');
const config = yaml.load(fs.readFileSync('mkdocs-dsfr.yml', 'utf8'));
console.log(config.site_name);///
/// tab | Bash
grep "^site_name:" mkdocs-dsfr.yml | cut -d: -f2/// ///
### Exemple 2 : Configurations alternatives
```markdown
/// tabs
/// tab | Docker (Recommandé)
```bash
docker compose -f docker-compose-dsfr.yml up -d
# Accès : http://localhost:8000/span-sg-repo/
Avantages : Isolation, pas de dépendances locales. ///
/// tab | Python local
pip install -r requirements-dsfr.txt
mkdocs serve --config-file mkdocs-dsfr.ymlPrérequis : Python 3.11+, pip. ///
/// tab | macOS Homebrew
brew install mkdocs
pip3 install mkdocs-dsfr
mkdocs serve --config-file mkdocs-dsfr.ymlNote : Utiliser Python 3 de Homebrew. /// ///
### Exemple 3 : Workflows Git
```markdown
/// tabs
/// tab | Feature (nouveau module)
```bash
git checkout -b feature/update-sircom
# Modifications dans docs/modules/sircom.md
git add docs/modules/sircom.md
git commit -m "feat(sircom): mise à jour plan 2025"
git push -u origin feature/update-sircom
# Créer PR vers staging
///
/// tab | Hotfix (production)
git checkout -b hotfix/fix-typo-synthese
# Corrections dans docs/synthese.md
git add docs/synthese.md
git commit -m "fix(synthese): correction typo tableau"
git push -u origin hotfix/fix-typo-synthese
# Créer PR vers main///
/// tab | Sync draft → main
git checkout main
git pull origin main
git merge draft --no-ff
git push origin main
# Déclenche déploiement production/// ///
### Paramètres tabs
| Paramètre | Description | Valeurs |
|-----------|-------------|---------|
| Tabs parent | Conteneur principal | `/// tabs` ... `///` |
| Tab enfant | Onglet individuel | `/// tab \| Titre` |
| Titre | Label de l'onglet | Texte (requis) |
### Accessibilité
Les onglets génèrent automatiquement :
- `role="tablist"` sur le conteneur
- `role="tab"` sur chaque onglet
- `aria-selected="true/false"` selon l'onglet actif
- Navigation clavier (flèches gauche/droite)
### Cas d'usage recommandés
- Exemples de code multi-langages
- Instructions alternatives (Docker vs local)
- Workflows Git différents (feature vs hotfix)
- Configurations environnements (dev, staging, prod)
---
## Références complémentaires
- **ADR-001** : [Choix thème DSFR](../adr/001-choix-theme-dsfr.md)
- **ADR-002** : [Format synthèse HTML](../adr/002-format-synthese-html.md) - Pourquoi HTML badges
- **ADR-004** : [Hooks Python](../adr/004-hooks-python-mkdocs.md) - Table wrapper
- **API Reference** : [Scripts Python](api-reference.md) - Génération badges dynamiques
---
**Note finale** : Ce guide est maintenu à jour avec chaque nouvelle utilisation de composant DSFR dans le projet. Pour proposer des ajouts, ouvrez une issue ou PR sur GitHub.