HTML et styles personnalisés
On peut insérer du HTML arbitraire dans une page, et le styler de quatre façons, de la plus ponctuelle à la plus réutilisable :
| Niveau | Technique | Portée | Idéal pour |
|---|---|---|---|
| 1 | Attribut style="…" |
Un élément | Un réglage isolé |
| 2 | Bloc <style> dans la page |
La page entière | Un rendu spécial sur une seule page |
| 3 | Classe dans src/styles/custom.css |
Tout le site | Un style réutilisé sur plusieurs pages |
| 4 | Composant .astro |
Chaque utilisation du composant | Un bloc complexe et paramétrable |
Tous les exemples ci-dessous sont rendus en direct : cette page est elle-même un fichier .mdx.
Les règles du HTML en MDX
Section intitulée « Les règles du HTML en MDX »En MDX, le HTML est interprété comme du JSX, plus strict que le HTML classique. Une erreur arrête le build, avec un message indiquant la ligne et la colonne fautives.
| Règle | ❌ Échoue | ✅ Fonctionne |
|---|---|---|
| Toute balise doit être fermée | <br>, <img src="…"> |
<br />, <img src="…" /> |
| Pas de commentaires HTML | <!-- note --> |
{/* note */} |
{ et } sont du JavaScript : le CSS d’un <style> doit être entouré de {`…`} |
<style>.a { color: red }</style> |
<style>{`.a { color: red }`}</style> |
| Du Markdown dans une balise doit être entouré de lignes vides | — | voir les exemples ci-dessous |
Avec Astro, on garde les attributs HTML habituels : class (et non className comme en React),
for, et style sous forme de texte.
Niveau 1 : l’attribut style
Section intitulée « Niveau 1 : l’attribut style »<div style="padding: 1rem; border: 2px dashed var(--sl-color-orange); border-radius: 0.5rem;">
Un bloc avec une **bordure orange en pointillés**. Les lignes vides autour de ce textepermettent d'y écrire du Markdown.
</div>Un bloc avec une bordure orange en pointillés. Les lignes vides autour de ce texte permettent d’y écrire du Markdown.
Simple et immédiat, mais à éviter dès que le même style se répète : il faudrait le recopier partout.
Niveau 2 : un bloc <style> dans la page
Section intitulée « Niveau 2 : un bloc <style> dans la page »On déclare des classes CSS dans la page, puis on les utilise sur autant d’éléments que nécessaire :
<style>{` .demo-cartes { display: grid; grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr)); gap: 1rem; } .demo-carte { padding: 1.25rem; border-radius: 1rem; text-align: center; color: white; font-weight: 700; box-shadow: 0 8px 20px -8px rgba(0, 0, 0, 0.5); transition: transform 0.2s; } .demo-carte:hover { transform: translateY(-4px) rotate(-1deg); } .demo-carte span { display: block; font-size: 2.5rem; } .demo-carte.un { background: linear-gradient(135deg, #6d28d9, #db2777); } .demo-carte.deux { background: linear-gradient(135deg, #0369a1, #0d9488); } .demo-carte.trois { background: linear-gradient(135deg, #c2410c, #ca8a04); }`}</style>
<div class="demo-cartes not-content"> <div class="demo-carte un"><span>1</span>Écrire</div> <div class="demo-carte deux"><span>2</span>Compiler</div> <div class="demo-carte trois"><span>3</span>Publier</div></div>La classe not-content
Section intitulée « La classe not-content »Starlight met automatiquement en forme le contenu des pages : espacement entre les blocs, style des titres, des listes, des liens… Pour un bloc au rendu très particulier, ces règles peuvent gêner, par exemple en ajoutant une marge au-dessus de chaque carte de la grille.
Ajouter la classe not-content à un élément le soustrait à cette mise en forme,
lui et tout son contenu. C’est ce qui est fait sur la grille ci-dessus.
Le thème clair et le thème sombre
Section intitulée « Le thème clair et le thème sombre »Les couleurs écrites en dur (#fff, black…) ne s’adaptent pas au thème choisi par le lecteur.
Pour qu’un bloc reste lisible dans les deux, on utilise les variables CSS de Starlight,
dont la valeur change avec le thème :
| Variable | Usage |
|---|---|
--sl-color-text |
Couleur du texte courant |
--sl-color-bg |
Fond de la page |
--sl-color-accent, -low, -high |
Couleur principale du site : normale, atténuée (fonds), renforcée (textes) |
--sl-color-gray-1 … --sl-color-gray-7 |
Nuances de gris, du plus contrasté au plus discret |
--sl-color-green, -orange, -red, -blue, -purple (+ -low, -high) |
Couleurs sémantiques |
--sl-text-sm, --sl-text-lg, --sl-text-2xl… |
Tailles de police |
Couleurs en dur
Fond blanc fixe : détonne en thème sombre.
Variables Starlight
S’adapte au thème : essayez le sélecteur en haut de page.
Niveau 3 : une classe globale dans custom.css
Section intitulée « Niveau 3 : une classe globale dans custom.css »Pour réutiliser un style sur plusieurs pages, on le déclare une fois dans une feuille de style
chargée sur tout le site. Elle est déclarée dans astro.config.mjs avec l’option
customCss: ['./src/styles/custom.css']. Voici son contenu actuel :
/* * Styles personnalisés, chargés sur toutes les pages (option `customCss` de Starlight). * Les variables --sl-color-* suivent automatiquement le thème clair / sombre. */
/* Section mise en avant, réutilisable dans n'importe quelle page via class="section-vedette" */.section-vedette { padding: 1.5rem 2rem; border-radius: 1rem; background: linear-gradient(135deg, var(--sl-color-accent-low), transparent 70%); border-left: 6px solid var(--sl-color-accent);}
.section-vedette h3 { margin-top: 0; color: var(--sl-color-accent-high);}
/* Images du contenu (captures d'écran notamment) : cadre discret pour les détacher du fond */.sl-markdown-content img { border: 1px solid var(--sl-color-hairline); border-radius: 0.5rem;}Il suffit ensuite d’utiliser la classe, y compris dans un fichier .md :
<div class="section-vedette">
### Section mise en avant
Ce style est défini une seule fois dans `custom.css`, et utilisable sur toutes les pages.
</div>Section mise en avant
Section intitulée « Section mise en avant »Ce style est défini une seule fois dans custom.css, et utilisable sur toutes les pages.
Niveau 4 : un composant Astro
Section intitulée « Niveau 4 : un composant Astro »Quand un bloc a une structure (titre, contenu, variantes…), on en fait un composant.
Un fichier .astro réunit le HTML, des paramètres (props) et un style
automatiquement isolé : Astro réécrit les sélecteurs pour qu’ils ne s’appliquent
qu’à ce composant, sans risque de déborder sur le reste de la page.
---/* * Encadré personnalisé, utilisable en MDX : * import Encadre from '../../../components/Encadre.astro'; * <Encadre titre="Titre" couleur="purple">Contenu en **Markdown**</Encadre> */interface Props { titre: string; couleur?: 'accent' | 'green' | 'orange' | 'red' | 'blue' | 'purple';}
const { titre, couleur = 'accent' } = Astro.props;---
<section class="encadre" style={`--couleur: var(--sl-color-${couleur}); --fond: var(--sl-color-${couleur}-low);`}> <p class="titre">{titre}</p> <div class="contenu"><slot /></div></section>
<style> /* Style « scopé » : Astro le limite automatiquement à ce composant */ .encadre { position: relative; padding: 2.25rem 1.5rem 1.25rem; margin-top: 2rem; border: 2px solid var(--couleur); border-radius: 0.75rem; background: var(--fond); } .titre { position: absolute; top: -0.9rem; left: 1rem; margin: 0; padding: 0.1rem 0.75rem; border-radius: 999px; background: var(--couleur); color: var(--sl-color-black); font-weight: 700; font-size: var(--sl-text-sm); } .contenu > :global(:first-child) { margin-top: 0; }</style>Utilisation dans une page .mdx :
import Encadre from '../../../components/Encadre.astro';
<Encadre titre="Bon à savoir">Le contenu d'un composant peut contenir du **Markdown**.</Encadre>
<Encadre titre="Attention" couleur="orange">Le paramètre `couleur` change l'apparence.</Encadre>Bon à savoir
Le contenu d’un composant peut contenir du Markdown.
Attention
Le paramètre couleur change l’apparence.
Nouveau
Et ainsi de suite, avec une seule définition à maintenir.
Lequel choisir, avec Decap CMS ?
Section intitulée « Lequel choisir, avec Decap CMS ? »| Technique | Fonctionne en .md |
Confort dans le CMS |
|---|---|---|
style="…" |
✅ | Bloc HTML brut, peu lisible pour un rédacteur |
<style> dans la page |
✅ | Idem, et risque de casser la page |
Classe de custom.css |
✅ | Acceptable : un simple <div class="…"> |
Composant .astro |
❌ (MDX seulement) | Possible via des composants d’éditeur personnalisés, à configurer |