@thedigitalman/eleventy-plugin-toc-a11y
v2.1.0
Published
An 11ty plugin to generate an accessible table of contents from page headings using an 11ty filter.
Downloads
117
Maintainers
Readme
eleventy-plugin-toc-a11y
This Eleventy (11ty) plugin generates a table of contents (TOC) from page headings using an Eleventy filter.
It adds a navigation landmark with a heading and ARIA role to make it accessible[1] [2]. And creates a nested list of headings by level.
Markdown
# Fruits
## Apples
### Empire
### Fuji
### Pink Lady
## Pears
### Bartlett
### Bosc
### Starkrimson
HTML
<nav class="nav-toc" role="navigation" aria-labelledby="nav-toc">
<h2 class="nav-toc-heading" id="nav-toc">Table of contents</h2>
<ol class="nav-toc-list">
<li class="nav-toc-list-item">
<a class="nav-toc-list-item-anchor" href="#apples">Apples</a>
<ol class="nav-toc-list">
<li class="nav-toc-list-item"><a class="nav-toc-list-item-anchor" href="#empire">Empire</a></li>
<li class="nav-toc-list-item"><a class="nav-toc-list-item-anchor" href="#fuji">Fuji</a></li>
<li class="nav-toc-list-item"><a class="nav-toc-list-item-anchor" href="#pink-lady">Pink Lady</a></li>
</ol>
</li>
<li class="nav-toc-list-item">
<a class="nav-toc-list-item-anchor" href="#oranges">Pears</a>
<ol class="nav-toc-list">
<li class="nav-toc-list-item"><a class="nav-toc-list-item-anchor" href="#bartlett">Bartlett</a></li>
<li class="nav-toc-list-item"><a class="nav-toc-list-item-anchor" href="#bosc">Bosc</a></li>
<li class="nav-toc-list-item"><a class="nav-toc-list-item-anchor" href="#starkrimson">Starkrimson</a></li>
</ol>
</li>
</ol>
</nav>
Step 1: Installation
npm install @thedigitalman/eleventy-plugin-toc-a11y --save-dev
Step 2: Configuration
All headings must have an id
attribute. The plugin uses the id
attribute of the headings it finds to build the navigation.
You can do this manually, but using markdown-it
and markdown-it-anchor
make it easy.
Open your Eleventy config file (probably .eleventy.js
), use addPlugin
, and add some Markdown settings.
const eleventyPluginTOC = require( '@thedigitalman/eleventy-plugin-toc-a11y' );
const markdownIt = require( 'markdown-it' );
const markdownItAnchor = require( 'markdown-it-anchor' );
module.exports = function ( eleventyConfig ) {
// Plugins
eleventyConfig.addPlugin( eleventyPluginTOC );
// Markdown settings
eleventyConfig.setLibrary( 'md',
markdownIt().use( markdownItAnchor )
);
}
Step 3: Usage
All headings must be in proper order without skipping levels [3].
Open a layout template file and add the filter before your content. This gives you a good outline, and lets people review the TOC before reading the content.
Liquid
{{ content | toc }}
<main>
{{ content }}
</main>
Nunjucks
Always include the safe filter when using Nunjucks.
{{ content | toc | safe }}
<main>
{{ content | safe }}
</main>
Default Options
{
tags: ['h2', 'h3', 'h4', 'h5', 'h6'],
wrapper: 'nav',
wrapperClass: 'nav-toc',
heading: true,
headingClass: 'nav-toc-heading',
headingLevel: 'h2',
headingText: 'Table of contents',
listType: 'ol',
listClass: 'nav-toc-list',
listItemClass: 'nav-toc-list-item',
listItemAnchorClass: 'nav-toc-list-item-anchor'
}
| Option | Data Type | Description | Notes |
| --------------------- | --------- | -------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
| tags
| Object | An array of heading levels to include in the TOC. | Page titles (i.e. h1
) should be excluded. |
| wrapper
| String | The navigation landmark element of the TOC. | In most cases use nav
. If you replace it, be sure it’s valid HTML and accessible. |
| wrapperClass
| String | The CSS class name for the TOC parent element. | Using an empty string removes the class
attribute. |
| heading
| Boolean | Whether the TOC uses a heading element. | Using heading text for sections helps everyone. |
| headingClass
| String | The CSS class name for the TOC heading element. | Using an empty string removes the class
attribute. |
| headingLevel
| String | The level of the TOC heading element. | In most cases use h2
, but you can use h2
– h6
. If you replace it, be sure it’s valid HTML and accessible. |
| headingText
| String | The TOC heading element text. | Keep it concise and relevant. |
| listType
| String | The type of list for navigation items. | Use ol
or ul
. Other elements won’t work. |
| listClass
| String | The CSS class name for the list. | Using an empty string removes the class
attribute. |
| listItemClass
| String | The CSS class name for each list item. | Using an empty string removes the class
attribute. |
| listItemAnchorClass
| String | The CSS class name for each anchor in a list item. | Using an empty string removes the class
attribute. |
Override Default Options
You can override the default options in the Eleventy config file or inline.
Eleventy config file
eleventyConfig.addPlugin( pluginToC, {
wrapperClass: 'toc',
headingClass: 'toc-heading',
headingText: 'Topics',
listType: 'ul'
});
Inline (Liquid)
{{ content | toc(wrapperClass='toc',headingClass='toc-heading',headingText='Topics',listType='ul') }}
Inline (Nunjucks)
{{ content | toc(wrapperClass='toc',headingClass='toc-heading',headingText='Topics',listType='ul') | safe }}
References
- 4.3.6 Navigation | WAI-ARIA Authoring Practices 1.2 W3C ↑
- Navigation Landmark: ARIA Landmark Example W3C ARIA Authoring Practices Task Force ↑
- H42: Using h1-h6 to identify headings Techniques for WCAG 2.1 ↑