• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1title: Attribute Lists Extension
2
3# Attribute Lists
4
5## Summary
6
7The Attribute Lists extension adds a syntax to define attributes on the various
8HTML elements in markdown's output.
9
10This extension is included in the standard Markdown library.
11
12## Syntax
13
14The basic syntax was inspired by Maruku's Attribute Lists feature (see [web archive][Maruku]).
15
16[Maruku]: https://web.archive.org/web/20170324172643/http://maruku.rubyforge.org/proposal.html
17
18### The List
19
20An example attribute list might look like this:
21
22```text
23{: #someid .someclass somekey='some value' }
24```
25
26A word which starts with a hash (`#`) will set the id of an element.
27
28A word which starts with a dot (`.`) will be added to the list of classes
29assigned to an element.
30
31A key/value pair (`somekey='some value'`) will assign that pair to the element.
32
33Be aware that while the dot syntax will add to a class, using key/value pairs
34will always override the previously defined attribute. Consider the following:
35
36```text
37{: #id1 .class1 id=id2 class="class2 class3" .class4 }
38```
39
40The above example would result in the following attributes being defined:
41
42```text
43id="id2" class="class2 class3 class4"
44```
45
46HTML includes support for some attributes to be a single term, like `checked`, for example. Therefore, the attribute
47list `{: checked }` would result in `checked` if the [output format](../reference.md#output_format) is `html` or
48`checked="checked"` if the output format is `xhtml`.
49
50Curly braces can be backslash escaped to avoid being identified as an attribute list.
51
52```text
53\{ not an attribute list }
54```
55
56Opening and closing curly braces which are empty or only contain whitespace are ignored whether they are escaped or
57not. Additionally, any attribute lists which are not located in the specific locations documented below are ignored.
58
59The colon after the opening brace is optional, but is supported to maintain consistency with other implementations.
60Therefore, the following is also a valid attribute list:
61
62```text
63{ #someid .someclass somekey='some value' }
64```
65
66In addition, the spaces after the opening brace and before the closing brace are optional. They are recommended as
67they improve readability, but they are not required.
68
69The Attribute List extension does not have any knowledge of which keys and/or values are valid in HTML. Therefore, it
70is up to the document author to ensure that valid keys and values are used. However, the extension will escape any
71characters in the key which are not valid by replacing them with an underscore. Multiple consecutive invalid
72characters are reduced to a single underscore.
73
74### Block Level
75
76To define attributes for a block level element, the attribute list should
77be defined on the last line of the block by itself.
78
79```text
80This is a paragraph.
81{: #an_id .a_class }
82```
83
84The above results in the following output:
85
86```html
87<p id="an_id" class="a_class">This is a paragraph.</p>
88```
89
90An exception is headers, as they are only ever allowed on one line.
91
92```text
93A setext style header {: #setext}
94=================================
95
96### A hash style header ### {: #hash }
97```
98
99The above results in the following output:
100
101```html
102<h1 id="setext">A setext style header</h1>
103<h3 id="hash">A hash style header</h3>
104```
105
106!!! seealso "See Also"
107    By default, the [Fenced Code Blocks](./fenced_code_blocks.md#attributes) extension includes limited support for
108    attribute lists. To get [full support](./fenced_code_blocks.md#keyvalue-pairs), both extensions must be enabled.
109
110### Inline
111
112To define attributes on inline elements, the attribute list should be defined
113immediately after the inline element with no white space.
114
115```text
116[link](http://example.com){: class="foo bar" title="Some title!" }
117```
118
119The above results in the following output:
120
121```html
122<p><a href="http://example.com" class="foo bar" title="Some title!">link</a></p>
123```
124
125If the [tables](./tables.md) extension is enabled, attribute lists can be defined on table cells. To differentiate
126attributes for an inline element from attributes for the containing cell, the attribute list must be separated from
127the content by at least one space and be defined at the end of the cell content. As table cells can only ever be on
128a single line, the attribute list must remain on the same line as the content of the cell.
129
130```text
131| set on td    | set on em   |
132|--------------|-------------|
133| *a* { .foo } | *b*{ .foo } |
134```
135
136The above example results in the following output:
137
138```html
139<table>
140  <thead>
141    <tr>
142      <th>set on td</th>
143      <th>set on em</th>
144    </tr>
145  </thead>
146  <tbody>
147    <tr>
148      <td class="foo"><em>a</em></td>
149      <td><em class="foo">b</em></td>
150    </tr>
151  </tbody>
152</table>
153```
154
155Note that in the first column, the attribute list is preceded by a space; therefore, it is assigned to the table cell
156(`<td>` element). However, in the second column, the attribute list is not preceded by a space; therefore, it is
157assigned to the inline element (`<em>`) which immediately preceded it.
158
159Attribute lists may also be defined on table header cells (`<th>` elements) in the same manner.
160
161### Limitations
162
163There are a few types of elements which attribute lists do not work with. As a reminder, Markdown is a subset of HTML
164and anything which cannot be expressed in Markdown can always be expressed with raw HTML directly.
165
166__Code Blocks:__
167
168:   Code blocks are unique in that they must be able to display Markdown syntax. Therefore, there is no way to
169    determine if an attribute list is intended to be part of the code block or intended to define attributes on the
170    wrapping element. For that reason, the extension ignores code blocks. To define attributes on code blocks, the
171    [codehilite] and [fenced code blocks] extensions provide some options.
172
173[codehilite]: code_hilite.md
174[fenced code blocks]: fenced_code_blocks.md
175
176__Nested Elements:__
177
178:   Markdown provides mechanisms for nesting various block level elements within other elements. However, attribute
179    lists only ever get applied to the immediate parent. There is no way to specify that an attribute list should be
180    applied some number of levels up the document tree. For example, when including an attribute list within a
181    blockquote, the attribute list is only ever applied to the paragraph the list is defined in. There is no way to
182    define attributes on the `blockquote` element itself.
183
184__Implied Elements:__
185
186:   There are various HTML elements which are not represented in Markdown text, but only implied. For example, the
187    `ul` and `ol` elements do not exist in Markdown. They are only implied by the presence of list items (`li`). There
188    is no way to use an attribute list to define attributes on implied elements, including but not limited to the
189    following: `ul`, `ol`, `dl`, `table`, `thead`, `tbody`, and `tr`.
190
191## Usage
192
193See [Extensions](index.md) for general extension usage. Use `attr_list` as the
194name of the extension.
195
196This extension does not accept any special configuration options.
197
198A trivial example:
199
200```python
201markdown.markdown(some_text, extensions=['attr_list'])
202```
203