Should IMG tag be placed in a P tag... in HTML5... in 2020

The image element, being an inline tag, used to be placed inside a P tag, which is a block element. That was in the days of XHTML and strict.

In HTML5, many old restrictions have been eliminated. But this IMG in P thing continues to exist. A paragraph tag is for text. Semantically, the IMG can should have been placed in a DIV tag, which is the more appropriate HTML option.

Using the CSS, inline elements can be converted to block elements. Hence, there is no need to place them in P tags.

img.align_right { float: right; margin: 0 0 1em 1em; }
img.align_left { float: left: margin: 0 1em 1em 0; }
img.align_center { display: block; margin: 1em auto; }

I write my books in Markdown. Unlike the Web, paragraphs in a physical book do not have spacing between them. Instead, the first line is indented. If I specify first-line indenting for paragraphs using CSS, then paragraphs containing images also get indented. It can be fixed with more CSS and appears fine in desktop browsers. However, when the CSS is processed by ebook creators (EPUB, MOBI) or Amazon KDP, formatting goes for a toss.

CommonMark should provide some way to write IMG tag directly to HTML without the P envelope.

Arguably, images that are the only content of a paragraph, i.e. have empty lines before and after, should be made a figure instead, if the output format supports this – HTML does only after version 4.01 with the introduction of <figure>.


Right. Figure is the tag that CommonMark should use for images. It will save a lot of problems for ebook writers.

Because CommonMark aims to be “highly compatible” with existing implementations, I don’t think the core spec should be fundamentally changed to include figures.

However, there have been a number of discussions about different ways to implement the figure tag via extensions. My personal preference is for the community to unite around the iA Writer Content Block syntax for images in figures (and other embedded content), for which there is already a basic spec. Example:

The default output can be highly compatible but cmark can have an optional command-line parameter to generate HTML5 content and replace old-style anachronisms such as p+img with figure. There is no reason for compatibility of the output if the user does not want it. I think, in HTML4, unknown tags are treated like DIVs. So, even if figure is generated, it will be more welcome than P. Unknown tags can also be styled in HTML4 using CSS.

How are we defining “highly compatible”? Is this by viewer market share? What systems aren’t aware or capable of figures in 2020?

Highly compatible with existing Markdown implementations. So, if you have some markup, a CommonMark parser should render the same output (or very close to the same) as markup rendered by a non-CommonMark Markdown parser such as Kramdown or

Because <figure> is a completely different HTML tag with a different meaning to <img>, I think figures are beyond the scope of the core spec are should be specified in an extension/add-on spec.

Pandoc has long had an implicit_figures extension that converts a
paragraph containing only an image (with non-null description) into
a proper figure with the description as the caption.

That is nearly almost better than a p containing an img. And it
can be implemented on top of existing cmark (or commonmark.js),
because it just requires manipulating the AST; no changes in the
parser itself are needed.

However, it doesn’t really provide the flexibility needed for
proper figures. There’s no way to have block-level content in
the caption. There’s no way to specify a short caption. There’s
no way to have alt text distinct from the caption. There’s no
way to have a figure with multiple images. This has led me to
think that a dedicated syntax for figures may be needed.

For relevant discussion see


What do you think of the content block spec @jgm? No doubt some advanced cases aren’t covered by it, but next to most other proposals, for individual figures, the syntax is relatively clean. Perhaps this could be combined with a block syntax for advanced cases?

For example, we have this figure example which @mb21 posted in the GitHub thread:

Using the content block syntax within the block syntax, something like this might be workable:

/gull.jpg "a) A gull"
/tiger.jpg "b) A tiger"
/mouse.jpg "c) A mouse"

Figure 1: Picture of animals

The nice thing about the content block syntax is that it keeps adding embedded content concise in simple cases, which will be the only cases for many writers.