Tutorial · 8 min read

Markdown Code Blocks: Fences, Inline Code, and Language Hints

Fenced and inline Markdown code syntax, backtick escaping, and language hints for syntax-highlighted code blocks.

Nina@Aurcue

Markdown Code Blocks: Fences, Inline Code, and Language Hints

d4193e55 ad6f 4b79 8ea5 36f6d91752da
Editorial illustration of a Markdown document with a fenced code block highlighted between two backtick fence markers

To put code in a Markdown file so it renders as code, wrap it. A markdown code block comes in two forms: wrap short expressions in single backticks for inline code, and wrap multi-line code in a fence of three backticks for a full block. Add a language hint after the opening fence when you want syntax highlighting. This guide covers both forms, common language identifiers, backtick escaping, and fixes for the three problems people hit most often: a block that renders as plain text, missing highlighting, and a fence inside a fence.

Two ways to mark code: inline backticks versus fenced blocks

Inline code uses one backtick on each side and keeps the code on the same line as your sentence:

Run ` npm install ` before you start the dev server.

Renders as: Run npm install before you start the dev server.

A fenced block starts with a line of three backticks, contains your code, and ends with a matching line of three backticks:

```
pip install requests
python scrape.py
```

A simple decision rule covers almost every case:

SituationUse
A command, function name, or filename inside a sentenceInline backticks
More than one line of code, a shell session, or a config fileFenced block
Code you want highlighted or copied by readersFenced block with a language hint

For emphasis inside regular prose, that is a different syntax: see our guide to Markdown bold, italic, and strikethrough.

Fenced code blocks: triple-backtick fences and what they do

The fence is the same markdown backtick character used three times in a row. The CommonMark specification defines the rules: the opening fence may be followed by an info string, the block ends at a closing fence of the same character with at least as many ticks, and the content is treated as literal text. Nothing inside a fenced block is parsed, so asterisks, underscores, and brackets stay exactly as you typed them.

The GitHub docs on code blocks also recommend a blank line before and after a fenced block so the raw file stays easy to read, even though CommonMark does not require it.

Language hints: common identifiers and renderer differences

The first word after the opening fence is the language hint:

```python
def greet(name):
    return f"Hello, {name}"
```

Common identifiers worth memorizing:

Language hintTypical content
python, js, tsScripts and functions
bash or shellTerminal commands and sessions
json, yaml, tomlConfig files
sqlQueries
diffPatches and review output
textOutput that should not be highlighted at all

One important distinction: highlighting is a renderer feature, not a Markdown feature. The Bitbucket community discussion on code highlighting and the markdowntools.com syntax-highlighting guide both describe the same two-stage pipeline: the Markdown parser turns ``` ```python ```` into a `<code> element with a language class, then a highlighting library such as highlight.js, Prism, or Rouge adds the colors. That is why the same file can look highlighted on GitHub and plain in a chat app that ships no highlighter.

Nested backticks: escaping backticks inside code

Two nested cases come up in real documents.

Backticks inside inline code. If the expression itself contains a backtick, open the inline span with a double backtick and put a space inside:

`` ` `ls `` command ``

Triple backticks inside a block. To show a fenced block inside a fenced block, make the outer fence longer than the inner one. Four backticks outside, three inside:

````markdown
```python
print("hello")
```
````

Because the closing fence must be at least as long as the opening one, CommonMark closes the outer block only when it sees a four-backtick line. A tilde fence (~~~) is the alternative when the info-string rules make backtick fences awkward.

Troubleshooting: three failures and their fixes

The live results for this topic are dominated by troubleshooting threads: Stack Overflow, the Elastic forum, Netlify answers, and Obsidian's forum all answer the same "why is my code block broken" questions. This matrix maps each symptom to its cause and fix.

SymptomLikely causeFix
Block renders as plain text with visible backticksA blank line inside the fence splits it into two blocks, or the fence is mixed with tabs/characters that the renderer does not accept (Netlify forum thread)Remove the blank line, keep fences on their own lines, and use plain backticks
Code shows but no highlightingThe renderer has no highlighter, or the language identifier is misspelled or unsupported (Bitbucket community)Use a standard identifier like python or js; accept that color depends on the viewer
Fence appears inside your code block and closes itYou used three backticks for the outer block while the content contains a fence (Stack Overflow on formatting blocks)Use four or more backticks for the outer fence, or a ~~~ tilde fence
Bold markers render inside what should be codeYou used bold syntax instead of a code span, or indented the line so the renderer treated it as a paragraph (Stack Overflow on bolded input)Wrap the value in single backticks or move it into a proper fenced block

Indented code blocks versus fences, and why fences are safer

The original Markdown syntax also recognizes an indented code block: indent every line by four spaces and the renderer treats it as code. It works, but it has a real failure mode: any list item, blockquote, or nested structure that also uses indentation can accidentally swallow your code or break your list. Fences make the start and end explicit, survive list nesting and copy-paste, and are the only form that carries a language hint. For anything a teammate or an AI agent will read later, prefer fences.

Code blocks for docs teams: portable files, Git diffs, and AI-agent context

Code fences matter beyond rendering. A fenced block is plain text inside an ordinary file, so Git diffs show exactly which line changed, and every local tool that reads text files can read it. That includes AI coding agents: a markdown code block with a language hint gives an agent an unambiguous signal about what the snippet is, without any editor-specific markup. When the same file is opened in five different apps, the fence is the part that stays identical.

If your snippets are diagrams rather than code, the fence works there too: our Mermaid editor guide covers ```mermaid blocks for flowcharts and sequence diagrams.

Write code in Fylune: local files, live preview, safe MDX

Fylune is a local-first document workspace for Markdown and MDX, so your code stays in ordinary files in your project folder. As you type a fenced block, the live preview renders it inline, which makes it easy to spot a missing closing fence immediately. Fylune also renders safe MDX blocks, so documentation that mixes prose, code, and components stays in one editable file that Git and local tools still own.

Test the examples in this article in your real project with Fylune's local preview: download Fylune.

FAQ

**What is in Markdown?** Three consecutive backticks form a code fence. A line starting with opens a fenced block, a matching line closes it, and everything between them renders as literal code. The word after the opening fence is an optional language hint.

How do I format a code block? Put the code on its own lines between two fence lines, then add a language identifier for highlighting:

```js
console.log("hello");
```

Can a Markdown code block be collapsible? Not in core Markdown. Collapsible sections use HTML details and summary elements, and whether they render depends on the target site's HTML policy. GitHub, for example, supports <details> in Markdown files, but chat apps and strict sanitizers usually strip it.

Sources