MD022 - Add blank lines around headings¶
Aliases: blanks-around-headings
What this rule does¶
Checks that headings have blank lines before and after them to improve readability and document structure.
Why this matters¶
- Better readability: Blank lines create visual separation, making content easier to scan
- Clear structure: Spacing helps readers understand the document hierarchy
- Consistent rendering: Many Markdown processors require blank lines for proper formatting
- Professional appearance: Well-spaced documents look more polished and organized
Examples¶
✅ Correct¶
Some introductory text here.
# Main Heading
This is the content under the main heading.
## Subheading
More content follows here.
### Another Section
And even more content.
❌ Incorrect¶
Some introductory text here.
# Main Heading
This is the content under the main heading.
## Subheading
More content follows here.
### Another Section
And even more content.
🔧 Fixed¶
Some introductory text here.
# Main Heading
This is the content under the main heading.
## Subheading
More content follows here.
### Another Section
And even more content.
Configuration¶
Basic configuration¶
[MD022]
lines-above = 1 # Blank lines required above headings (default: 1)
lines-below = 1 # Blank lines required below headings (default: 1)
allowed-at-start = true # Allow headings at document start without blank line above (default: true)
Exact spacing above headings¶
By default, lines-above-mode = "minimum" accepts extra blank lines. Use exact
mode to also report and remove surplus blank lines immediately above headings:
The mode uses the same per-level lines-above values, document-start exceptions,
and inline disables as minimum mode. A value of 0 removes blank lines above
that level where safe; a separator before Setext headings or after HTML blocks
is retained. -1 leaves spacing unrestricted. Spacing below headings retains
its minimum behavior. Between adjacent headings, the gap also respects the
preceding heading's lines-below requirement, using the larger required spacing.
Comment-only lines continue to satisfy the minimum spacing requirement. Exact mode caps the contiguous run of actual blank lines immediately above the heading, or above comments attached directly to it. Earlier gaps between blocks and all comments stay intact. It also preserves blank lines that separate independent blockquotes.
Per-level configuration¶
You can specify different spacing requirements for each heading level (h1-h6) using arrays:
[MD022]
# Different spacing for each level: [h1, h2, h3, h4, h5, h6]
lines-above = [2, 1, 1, 1, 1, 1] # h1 needs 2 blank lines above, others need 1
lines-below = [1, 1, 1, 0, 0, 0] # h4-h6 don't need blank lines below
Use -1 to accept any number of blank lines for a specific level:
[MD022]
lines-above = [-1, 2, 1, 1, 1, 1] # h1 is unrestricted, h2 needs 2 blank lines
lines-below = [1, -1, -1, -1, -1, -1] # h1 needs 1, others are unrestricted
This is useful when you want:
- More space before top-level headings for visual separation
- Less space around deeply nested headings
- Different spacing conventions for different document sections
Automatic fixes¶
This rule automatically adds the required number of blank lines:
- Before headings (except at the start of a document)
- After headings (except at the end of a document)
Lists and code fences directly below a heading¶
No blank line is required below a heading when the next line starts a list item or opens a fenced code block. That gap belongs to MD032 and MD031, which require the blank line there themselves, so only one rule reports it.
A thematic break is not one of those constructs, so a heading directly above one
still needs its blank line, whichever way the break is written (---, ***,
* * *, - - -).
HTML comments¶
A line holding nothing but an HTML comment counts as a blank line, so a comment
directly above or below a heading satisfies this rule and rumdl fmt leaves the
document alone:
This keeps a directive comment attached to what it applies to: inserting a blank line there would turn the directive off.
The comment has to have the line to itself. Some text. <!-- note --> is a
paragraph, so a heading written under it is still missing its blank line. A
comment spanning several lines counts at both ends, and the convention holds
inside a blockquote. MD031, MD032 and MD058
read blank lines the same way.
Markdown with Gherkin¶
Under the mdg flavor, MD022 does not require a blank line above a heading that
names a Gherkin structure when the line directly above it is a tag line — a line
containing a backtick-wrapped tag:
Recognition follows Cucumber's `(@[^`]+)` scan. A matching tag may occur
anywhere on the line, and surrounding text or a trailing comment does not
disqualify it.
When the tag line opens the document, Gherkin reads the inserted blank as the Feature line and the Feature collapses into an unnamed node. Lower down the blank leaves the parse intact, and the exemption keeps the tags written against the structure they belong to.
The exemption needs both halves. An ordinary heading such as ## Notes names no
structure and keeps the requirement even below a tag line, a line without a
matching tag is not a tag line, and the requirement below a heading is never
waived.
See Markdown with Gherkin Flavor for the full flavor specification.