Markdown の基本的な書き方を、現在の標準である CommonMark と GFM(GitHub Flavored Markdown) の範囲でまとめたリファレンスです。
この記事で扱うのは、仕様書に定義されている記法だけです。脚注・アラート・絵文字ショートコード・@メンションなどの GitHub 独自拡張や、GLFM(GitLab)独自の記法は、標準仕様ではなく対応していないパーサーもあるため扱いません。
Markdown の仕様の関係
Markdown にはいくつかの「仕様」があり、次のように積み重なっています。
オリジナル Markdown(2004・John Gruber)
│ 曖昧さをなくし、テスト付きの厳密な仕様に
▼
CommonMark … 基本記法の共通仕様
│ 5 つの拡張を追加
▼
GFM(GitHub Flavored Markdown)… CommonMark + 5 つの拡張
│ GitLab 環境向けの独自拡張を追加
▼
GLFM(GitLab Flavored Markdown)
| 仕様 | 概要 |
|---|---|
| オリジナル Markdown | 元祖。散文の説明と Perl スクリプト(Markdown.pl)だけで定義されていたため、細かい挙動が曖昧だった |
| CommonMark | 曖昧さを排除した厳密な共通仕様。見出し・段落・強調・リスト・コード・引用・リンクなどの基本記法を定義 |
| GFM | CommonMark の完全な上位互換。テーブル・タスクリスト・打ち消し線・自動リンク拡張・一部 HTML タグの無効化の 5 つを追加 |
| GLFM | GFM をベースにした GitLab 版。GFM で書いたものは基本的にそのまま通用する |
「GFM 準拠」はどこまでか
GFM の仕様書(GitHub Flavored Markdown Spec)で「extension」として定義されているのは、次の 5 つだけです。
- テーブル(
table) - タスクリスト(
tasklist) - 打ち消し線(
strikethrough) - 自動リンクの拡張(
autolink) - 一部の HTML タグの無効化(
tagfilter)
GitHub 上で使える脚注・アラート(> [!NOTE])・絵文字(:smile:)などは、GFM 仕様には含まれない GitHub 独自の機能です。そのため「GFM 対応」をうたうパーサーでも、対応しているとは限りません。
CommonMark の基本記法
ここからは、CommonMark 準拠のパーサーならどこでも通用する基本記法です。
見出し(Heading)
ATX 形式(#)
行頭に # を 1〜6 個置き、その後に半角スペースを入れます。
# 見出し1
## 見出し2
###### 見出し6
#の後のスペースは必須です。#見出しは見出しにならず、ただの段落になります。#を 7 個以上並べると見出しになりません。- 末尾に閉じの
#を付けても無視されます(## 見出し ##も可)。
Setext 形式(下線)
テキストの次の行に =(h1)または -(h2)で下線を引く形式です。記号の個数は 1 個以上なら問われません。
見出し1
======
見出し2
------
作れるのは h1・h2 だけなので、実務では ATX 形式(#)が主流です。
段落と改行(Paragraph / Line Break)
空行で区切られたテキストのかたまりが 1 つの段落(<p>)になります。
段落の中の改行(1 回)は、HTML では改行になりません(ソフト改行)。ブラウザ上ではスペースと同じ扱いになります。
1行目
2行目
↓
<p>1行目
2行目</p>
明示的に改行(<br>)を入れる方法
改行を入れたい行の末尾に、次のどちらかを置きます(ハード改行)。
- 半角スペース 2 個以上
- バックスラッシュ
\
1行目\
2行目
↓
<p>1行目<br />
2行目</p>
行末スペースはエディタの設定で消えたり、目で見えなかったりするため、\ の方が確実です。
環境差に注意:GitHub のコメント欄など、「1 回の改行をそのまま
<br>にする」設定になっている環境もあります。これは Markdown の仕様ではなく、その環境の設定によるものです。
強調(Emphasis)
| 記法 | 結果 |
|---|---|
*斜体* / _斜体_ |
斜体(<em>) |
**太字** / __太字__ |
太字(<strong>) |
***太字斜体*** |
太字斜体 |
日本語での注意
CommonMark の強調には、「記号の前後に何があるか」で開始・終了を判定する細かいルールがあります。日本語の文章でつまずきやすいのは、次の 2 つのパターンです。
1. _(アンダースコア)は、文字に直接くっつけると効かない
_ は単語の途中で強調にならないルールがあるため、前後に和文が密着していると強調になりません。
これは__重要__です ← 太字にならない
これは**重要**です ← 太字になる
2. 記号の内側に括弧などの記号があると効かない
** のすぐ内側が 「」 や () などの記号で、外側に文字が密着していると、強調になりません。
これは**「重要」**です ← 太字にならない
これは **「重要」** です ← 太字になる
日本語では * を使い、効かないときは前後に半角スペースを入れるのが確実です。
リスト(List)
順序なしリスト(<ul>)
マーカーは - + * の 3 種類で、どれを使っても同じ <ul> になります。
- Item A
- Item B
- Item C
- 実務では
-がおすすめです(Prettier・markdownlint の既定で、強調の*とも紛れない)。 - 1 つのリストの中でマーカーを混ぜると、別のリストに分かれます。
- Item A
- Item B
* Item C ← ここから別の <ul> になる
マーカー後のスペース
マーカーの直後には空白(スペースまたはタブ)が 1 個以上必要です。
-Item A ← リストにならない(ただの段落)
- Item A ← OK
マーカーの後の空白を 5 個以上にすると、内容がインデントされたコードブロックとして解釈されることがあります。スペース 1 個が最も安全です。
順序付きリスト(<ol>)
数字 + .(または ))+ スペースで書きます。
1. Item 1
2. Item 2
3. Item 3
- 開始番号は反映されます。
3.から始めると<ol start="3">になります。 - 2 行目以降の番号は無視され、先頭の番号から自動で連番になります。
1.1.1.と書いても 1, 2, 3 と表示されます。 - 途中で
.と)を切り替えると、別のリストに分かれます。
段落の直後にリストを書くとき
段落の直後(空行なし)でもリストを始められますが、順序付きリストは 1. から始まる場合だけです。
段落です
2. Item ← リストにならず、段落の続きになる
リストの前には空行を入れておくと安全です。
ネスト(入れ子)
子リストは、親のマーカーの後の内容の開始位置までインデントします。親が - なら 2 スペース、1. なら 3 スペースです。
- 親
- 子
- 孫
1. 親
- 子 ← 3 スペース必要(2 スペースだとネストされない)
tight / loose(項目間の空行)
項目の間に空行があるかどうかで、出力が変わります。
- Item A
- Item B
↓ 空行なし(tight):<li>Item A</li>
- Item A
- Item B
↓ 空行あり(loose):<li><p>Item A</p></li> と、各項目に <p> が付く
1 か所でも空行があると、リスト全体が loose になります。
行頭の数字がリストになってしまう場合
行頭が「数字 + . + スペース」だと、意図せず順序付きリストになります。
1986. What a great season.
↓ <ol start="1986"> のリストになってしまう
ピリオドをバックスラッシュでエスケープすると回避できます。
1986\. What a great season.
コード(Code)
インラインコード
バッククォート `` ` で囲みます。
`code`
中にバッククォートを含めたいときは、外側のバッククォートを 2 個以上にし、内側との間に半角スペースを入れます(両端のスペース 1 個ずつは出力時に取り除かれます)。
`` `code` を含む ``
コードブロック(フェンス)
``` または ~~~ を 3 個以上並べた行で囲みます。開始フェンスの後に言語名を書くと、シンタックスハイライトの手がかりになります(出力は <code class="language-js">)。
```js
const x = 1;
```
- 中にフェンスを含めたいときは、外側のフェンスを長くします(4 個で囲むなど)。
- 閉じフェンスは、開始フェンスと同じ記号で、同じ個数以上にします。
コードブロック(インデント)
各行を半角スペース 4 個(またはタブ)下げても、コードブロックになります。言語名を指定できないため、実務ではフェンス方式が主流です。
const x = 1;
引用(Blockquote)
行頭に > を付けます。
> 引用文
> 複数行も続けられる
>
> > ネストもできる
引用の中にも、見出し・リスト・コードなどの記法を書けます。
リンク(Link)
[表示テキスト](https://example.com)
[タイトル付き](https://example.com "ホバー時のタイトル")
参照形式
URL を別の場所にまとめて定義する書き方です。定義した行そのものは出力されません。
[表示テキスト][ref]
[ref][] ← 表示テキストと参照名が同じなら省略できる
[ref]: https://example.com "タイトル(任意)"
参照名の大文字・小文字は区別されません。
自動リンク(< >)
URL やメールアドレスを < > で囲むと、そのままリンクになります。
<https://example.com>
<foo@example.com>
< > なしの URL をリンクにするのは GFM の拡張です(後述)。
画像(Image)
リンクの先頭に ! を付けます。


参照形式(![代替テキスト][ref])も使えます。
Markdown の画像記法では、サイズや配置は指定できません。幅・高さなどが必要なときは、<img> タグを直接書きます。
水平線(Thematic Break)
- * _ のいずれかを 3 個以上、単独の行に書きます。間にスペースを入れても構いません。
---
***
* * *
注意:テキストの直後(空行なし)に
---を書くと、水平線ではなく Setext 形式の見出し(h2)の下線として解釈されます。水平線の前には空行を入れます。
HTML の埋め込み
Markdown の中に、HTML をそのまま書けます。
<div class="note">
ここは HTML ブロックとして扱われる
</div>
HTML ブロックの中で Markdown を使うとき
HTML ブロックは空行で終わるというルールがあります。HTML タグの中で Markdown を使いたいときは、前後に空行を入れます。
<div class="note">
*ここは Markdown として処理される*
</div>
空行がないと、*...* はそのまま文字として出力されます。
注意:Markdown の仕様上は HTML を書けますが、多くの環境ではセキュリティのために一部のタグや属性(
<script>、on〜属性など)を除去します。
エスケープと文字参照
バックスラッシュエスケープ
記号を記法として解釈させず、そのまま表示したいときは、前にバックスラッシュ \ を置きます。
\*斜体にならない\*
\# 見出しにならない
エスケープできるのは ASCII の記号(`` ! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ \ ] ^ _ { | } ~ `)です。それ以外の文字の前の \ は、そのまま \ として表示されます。
文字参照
HTML と同じ文字参照(© © © など)も使えます。いずれも © と表示されます。
GFM の拡張記法
ここからは、CommonMark にはない GFM の拡張記法です。GFM に対応したパーサーで使えます。
テーブル(Table)
パイプ | で列を区切り、ヘッダ行の直下に区切り行を置きます。
| 列1 | 列2 | 列3 |
| --- | --- | --- |
| 内容1 | 内容2 | 内容3 |
区切り行(| --- |)は必須
テーブルは「ヘッダ行 + 区切り行 + 0 行以上のデータ行」で構成されます。区切り行がないとテーブルにならず、ただの段落になります。
| 列1 | 列2 |
| 内容1 | 内容2 |
↓ テーブルにならない
<p>| 列1 | 列2 |
| 内容1 | 内容2 |</p>
配置(アライメント)
区切り行のハイフンに : を付けて、配置を指定できます。
| 左寄せ | 中央 | 右寄せ |
| :--- | :---: | ---: |
| a | b | c |
| 記法 | 配置 |
|---|---|
:--- |
左寄せ |
:---: |
中央 |
---: |
右寄せ |
列数のルール
- ヘッダ行と区切り行の列数は一致させる必要があります。一致しないとテーブルになりません。
- データ行の列数が足りない場合は空のセルで埋められ、多い場合は余分なセルが無視されます。
その他の注意
- 先頭・末尾の
|は省略できますが、付けたほうが崩れにくいです。 - セル内で
|を使いたいときは\|とエスケープします。 - セル内に書けるのはインラインの記法だけです(強調・リンク・インラインコードなど)。リストやコードブロックは書けません。セル内で改行したいときは
<br>を使います。 - テーブルは空行で終わります。
タスクリスト(Task List)
リスト項目の先頭に [ ](未完了)または [x](完了)を付けます。
- [ ] 未完了のタスク
- [x] 完了したタスク
↓
<ul>
<li><input type="checkbox" disabled="" /> 未完了のタスク</li>
<li><input type="checkbox" checked="" disabled="" /> 完了したタスク</li>
</ul>
仕様上の出力は disabled なチェックボックスです(GitHub 上でクリックして切り替えられるのは GitHub 独自の機能です)。
打ち消し線(Strikethrough)
~~ で囲みます。GFM 仕様では ~ 1 個でも打ち消し線になります。
~~打ち消し~~
↓
<del>打ち消し</del>
~ 1 個は、パーサーによっては対応していないことがあります。~~ を使うのが確実です。
自動リンクの拡張(Autolink)
< > で囲まなくても、次のような文字列は自動でリンクになります。
https://example.com
www.example.com
foo@example.com
↓
<a href="https://example.com">https://example.com</a>
<a href="http://www.example.com">www.example.com</a>
<a href="mailto:foo@example.com">foo@example.com</a>
www.で始まるものは、http://が補われます。- URL 末尾の
.,)などの句読点は、リンクに含まれないよう調整されます。
一部の HTML タグの無効化(Disallowed Raw HTML)
GFM では、次の HTML タグが無効化されます。タグの < が < に置き換えられ、ただの文字として表示されます。
<title> <textarea> <style> <xmp> <iframe> <noembed> <noframes> <script> <plaintext>
<script>alert(1)</script>
↓
<script>alert(1)</script>
ハマりどころまとめ
| 項目 | 挙動・注意 |
|---|---|
| 1 回の改行 | <br> にならない。行末に \ かスペース 2 個 |
| 日本語と強調 | _ は和文に密着すると効かない。**「」** のように内側が記号でも効かない。前後に半角スペースが確実 |
見出しの # |
後ろにスペースが必須 |
| リストのマーカー | 途中で変えると別リストに分かれる。マーカー後の空白は必須 |
| リストのネスト | 親の内容の開始位置まで下げる(1. の下は 3 スペース) |
| tight / loose | 項目間に空行があると各項目に <p> が付く |
行頭の 数字. |
順序付きリストになる。\. でエスケープ |
水平線 --- |
直前に空行がないと見出しの下線になる |
| HTML ブロック | 中で Markdown を使うなら前後に空行 |
| 画像サイズ | Markdown では指定できない。<img> を直接書く |
| テーブル | 区切り行が必須。ヘッダと区切り行の列数を一致させる |
付録:オリジナル Markdown との違い
オリジナル Markdown(Daring Fireball の原典と Markdown.pl)は、CommonMark / GFM と挙動が違う点があります。古いパーサーや、オリジナル準拠をうたうツールを使うときに注意が必要な点をまとめます。
GFM の拡張は存在しない
テーブル・タスクリスト・打ち消し線・裸の URL の自動リンクは、オリジナルにはありません。< > で囲む自動リンクは使えます。
フェンス方式のコードブロックがない
コードブロックは、4 スペース(またはタブ 1 個)のインデントで書く方法だけです。``` で囲む書き方はオリジナルにはありません。
見出しの # の後にスペースがなくてもよい
オリジナルでは #見出し も見出しになります。CommonMark ではスペースが必須になりました。
順序付きリストの開始番号が無視される
オリジナルでは、リストに書いた番号は出力に影響しません。3. から始めても、1 から始まるリストになります。
リストのマーカーを混ぜても 1 つのリスト
オリジナルでは - + * は交換可能とされ、混ぜても 1 つのリストになります。CommonMark では別のリストに分かれます。
リスト内のインデントは 4 スペース基準
オリジナルでは、リスト項目の中に段落を続けるときは 4 スペース(またはタブ 1 個)下げると定められています。CommonMark のように「マーカーの幅に合わせて 2 スペース」でネストすると、オリジナル準拠のパーサーでは意図どおりにならないことがあります。
_ を単語の途中でも強調に使える
オリジナルでは、_ も単語の途中で強調として使えます。CommonMark では、単語の途中で強調になるのは * だけです。
ハード改行は行末スペース 2 個だけ
オリジナルで <br> を入れる方法は、行末のスペース 2 個以上だけです。行末の \ による改行は CommonMark で追加されました。
HTML ブロックの中では Markdown が処理されない
オリジナルでは、<div> などのブロック要素の中に書いた Markdown は、空行を入れても処理されません。CommonMark では、前後に空行を入れれば処理されます。
メールアドレスの自動リンクが難読化される
オリジナルでは、<foo@example.com> のようにメールアドレスを自動リンクにすると、アドレスの各文字がランダムに 10 進・16 進の文字参照(fo…)に変換されます。スパム収集ボット対策の機能で、ブラウザでの表示は変わりません。
参考リンク
- オリジナル Markdown(Daring Fireball): https://daringfireball.net/projects/markdown/syntax
- オリジナル dingus(動作確認): https://daringfireball.net/projects/markdown/dingus/a>
- CommonMark 公式: https://commonmark.org/
- CommonMark 仕様書: https://spec.commonmark.org/
- CommonMark dingus(動作確認): https://spec.commonmark.org/dingus/
- GFM 仕様書: https://github.github.com/gfm/
- GitLab Flavored Markdown: https://docs.gitlab.com/user/markdown/