2.1.0 • Published 3 years ago

@thedigitalman/eleventy-plugin-toc-a11y v2.1.0

Weekly downloads
64
License
ISC
Repository
github
Last release
3 years ago

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'
}
OptionData TypeDescriptionNotes
tagsObjectAn array of heading levels to include in the TOC.Page titles (i.e. h1) should be excluded.
wrapperStringThe navigation landmark element of the TOC.In most cases use nav. If you replace it, be sure it’s valid HTML and accessible.
wrapperClassStringThe CSS class name for the TOC parent element.Using an empty string removes the class attribute.
headingBooleanWhether the TOC uses a heading element.Using heading text for sections helps everyone.
headingClassStringThe CSS class name for the TOC heading element.Using an empty string removes the class attribute.
headingLevelStringThe level of the TOC heading element.In most cases use h2, but you can use h2h6. If you replace it, be sure it’s valid HTML and accessible.
headingTextStringThe TOC heading element text.Keep it concise and relevant.
listTypeStringThe type of list for navigation items.Use ol or ul. Other elements won’t work.
listClassStringThe CSS class name for the list.Using an empty string removes the class attribute.
listItemClassStringThe CSS class name for each list item.Using an empty string removes the class attribute.
listItemAnchorClassStringThe 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

  1. 4.3.6 Navigation | WAI-ARIA Authoring Practices 1.2 W3C
  2. Navigation Landmark: ARIA Landmark Example W3C ARIA Authoring Practices Task Force
  3. H42: Using h1-h6 to identify headings Techniques for WCAG 2.1