Markdown Horizontal Line: Syntax, the Heading Gotcha, and Platform Differences
A horizontal line in Markdown (the spec calls it a “thematic break”) is three or more hyphens, asterisks or underscores on a line by themselves. That part takes ten seconds to learn. The part that trips people up is what happens when the line sits directly under a paragraph, and what happens on platforms that do not follow the standard.
The syntax
Any of these produces a horizontal rule:
---
***
___
Rules that apply in CommonMark and GitHub Flavored Markdown:
- You need at least three characters.
- You cannot mix characters.
-*-is not a rule. - Spaces between the characters are allowed, so
- - -and* * *both work. - You can indent the line by up to three spaces. Four spaces turns it into a code block.
- Put a blank line before and after it.
That last rule matters more than the rest. Here is why.
The gotcha: a hyphen line under text becomes a heading
Markdown has a second, older heading syntax where you underline a line of text with === for an H1 or --- for an H2. If you write this:
Some paragraph text
---
you do not get a paragraph followed by a line. You get an H2 that says “Some paragraph text”. The fix is a blank line between the two:
Some paragraph text
---
Using *** or ___ avoids the problem entirely, because only = and - underlines create headings. If you have ever seen a divider turn into a big bold title, this is the cause.
Which character should you use?
All three are equivalent for the renderer. In practice:
| Style | Good for | Watch out for |
|---|---|---|
--- |
The most common choice, easy to type | Becomes a heading if there is no blank line above it. Also looks like YAML frontmatter delimiters |
*** |
Safe anywhere, never triggers a heading | Looks like bold markers at a glance |
___ |
Rarely used | Easy to confuse with an underline |
A sensible default is --- with a blank line above and below it. If a file starts with frontmatter, remember that the first --- at the very top of the file opens the frontmatter block, so do not use a rule as the first line of a Jekyll or Hugo post.
Platform differences
The standard syntax works in GitHub, GitLab, Obsidian, VS Code preview, Jekyll, Hugo and MkDocs. Other tools differ.
Notion. Typing --- in the editor creates a divider block. Pasting Markdown that contains --- also converts to a divider. This is one of the places where Notion behaves the way you would expect.
Slack. There is no horizontal rule at all in Slack messages. Lines of --- show up as literal text. Our Markdown to Slack converter strips them for this reason. The common workaround is a row of box-drawing characters or an emoji line, which is purely visual.
Confluence and Jira. Wiki markup uses four hyphens, ----, on a line by itself. If you are converting Markdown for either one, the Markdown to Confluence and Markdown to Jira tools translate the rule for you.
Word and email. A rule becomes a bordered empty paragraph in a Word document and an <hr> or a bordered table cell in HTML email. Both are handled in our Markdown to Word and Markdown to Email HTML tools.
Styling the line
Markdown has no way to set the color, thickness or width of a rule. If you control the HTML, use an <hr> tag with a style attribute:
<hr style="border: 0; border-top: 2px solid #999; width: 50%;">
This works on GitHub and most static site generators, but not in Notion, Slack or any renderer that strips raw HTML. On a Jekyll or Hugo site, the better approach is to style hr in your stylesheet so every rule in every post matches.
When not to use a rule
Headings do the job of dividing sections better than lines do, and they give you navigation and anchor links for free. A horizontal rule is best for a change of topic inside a section, a break before a footer or sign-off, or separating a callout from the main text. If you find yourself putting a rule before every heading, drop the rules.
Check your output
If a rule is not rendering where you expect, paste the document into the Markdown Editor to see the result live, or run it through the Markdown Linter to catch layout problems. For a broader look at why Markdown renders differently between tools, see Why Your Markdown Isn’t Rendering and the platform compatibility guide.