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 つだけです。

    1. テーブル(table)
    2. タスクリスト(tasklist)
    3. 打ち消し線(strikethrough)
    4. 自動リンクの拡張(autolink)
    5. 一部の 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)

    リンクの先頭に ! を付けます。

    ![代替テキスト](image.png)
    ![代替テキスト](image.png "ホバー時のタイトル")

    参照形式(![代替テキスト][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 と同じ文字参照(&copy; &#169; &#xA9; など)も使えます。いずれも © と表示されます。


    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 タグが無効化されます。タグの < が &lt; に置き換えられ、ただの文字として表示されます。

    <title> <textarea> <style> <xmp> <iframe> <noembed> <noframes> <script> <plaintext>
    <script>alert(1)</script>

    ↓

    &lt;script>alert(1)&lt;/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 進の文字参照(&#102;&#x6f;…)に変換されます。スパム収集ボット対策の機能で、ブラウザでの表示は変わりません。


    参考リンク