Consistent attribute syntax

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.

The attributes would be split from the text which refers to the image (![image](src)), and rather reside on the cms’ database or whatever. And by the following I get that that’s exactly what’d you prefer:

But my point was always that the attributes are not always just presentational, but also inherent properties of the content. So that they shouldn’t be separated and still be copied over. So that the other system can also present the differences specified by the attributes if they so desire/think it’s meaningful to do so.

If auto-generation of heading anchors is accepted into the spec, then it’s most imperative that there’s a custom method to override them, in case of conflicts between two same IDs. The syntax proposed here makes the most sense as it’s widely used already, so minimal backwards compatibility issues.

  • Indicating rel links.
  • Indicating dir, at least for the code blocks example.

FYI: So far this is the kind of attribute syntax that we are agreeing upon in Generic directives/plugins syntax

Is this what you guys are ultimately talking about in terms of consistency in attribute?

Url Links

 [description](url){#myId .myClass  key=val key2="val 2"}

Embedded Media

!mediaType[description](url){#myId .myClass key=val key2="val 2"}
  • assumed to be image if mediaType left blank

  • syntactic sugar ( content of () handled by mediaType handler/extension):

      ![](file.mp4 "video title" 80x10 )
     is equivalent to typing: 
      !video[](file.mp4){title="video title" width=80 height=10}

Extension Directives (For extra extensions!):

@name[content](arg){#myId .myClass key=val key2="val 2"}
  • name :~ extention name


@@@name[content](arg){#myId .myClass key=val key2="val 2"}
    >>extension code/content to process here<<


`<someCodeHere>`{#myId .myClass key=val key2="val 2"}

Shorthand version:


fenced code:

``````{#myId .myClass  key=val key2="val 2"}

short hand version:



# HeaderTextHere # {#myId .myClass key=val key2="val 2"}

################## {#myId .myClass key=val key2="val 2"}

~~~~~~~~~~~~~~~~~~ {#myId .myClass key=val key2="val 2"}

------------------ {#myId .myClass key=val key2="val 2"}

================== {#myId .myClass key=val key2="val 2"}

Alt Possibility: wonder if we could include something in [] below… maybe summery?:

### HeaderTextHere ### [Short Summary of content]{#myId .myClass key=val key2="val 2"}

Edit: RWZY suggested a header example

1 Like

As long as the extension directives part is proposed to be an extension and not in the core, I’m okay with it. Except:

  • Have the same syntax proposed for headings too, to be able to specify custom anchors and such. (You didn’t list headings as an example.)

  • 136 got accepted.

This means that the shorthand inline code example:


turns into:

<code class="language-myClass">code</code>

instead of:

<code class="myClass">code</code>

Same with the code block example. But I don’t think it’s a problem since it follows the html spec to do that. I’m just clarifying that if you want to actually just indicate myClass instead of language-myClass, you will have have to use curly braces as such:


  • Also, in your fenced code block examples, you use six backticks, but I’m assuming the same numbering rules apply as already outlined in the spec?

yea I’m not really counting back ticks, since that is not the point of the discussion.

I think the syntax for the extension directives should be implemented as core as a way for other extensions to cleanly hook into it. However the core should not include any extensions by default.

Your code block HTML representation proposal makes sense. I’m just defining the commonmark syntax

if you want to actually just indicate myClass instead of language-myClass, you will have have to use curly braces as such:

Oh, and yes this does make sense, since {} can be seen as ‘explicit’ rather than implicit without the curly braces.


is just syntactic sugar (In human written language: Shorthand notation. E.g. “Don’t” ) for

 `````` {.language-ruby}

(Note: this gets rather long, but I hope that it’s a start towards something useful.)

This is an important feature to have, since without it there’s absolutely no way to style individual documents differently. If I want a particular element to act a certain way, I have to change it entirely into HTML instead of just adding a small {attributes} declaration to my existing Markdown. Human-readability is key here, and we all agree that raw HTML within a Markdown document is just plain ugly.

An argument exists that it looks too “developer-ey” (most likely stemming from the fact that it uses curly braces and can be used for CSS), but that’s ignoring one fact: users that don’t need the feature aren’t going to stumble across it accidentally. Nobody’s just going to randomly type # h1 {id="header"} without first needing that syntax and looking it up, and therefore they won’t be bothered by it. Even if they read a document using that syntax, it’s fairly obvious that whatever gets typed within the curly braces doesn’t get visibly rendered to the document (if they even bother to check).

I agree that we need to keep the language specifier for code blocks, and I especially support the notion that we look at it as “syntactic sugar” for the more verbose curly brace format.

A suggested start for the spec:

  1. Curly braces define attributes on an element:
    {class="hello" id="greeting"}

  2. Classes can be written shorthand by prefixing a word with a dot:
    {.shorthand-class .another-class}

  3. IDs can be written shorthand by prefixing a word with a pound sign:

  4. Shorthand and longhand forms cannot exist for the same attribute at the same time:
    {class="not-allowed" .nope}

  5. On a fenced code block, the first word after the opening fence will be considered shorthand for the following (where x is the first word):
    {class="language-x"} or its equivalent: {.language-x}

  6. ID uniqueness will not be enforced by the Markdown parser (too problematic; should discuss)

  7. An attribute declaration must directly follow the declaration of another element type (inline or block) without any intermediate spaces. Attribute declarations can be placed on any element in a Markdown document. Any attribute declaration not at the end of an inline or block element will be treated as if it had no special meaning (plaintext).

As for point #7, here are some examples of how I think it would work:

This is a paragraph {.some-class}

[This is a link](url){.some-class}

# This is a header {.some-class}

`This is a code block`{.some-class}

This is a larger paragraph `with a code block`{.code-block-class} and more text **here**{.stong-text-class} and more here as well. {.paragraph-class}

It gets a little ugly **like this**{.strong-text-class}. {.paragraph-class}

Agreed on most points of ConnorKrammer’s post above with exceptions of:

(4.) If I recall. Markdown philosophy is that all input is valid input. (But I do support having warning outputs). So for:

{class="not-allowed" .nope}

Just accept it, but make class="not-allowed" have higher precedence than .nope .

(6.) I agree on not worrying about ID uniqueness. That is the responsibility of the author. As long as we are not auto generating ‘anchors’ from header names, writers won’t likely accidentally make non unique name (and if they do, it’s their own fault).

(7.) Bit worried about potential problems with putting {} after a paragraph. As for the later examples looking quite ugly with too many {}, it doesn’t matter since in most cases people will not need to use it. But when they do need it, it will be a lifesaver. (Take for instance: customizing a link to look like a CSS based button).

The biggest reason to adopt this into core. Is that {} is optional, and will often get out of the way, but will save your sanity when you need it.

1 Like