Consistent attribute syntax

Eventually, the spec should specify a consistent way to add attributes to at least the following elements: headers, images, code blocks (and maybe even tables, block quotes and inline code and quotes). The most important attributes are certainly id (to enable links to those elements) and class (for styling) which might have shortcuts like #myId and .myClass but other attributes (like width and height for images) are useful as well.

Stmd currently specifies info strings for code blocks. I think this is setting a dangerous precedent that should not be made lightly. Do we really want the first word in an attribute list always to be the class? This would consequently result in headers that are something like ### myHeader ###myClass id=myId.

To enable a generic attribute syntax, I would therefore prefer the one that Pandoc, Markdown Extra and Kramdown use: {#id .class key=val key2="val 2"}, as in:

### myHeader {#myId}

![altText](myImage.png){.myClass width=40 height=50}



``` {.ruby}

paragraph with right-to-left text

> this is a blockquote with the class "pullquote"

1. first item
2. second item

A few more use cases:

Edit: I have put a draft spec together and made a pull request (although discussion should stay here).

Div block syntax
Mermaid - Generation of diagrams and flowcharts from text in a similar manner as markdown
Beyond Markdown
Info strings elsewhere
Links with attributes like target, class, etc
Embedded audio and video
Embedded audio and video
Info strings for suffixed headings
Info strings for suffixed headings
A problem with backtick code fences
Generic directives/plugins syntax
Floating images
Generic directives/plugins syntax
Turning empty link definitions into anchors
Metadata in documents
What could a "spoiler tag" extension look like?
Block Directives
Block Directives
Generic directives/plugins syntax
Css classes on any block
Css classes on any block
Code Blocks Extension for filenames and line numbers
Internal references (anchors) with multiple types
Info strings elsewhere
Anchors in markdown
Creating figures with a caption depending on context (no markup natural convention)
The P tag that holds the IMG tag needs a unique class
New features? colorizing?
Revisting Underline & Healthcare Documents
Generic directives/plugins syntax
Support for image dimensions
Floating images
Generic directives/plugins syntax
Floating images
Generic directives/plugins syntax
Fenced code blocks should add class to `code` rather than `pre`, matching the HTML best practice
Anchors in markdown
Explicit RTL indication in pure Markdown
Support for image dimensions
Make CommonMark safe by default?
Support for align right?
Markdown Colour Support
Support for image dimensions
Fenced block but not fenced code block
Embedded audio and video
Marking code blocks fragments bold / italic
MultiMarkdown Link and Reference Image Attributes
Fenced Block Types, Generic Extension/Webcomponents, and fallback handling
Mermaid - Generation of diagrams and flowcharts from text in a similar manner as markdown

I agree. But in this very situation where you have a context dependency at an object (e.g. when writing code in a specific language) it would make more sense to me to define it directly at the object initialisation. And I guess classes are the best way to tell context dependencies. But I also agree that just writing the class name after the initialisation is not the right way to do it. What about an abbreviation just for classnames Like the following example:

def foo(x)

the same as:

def foo(x)

This is very developer-y and a syntax that people who are not developers would not understand. I think it is perfectly fine to do this for fenced code blocks, but don’t see a point in doing it for other elements.


Markdown should be easy to write above all … If you need rich meta-data capabilities, remember that HTML is still supported :wink: IMO this is a bad road to take and will just end up making a new kind of XML


I agree that markdown should first and foremost be simple and email-like. But adding attributes is an advanced feature that most people will never use but is invaluable for the few of us that do. That’s why I think having the {...} is a kind of nice way of saying “this is stuff that’s not going to be visible and if you don’t understand it, don’t worry about it”.

Also, there seem to be many requests for even more exotic use-cases. Allowing for standardized attributes seems like a good place to avoid having other markdown processors print the characters intended for customized markdown processors (because inevitably some users will continue to customize processors). For example, someone proposed ![](image.png 700x700) for image dimensions, but in many markdown processors this will result in src="image.png%20700x700". Delegating custom attributes inside curly braces solves that.


I agree that it would be great to have a standard meta-data escape, but it winds up being pretty HTML-specific.

However, I tend to use a lot of HTML in my markdown, particularly for links. I like, for instance, being able to set rel=“external” for an <a> tag or classes for <img> tags.


What about an fallback. I do like to be able to have attributes but I also find it more complicated to have extra braces to add a class. And for some elements it would be even okay to allow setting a class without the dot which I don’t find a good solution.

So I would like to have this working:

#.classname Title

Long version but same thing
# {.classname} Title
![Image](/image) {.classname}

#{.classname} Title

same thing
What about that? :smile:

To me the difference between adding classes or IDs to stuff like headers, images and paragraphs versus the language declaration on fenced code blocks is that the language declaration on code blocks doesn’t necessarily have to be a class. This is just how it’s been implemented in HTML so far, but the declaration goes way beyond just deciding the class. It decides the type of content in the code block and that doesn’t translate directly to a class on any other element.

As others have said before me in this thread, I believe we should keep advanced syntax like this out of Markdown, specifically due to the support of HTML and the simplicity of currently writing Markdown.


Wouldn’t that conflict with a heading?:

# Heading #id .class

mex, wasn’t the original markdown about supporting html? Couldn’t implementations not for html just ignore/remove such information if it’s not used?

mb21’s suggestion is quite the simple, readable and logical extension here that I believe should be added because those that don’t need it simply don’t need to use it, but it’s extremely powerful for those that do. There is high demand for this since a couple of small additions saves resorting to pure html, which can be much more long-winded/complicated. It’s not as far fetched/complicated a syntax as some of you seem to think, just attributes surrounded by curly braces, quite readable.

Perhaps the image one though could require no space in between the parenthesis and the curly braces so that curly braces could be used normally with a space separating it:

![img](img.png){.class} instead of ![img](img.png) {.class}

(In contrast to say headers where curly braces are more rarely used than in body text.)

1 Like

Isn’t readability by humans one of the Markdown’s best advantages? If you need to specify many attributes readability will suffer anyway IMO, so why not use a HTML?

P.S. Id and class attributes would be nice to have, though. It’s a common case when you need to have some links within a documentation, that point to some blocks within the same page.

Again, if you don’t need it, then readability doesn’t suffer here with this addition. This allows for very easy and flexible edits to already existing documents if you want to add some attributes, as opposed to changing it to html itself.

It’s a logical extension since many already use it in pandoc markdown’s fenced code attributes extension, and having it for other elements such as headers, images and tables makes sense too since it is often the case you may want/need it. For example, aligning a particular image differently to the rest. Whereas without it, you’d have to resort to html syntax to do what should really be simple and put into the spec. Makes the document look quite inconsistent too.

I have no problem with wrapping div block elements for this, but the suggested syntax is much nicer.

1 Like

There’s no need to explicitly add the height and width of an image in Markdown. Use a server side script to get the dimensions from the image file and add these to the HTML after it has been converted from Markdown. This will make the Markdown much simpler to read and easier to write.

As for classes and IDs, how about some specific real world use case examples? I provided a solution for image alignments in 266 that does not extend the Markdown syntax. I would be very hesitant to add IDs to Markdown as you’re moving into presentation territory, the realm of CSS. There’s often a better way implementing advanced features that does not clutter up the content with metadeta.

1 Like

I disagree, adding IDs/classes/attributes is something that’s normally done in the html itself, css only controls the presentation if needed.

Your example in 266 doesn’t need an extended syntax because you’re simply selecting images based on a pattern (odd/even), not an arbitrary selection based on the image itself which is only possible with the addition of an id or class.

There are lots of extras in HTML that make sense from a web developer perspective, but create confusion if you’re not a developer. If these attributes only exist so that the presentation can be changed for specific elements then you’re extending Markdown solely for presentation reasons. Why is it the role of the content writer to specify this?

The image syntax is complex enough for non-developers without adding classes too. We already have a unique identifier for images - the file name. Perhaps this could be used to save the content writer from making up an additional ID? You could do the same for headings too if each heading is unique.

1 Like

The point is that IDs/classes/attributes are part of the content, not presentation. Since they should be describing the content semantically rather than just providing stylistic information.

You shouldn’t do things like add class left or right like you do in your example from 266, but add a class that describes more specifically what type of image it actually is, content-wise, and then in the css refer to that class when doing align: left/right.

The curly braces section should be optional, therefore, if users don’t need it, it doesn’t complicate the syntax for them.

The case for having the content writer specify the id/class would be because the elements themselves are inherently (content-wise, semantically) different than the rest of the elements which of are of the same type. The content writer needs to somehow be able to specify this so that the presentation of it can be changed/controlled if desired.

The filename as an unique identifier for images doesn’t work because you can’t select that with css. Even if you could, your css would have to include image file names, which is inflexible since a filename might change. Classes can be applied to multiple images and don’t have to change with a filename change.

It does work for headings (generating IDs from the heading text itself) since headings (of the same type) are all usually styled the same way. The reason for unique identifiers for headings is usually due to anchoring.

Original post says to change syntax from:

def foo(x)
  return 3


``` {.ruby}

but that obviously has backward compatiblity issues since many already use the former syntax. I think what mb21 proposes can still be achieved though:

  • For code blocks, keep the ability to have the former syntax.

    • If ID’s or other attributes are needed, you’ll need to surround them in curly braces after the language class/declaration.
    • This may be a needed differentiation for code blocks since, if 136 is accepted, the initial language declaration (ruby in this case) would be changed to language-ruby, instead of just a ruby class if .ruby was in curly braces.
      • And if you don’t want this change from ruby to language-ruby for whatever reason (if you don’t want a language declaration at all), you can just omit it, but you’ll have to use curly braces to add IDs/classes/attributes to differentiate between that.
  • But for headings or other elements, where the attributes would need to be added on the same line as the heading/content itself, curly braces should be required for adding attributes so that it doesn’t conflict with normal heading/content text.

Edit: 136 has been accepted, so the old syntax definitely needs to stay otherwise there would be conflicts.


I think we need to get away from thinking about Markdown directly correlating to HTML and CSS. While Markdown ultimately compiles to HTML, it doesn’t need to do so directly.

With this particular example, you could add IDs to the images after the Markdown is converted to HTML. The IDs could be generated from the filename. This is inflexible as the filename might change, but the ID might change too. I’m sure you could come up with a script to keep them in sync if it was going to be a problem.

I can see this being hard to implement without classes. You could resolve it by having a separate system in your CMS where you drag and drop images into groups that are linked to CSS classes. But I understand the general point you’re making: the current Markdown syntax on it’s own is not sufficient for some advanced scenarios.

This is advanced, layout specific stuff. I don’t think it should be the core spec, but an extension. There are other ways you might implement particular image properties. Properties could be defined for each image in the CMS. Or lots of small Markdown text boxes and images could be rearranged with drag and drop. Etc.

With the Ruby fenced code block example, the former syntax currently used by GitHub and Discourse is clearly more readable. And as a writer, I’m not thinking about whether it translates into a class behind the scenes. I’m thinking about writing a code block in the Ruby programming language. I want the syntax to be as simple and lightweight as possible. The fact that it compiles into a class is an implementation detail that I only care about if I understand HTML. (Edit: I see “keep the ability to have the former syntax” is a consideration - good).

1 Like

That last part about the ruby class staff was more directed at the original poster’s recommendations, not you, sorry! The hr line isn’t very visible. The whole point of that part was due to retaining the former syntax too. :slight_smile:

And yeah, I guess having some way to add IDs/classes/attributes to some types of elements is just really useful. There are probably other ways but it makes the most sense for the content writer to specify the info if they desire. It’s also much easier than separately maintaining the classifications, as with your cms drag drop interface example.

And if the writer doesn’t want/need to, when it’s not semantically relevant, then they need not worry about it or be affected by it! I wouldn’t say it’s layout specific though since that implies it’s only related to presentation, which it shouldn’t really be.

Not sure if it’s even that advanced either, as this is already a widely used feature with the headings (for example in markdown extra/pandoc’s markdown), but I guess that’s just my opinion of it.

Well john said that he’d like to focus on just the markdown as a method to produce html for now at least. I’ll try to edit in a link to where he says it when/if I find it (assuming it’s not a false memory).

But I certainly know that other output formats for markdown exist. I literally have hundreds of pdfs produced from markdown documents (nearing one thousand soon). Nevertheless, I understand that the primary, default format is html, the current spec itself always refers to html output, so I see no reason for that to hinder having this proposal in the spec. If another output format doesn’t need such information, then it can be easily removed/ignored.

I’m coming at this from a usability perspective, so while creating a drag and drop UI might be more difficult for the web developer, from the user’s perspective it could be simpler to operate. I believe that regular Markdown for emphasis, links, and images is actually simpler than using a WYSIWYG editor (once you learn the basic syntax). I’m less sure about some of the proposals I’ve seen here which seem more developer-y. So as a CMS developer, I would be hesitant to allow users to specify classes.

[quote=“rwzy, post:17, topic:272”]And if the writer doesn’t want/need to, when it’s not semantically relevant, then they need not worry about it or be affected by it! I wouldn’t say it’s layout specific though since that implies it’s only related to presentation, which it shouldn’t really be.

Another way of thinking about this is asking how portable any new syntax is. If we were to copy/paste the Markdown to a different website with a different layout, would the IDs/classes still be relevant? What uses do the IDs/classes have besides providing a semantic link to layout/presentation features?

No it wouldn’t. It would be much easier to specify it in the text itself than separately handling such information. Your content would be split up in two different places, when it shouldn’t be.

The syntax proposed here is just a pair of curly braces surrounding your attributes.

IDs are also commonly used for anchoring.

The content would already be split in two places, because the image file itself is not part of the text. I’m thinking of a CMS where the images are displayed on the page next to the content (which contains the ![]() tag to reference that image and all of it’s properties). The image properties could be customised alongside that image file. This would also keep the image properties specific to the particular website; if the rest of the Markdown was copied, the properties wouldn’t automatically be copied too. I see that as feature if they are presentational properties.

Anchors in headings could be auto-generated, so we wouldn’t need an explicit syntax. Any other examples?

I think I covered your other points in 266.