Add classes, identifiers and attributes to your markdown with {} curly brackets, similar to pandoc's header attributes

Usage no npm install needed!

<script type="module">
  import markdownItAttrs from '';


markdown-it-attrs Build Status npm version Coverage Status

Add classes, identifiers and attributes to your markdown with {.class #identifier attr=value attr2="spaced value"} curly brackets, similar to pandoc's header attributes.

Example input:

# header {.style-me}
paragraph {data-toggle=modal}


<h1 class="style-me">header</h1>
<p data-toggle="modal">paragraph</p>

Works with inline elements too:

paragraph *style me*{.red} more text


<p>paragraph <em class="red">style me</em> more text</p>

And fenced code blocks:

```python {data=asdf}
nums = [x for x in range(10)]


<pre><code data="asdf" class="language-python">
nums = [x for x in range(10)]

You can use .. as a short-hand for css-module=:

Use the css-module green on this paragraph. {}


<p css-module="green">Use the css-module green on this paragraph.</p>

Also works with spans, in combination with the markdown-it-bracketed-spans plugin (to be installed and loaded as such then):

paragraph with [a style me span]{.red}


<p>paragraph with <span class="red">a style me span</span></p>


$ npm install --save markdown-it-attrs


var md = require('markdown-it')();
var markdownItAttrs = require('markdown-it-attrs');

md.use(markdownItAttrs, {
  // optional, these are default options
  leftDelimiter: '{',
  rightDelimiter: '}',
  allowedAttributes: []  // empty array = all attributes are allowed

var src = '# header {.green #id}\nsome text {with=attrs and="attrs with space"}';
var res = md.render(src);


demo as jsfiddle


A user may insert rogue attributes like this:


If security is a concern, use an attribute whitelist:

md.use(markdownItAttrs, {
  allowedAttributes: ['id', 'class', /^regex.*$/]

Now only id, class and attributes beginning with regex are allowed:

text {#red .green regex=allowed onclick=alert('hello')}


<p id="red" class="green" regex="allowed">text</p>


When class can be applied to both inline or block element, inline element will take precedence:

- list item **bold**{.red}


<li>list item <strong class="red">bold</strong></li>

If you need the class to apply to the list item instead, use a space:

- list item **bold** {.red}


<li class="red">list item <strong>bold</strong></li>

If you need the class to apply to the <ul> element, use a new line:

- list item **bold**


<ul class="red">
<li>list item <strong>bold</strong></li>

If you have nested lists, curlys after new lines will apply to the nearest <ul> or <ol>. You may force it to apply to the outer <ul> by adding curly below on a paragraph by its own:

- item
  - nested item {.a}



<ul class="c">
    <ul class="b">
      <li class="a">nested item</li>

This is not optimal, but what I can do at the momemnt. For further discussion, see

Similar for tables, attributes must be two new lines below:

header1 | header2
------- | -------
column1 | column2



<table class="special">

If you need finer control, decorate might help you.

Custom rendering

If you would like some other output, you can override renderers:

const md = require('markdown-it')();
const markdownItAttrs = require('markdown-it-attrs');


// custom renderer for fences
md.renderer.rules.fence = function (tokens, idx, options, env, slf) {
  const token = tokens[idx];
  return  '<pre' + slf.renderAttrs(token) + '>'
    + '<code>' + token.content + '</code>'
    + '</pre>';

let src = [
  '```js {.abcd}',
  'var a = 1;',



<pre class="abcd"><code>var a = 1;

Read more about custom rendering at markdown-it.

Custom blocks

markdown-it-attrs will add attributes to any token.block == true with {}-curlies in end of For example, see markdown-it/rules_block/fence.js which stores text after the three backticks in fenced code blocks to

Remember to render attributes if you use a custom renderer.

Custom delimiters

To use different delimiters than the default, add configuration for leftDelimiter and rightDelimiter:

md.use(attrs, {
  leftDelimiter: '[',
  rightDelimiter: ']'

Which will render

# title [.large]


<h1 class="large">title</h1>


MIT © Arve Seljebu