← Blog

Markdown code blocks: fenced, indented, language hints, escaping

Everything about Markdown code blocks — fenced vs indented, syntax highlighting, escaping backticks, nesting, and the rules that differ between renderers.

Code blocks are the Markdown feature most often used and most often broken. Triple-backtick fences, four-space indents, language hints, escaping rules — different renderers care about different things. This is the complete guide.

Inline code

Wrap a single word or phrase with single backticks:

Use the `console.log()` function for debugging.

Renders as: Use theconsole.log() function for debugging.

To include a literal backtick inside inline code, wrap withtwo backticks:

``Here's a backtick: ` inside the inline code.``

Fenced code blocks (modern, preferred)

Three backticks on their own line above and below:

```
plain code block, no language hint
```

With a language hint for syntax highlighting:

```python
def hello():
    return "syntax highlighted as Python"
```

The opening fence and the language tag have to be on the same line. The closing fence is just three backticks on a line by themselves.

Indented code blocks (legacy)

Indent any line by four spaces (or one tab) to turn it into a code block:

Some prose.

    indented_code = "this is a code block"
    function call()

More prose.

Indented code blocks predate fences and don't support language hints. They're still valid Markdown but the fenced form is the modern convention. The trap: an indented list followed by an indented continuation paragraph can accidentally become a code block. Use fences when in doubt.

Language hints — what's supported

The list depends on the renderer's syntax-highlighting library. Most usehighlight.js (about 200 languages) orPrism.js (300+ with plugins). Common safe choices:

  • python,javascript,typescript,tsx,jsx
  • bash,shell,sh,zsh
  • json,yaml,toml,xml,html,css,scss
  • go,rust,java,c,cpp,csharp
  • sql,dockerfile,nginx,markdown (yes, code blocks of Markdown)
  • text,plaintext,none — explicitly disable highlighting

If your renderer doesn't know the language, it usually falls back to no highlighting (not an error).

The four-backtick trick (nested fences)

When you need a code block that contains a triple-backtick fence inside it (e.g., showing Markdown source that has fenced code blocks), use four backticks for the outer fence:

````markdown
```python
print("inner triple-backtick code block")
```
````

You can go to five, six, or more — as long as the closing fence has at least as many backticks as the opening.

This is how you write a Markdown blog postabout Markdown code blocks, the recursion that just made this page hurt to write.

Tilde fences as an alternative

Tildes also work:

code block delimited by tildes


```python
def alternative(): pass

Equivalent to backticks. Useful when your code contains a lot of backticks and you don't want to count fence depth.

## Code blocks in lists

The indent for code inside a list item must match the text after the list marker:

````markdown
1. First step:

   ```python
   # Three-space indent matches "First step"
   indented_to_align()
  1. Second step.

Without the blank line before the fence, parsers can interpret the code block as part of the previous prose. Without the indent matching the list-item's content, the fence breaks the list.

For the full list rules, see [Markdown lists](/blog/markdown-lists).

## Highlighting per line (some renderers)

GitHub, GitLab, MkDocs (with Material), and Pandoc support line highlighting in code blocks via an extended syntax:

````markdown
```python {.line-numbers hl_lines="2 4"}
print("not highlighted")
print("highlighted line 2")
print("not highlighted")
print("highlighted line 4")
```

Syntax varies —{.class} style vshl_lines="…" vsdata-line attributes. Check your renderer's docs.

Escaping inside code blocks

Inside a code block (fenced or indented),no Markdown is parsed. That means:

  • **bold** shows as the literal asterisks
  • [link](url) shows as the literal brackets
  • <tags> show as the literal angle brackets (no HTML parsing)

This is why code blocks are safe for showing untrusted source.

Discord / Slack / Confluence behavior

  • Discord — backtick fences work; language hints enable syntax highlighting. SeeMarkdown in Discord.
  • Slack — fences work; no syntax highlighting (just monospace). SeeMarkdown in Slack.
  • Confluence — Markdown paste-converts code blocks into the Confluence code-block macro. Language hint becomes the macro'slanguage parameter. SeeConfluence and Markdown.

Common AI-generated mistakes

Two failure modes you'll see in AI Markdown output:

  1. Unclosed fences. The opening triple-backtick is there; the closing one is missing. Everything after the fence becomes a code block. Renderer chokes or shows the whole rest of the document in mono.
  2. Wrong language hint. AI assistants make up language names that the syntax highlighter doesn't recognize (pseudocode,cli,console-output). Usually just falls back to no highlighting, which is fine.

Markdown Tidy auto-closes unclosed fences and normalizes language hints in one Tidy pass. Both are part of therepair rules.

Quick reference

`inline code`

``inline with ` backtick``

```
plain block
```

```python
highlighted block
```
four backticks to nest a triple fence

~~~
tilde fences also work
~~~

For the rest of Markdown, see thecomplete syntax cheat sheet.

Try Markdown Tidy free

Paste markdown, get a polished document — no signup required.