Step 1 of 5 · Reading · ~3 min
Read
Lists & Code
Tight vs Loose Lists
Two lists that differ by a single blank line produce different HTML. This is not a rendering quirk you can ignore — it is in the spec, every conforming parser does it, and it is the rule most weekend Markdown parsers get wrong.
The same items, two shapes
Tight — no blank line anywhere between the items:
<ul>
<li>alpha</li>
<li>beta</li>
</ul>
Loose — one blank line somewhere between two items:
<ul>
<li>
<p>alpha</p>
</li>
<li>
<p>beta</p>
</li>
</ul>
Note what changed: every item gained a <p> wrapper, not just the ones
adjacent to the blank line. Looseness is a property of the whole list. That is
what makes it awkward to implement — you cannot decide how to render item one
until you have read item five.
What exactly makes a list loose?
Two conditions, either one is enough:
- Any two of its items are separated by a blank line.
- Any single item directly contains two block-level elements with a blank line between them.
And what does not count is just as important:
| Situation | Verdict |
|---|---|
| ✓ blank line between item one and item two | loose |
| ✓ an item holding two paragraphs | loose |
| ✗ blank line before the first item | tight |
| ✗ blank line after the last item | tight — that blank just ends the list |
| ✗ blank line inside a fenced code block in an item | tight |
| ✗ blank line inside a sublist | outer tight, sublist loose |
That last row catches people. Nesting means a document can hold a tight list whose child list is loose, side by side.
Detecting it in one pass
Carry a "did I just see a blank line?" flag and only promote to loose when the next item actually arrives:
Line three is the whole trick. The trailing blank sets gap, but no item ever
follows it, so loose is never set. Collect first, decide second, render third.
Why the spec bothers
Tight lists render compactly because the item text is not a paragraph and gets no paragraph margin. Loose lists give every item full paragraph spacing, which is what you want when items are several sentences long or contain sub-blocks. The author signals the choice with whitespace; the parser has to honour it.
Your exercise
Render one unordered list as tight or loose.
The mistake the grader catches is applying looseness only to the items after
the blank line. A hidden test feeds four items with the gap between the second
and the third and expects all four wrapped in <p>. If you set a flag mid-loop
and start wrapping from that point on, items one and two come out bare and the
diff shows exactly two wrong lines out of twelve.
The other one is the trailing blank line: a test ends the input with a blank after the last item and still expects the tight rendering. Only promote to loose when a blank line is followed by another item.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…