Skip to content
Tight vs Loose Lists
step 1/5

Reading — step 1 of 5

Read

~1 min readLists & Code

Tight vs Loose Lists

A subtle but visible CommonMark rule: the presence of a blank line between list items changes how each <li> is rendered.

Tight list (no blank lines between items)

- alpha
- beta
- gamma

Renders to:

<ul>
<li>alpha</li>
<li>beta</li>
<li>gamma</li>
</ul>

Loose list (any blank line between items)

- alpha

- beta
- gamma

Renders to:

<ul>
<li>
<p>alpha</p>
</li>
<li>
<p>beta</p>
</li>
<li>
<p>gamma</p>
</li>
</ul>

Why does the same list render two ways? Tight lists are styled compactly — no extra paragraph margin between items. Loose lists give each item the full paragraph styling, useful when items contain multiple paragraphs or sub-blocks.

Decision rule (from the spec)

A list is loose if any of its constituent items are separated by blank lines. Otherwise it is tight.

The detection happens during block parsing. The renderer then either wraps each item's content in <p>...</p> (loose) or inlines it raw (tight).

Implementation

  • Collect list items in one pass.
  • Track whether any blank line appeared between two items.
  • On render, if loose==True, wrap each item in <p>.

This is one of those rules that distinguishes a serious Markdown parser from a weekend regex hack — most ad-hoc parsers get the loose vs tight distinction wrong, producing visually inconsistent output.

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…