Adding classes to specific markdown elements in Vuepress

Targeting elements in markdown generated by Vuepress can sometimes be challenging because you're likely to be including Vue components within your markdown files, so individual blocks of markdown are unlikely to be wrapped in a dedicated container div.

Update

Since writing the original post, I have packaged this functionality into a VuePress Plugin. Install the package ...

npm i @silvanite/vuepress-plugin-markdown-classes

Load the plugin in your .vuepress/config.js

module.exports = {
    ...
    "plugins": [
        "@silvanite/markdown-classes"
    ]
}

Full documentation is avilable on the Github Repository.

Original Post

You can use the extendMarkdown within your .vuepress/config.js to append classes to any markdown blocks so that you can target them in your css.

module.exports = {
    ...
    markdown: {
        extendMarkdown: md => {
            [
                'bullet_list_open',
                'heading_open',
                'image',
                'link_open',
                'paragraph_open',
            ].map((rule) => {
                md.renderer.rules[rule] = (tokens, idx, options, env, slf) => {
                    if (!tokens[idx].attrs) tokens[idx].attrs = []
                    tokens[idx].attrs.push([ 'class', `md-${rule}` ])
                    return slf.renderToken(tokens, idx, options)
                }
            });
        }
    },
    ...
}

This script will add a class named md-{hook_name} to the html rendered by the markdown. E.g.

<p class="md-paragraph_open">Markdown content</p>

You can find what hooks to target from the markdown-it repository by looking in the various folders and files.

// Look for these type of entries to find available hooks to target

token = state.push('ordered_list_open', 'ol', 1);

Copyright 2019 Marco Mark