Table des matières
Génération automatique de la table des matières à partir des titres de la page avec scroll spy et défilement fluide.
Table des matières
Génération automatique de la table des matières à partir des titres de la page avec mise en évidence de la section active.

Le panneau On this page à droite est la table des matières, construite à partir des titres h2–h6 de la page.
Vue d’ensemble
- Auto-générée : Extraite des titres h2-h6
- Scroll Spy : Met en évidence la section courante
- Défilement fluide : Navigation animée
- Responsive : Barre latérale sur ordinateur, offcanvas sur mobile
Implémentation
Modèle d’inclusion
{% include content/toc.html %}
Génération de la TOC
L’include toc.html utilise la TOC intégrée de Kramdown :
<nav id="TableOfContents" class="toc">
<h2 class="toc-title">On This Page</h2>
{{ content | toc_only }}
</nav>
Ou une extraction manuelle :
<nav id="TableOfContents">
<ul class="toc-list">
{% for heading in page.content | split: '<h' %}
{% if heading contains 'id="' %}
{% assign id = heading | split: 'id="' | last | split: '"' | first %}
{% assign level = heading | slice: 0, 1 %}
{% assign text = heading | split: '>' | last | split: '<' | first %}
<li class="toc-item toc-level-{{ level }}">
<a href="#{{ id }}" class="toc-link">{{ text }}</a>
</li>
{% endif %}
{% endfor %}
</ul>
</nav>
Configuration
Activer la TOC
Dans le front matter :
---
toc: true
---
Ou à l’échelle du site dans _config.yml :
defaults:
- scope:
type: docs
values:
toc: true
Niveaux de titres
Configurer les titres à afficher :
toc:
min_level: 2 # Start at h2
max_level: 4 # End at h4
Style
Styles de base
.toc {
position: sticky;
top: 80px;
max-height: calc(100vh - 100px);
overflow-y: auto;
}
.toc-title {
font-size: 0.875rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.05em;
margin-bottom: 1rem;
}
.toc-list {
list-style: none;
padding: 0;
margin: 0;
}
.toc-link {
display: block;
padding: 0.25rem 0;
color: var(--bs-secondary);
text-decoration: none;
font-size: 0.875rem;
border-left: 2px solid transparent;
padding-left: 0.75rem;
}
.toc-link:hover {
color: var(--bs-primary);
}
.toc-link.active {
color: var(--bs-primary);
border-left-color: var(--bs-primary);
font-weight: 500;
}
Niveaux imbriqués
.toc-level-3 {
padding-left: 1rem;
}
.toc-level-4 {
padding-left: 2rem;
font-size: 0.8125rem;
}
Scroll Spy
Intersection Observer
function initScrollSpy() {
const headings = document.querySelectorAll('h2[id], h3[id], h4[id]');
const tocLinks = document.querySelectorAll('.toc-link');
const observer = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
tocLinks.forEach((link) => link.classList.remove('active'));
const activeLink = document.querySelector(
`.toc-link[href="#${entry.target.id}"]`
);
activeLink?.classList.add('active');
}
});
},
{ rootMargin: '-20% 0% -70% 0%' }
);
headings.forEach((heading) => observer.observe(heading));
}
Défilement fluide
Méthode CSS
html {
scroll-behavior: smooth;
}
Méthode JavaScript
document.querySelectorAll('.toc-link').forEach((link) => {
link.addEventListener('click', (e) => {
e.preventDefault();
const targetId = link.getAttribute('href').slice(1);
const target = document.getElementById(targetId);
const headerOffset = 80;
const position = target.offsetTop - headerOffset;
window.scrollTo({
top: position,
behavior: 'smooth'
});
history.pushState(null, '', `#${targetId}`);
});
});
Comportement responsive
Ordinateur
La TOC apparaît dans la barre latérale droite :
<aside class="d-none d-lg-block">
{% include content/toc.html %}
</aside>
Mobile
TOC en offcanvas (voir Mobile TOC) :
<div class="offcanvas offcanvas-end d-lg-none" id="tocSidebar">
{% include content/toc.html %}
</div>
Accessibilité
Attributs ARIA
<nav id="TableOfContents"
aria-label="Table of contents"
role="navigation">
Navigation au clavier
- Tabulation à travers les liens de la TOC
- Entrée pour naviguer vers la section
- Le focus se déplace vers le titre
Dépannage
La TOC ne se génère pas
- Vérifiez que les titres ont des ID
- Vérifiez
toc: truedans le front matter - Assurez-vous d’utiliser le processeur Kramdown
Le Scroll Spy ne fonctionne pas
- Vérifiez que les ID des titres correspondent aux href de la TOC
- Vérifiez la prise en charge d’Intersection Observer
- Testez les marges de l’observer
Problèmes de style
- Vérifiez le positionnement sticky
- Vérifiez le z-index
- Testez le comportement d’overflow
Voir aussi
Voir aussi
- [[Features]]
- [[Mobile TOC Floating Action Button]]
- [[Sidebar Navigation System]]