11.

HTML5 <main> 要素の使い方と ARIA role / Skip Link / SEO

編集
この記事の要点
  • <main> は HTML5 のページのメインコンテンツを示すセクション要素
  • 1 ページに 1 つだけ(複数あるとアクセシビリティ違反)
  • 暗黙の ARIA role は main。HTML5 では role 属性を別途付ける必要なし
  • <header> / <footer> / <nav> / <aside><main>含めない
  • Skip Link<a href="#main">本文へスキップ</a>)と組み合わせると a11y / キーボード操作向上

main 要素とは

HTML5.1 で標準化されたセクション要素。ページの主要コンテンツを意味します。スクリーンリーダー利用者が「本文だけを読みたい」とき、この要素にジャンプできます。

<!DOCTYPE html>
<html>
<head><title>記事タイトル | サイト名</title></head>
<body>
  <header>
    <h1>サイト名</h1>
    <nav>...</nav>
  </header>

  <main>
    <!-- ここがページの主役 -->
    <article>
      <h1>記事タイトル</h1>
      <p>本文...</p>
    </article>
  </main>

  <aside>
    <h2>関連記事</h2>
    ...
  </aside>

  <footer>
    <p>© 2026 サイト名</p>
  </footer>
</body>
</html>

含めるべき / 含めないべき

要素<main> 内?理由
<header>(サイト共通)×全ページ共通の要素
<nav>(グローバルナビ)×全ページ共通
<article>ページの主役
<section>本文の節
記事内のヘッダ <header>記事の冒頭部分(タイトル等)
記事内のフッタ <footer>記事の末尾(著者情報等)
サイドバー <aside>本文の補足なら含めても OK
<footer>(サイト共通)×全ページ共通

1 ページに 1 つだけ

HTML5 仕様は「<main>ページに 1 つだけ」と明記。複数あるとバリデーションエラー、スクリーンリーダーも混乱します:

<!-- ❌ NG: main が 2 つ -->
<body>
  <main><article>記事 A</article></main>
  <main><article>記事 B</article></main>
</body>

<!-- ✅ OK: 1 つの main に複数 article -->
<body>
  <main>
    <article>記事 A</article>
    <article>記事 B</article>
  </main>
</body>

例外: hidden 属性付きなら複数 OK(SPA で画面切替時に使う)。

<!-- SPA でルートごとに切替(hidden で非表示にする) -->
<main id="home"><h1>ホーム</h1>...</main>
<main id="about" hidden><h1>About</h1>...</main>
<main id="contact" hidden><h1>Contact</h1>...</main>

<script>
function show(id) {
    document.querySelectorAll('main').forEach(m => m.hidden = m.id !== id);
}
</script>

ARIA role との関係

HTML5 の <main>暗黙の role が main。明示的に書く必要はありません:

<!-- ✅ HTML5: role 不要 -->
<main>
  ...
</main>

<!-- 明示的に書いても OK だが冗長 -->
<main role="main">
  ...
</main>

<!-- 古い HTML4 / XHTML での代替(main 要素未対応) -->
<div role="main">
  ...
</div>

<!-- IE11 等の超古ブラウザフォールバック -->
<main role="main">  <!-- IE11 は main を認識しないので role を併記 -->
  ...
</main>

Skip Link(本文へスキップ)

キーボード / スクリーンリーダー利用者のため、ページ冒頭に「本文へスキップ」リンクを置きます:

<body>
  <a href="#main" class="skip-link">本文へスキップ</a>

  <header>...</header>
  <nav>...</nav>

  <main id="main" tabindex="-1">
    <!-- tabindex="-1" でフォーカス可能に -->
    ...
  </main>
</body>

<style>
.skip-link {
    position: absolute;
    left: -9999px;
    top: 0;
    padding: 1em;
    background: #1a73e8;
    color: white;
    z-index: 1000;
}

.skip-link:focus {
    /* Tab キーで focus したときだけ画面に表示 */
    left: 1em;
    top: 1em;
}
</style>

HTML5 アウトラインと main

HTML5 のアウトラインアルゴリズム上、<main>セクショニング要素ではない<article> / <section> / <nav> / <aside> がセクショニング)。アウトラインに新しい階層は作りません:

<body>
  <h1>サイト名</h1>            <!-- アウトライン Level 1 -->
  <main>
    <h2>記事タイトル</h2>        <!-- main は階層作らない → Level 2 -->
    <h3>セクション 1</h3>        <!-- Level 3 -->
  </main>
</body>

SEO 観点

  • Google は <main> を「メインコンテンツの目印」として活用
  • 抜粋(meta description 自動生成)に <main> 内が優先される傾向
  • サイドバーや広告を本文と区別できる → 検索品質向上
  • Reader Mode(Safari / Firefox)が <main> を起点に本文抽出

CSS で main にスタイル

/* レイアウトの基本 */
main {
    max-width: 800px;
    margin: 0 auto;
    padding: 2em 1em;
    line-height: 1.7;
}

/* 2 カラム(main + aside) */
body {
    display: grid;
    grid-template-columns: 1fr 300px;
    gap: 2em;
    max-width: 1200px;
    margin: 0 auto;
}

aside {
    border-left: 1px solid #ccc;
    padding-left: 2em;
}

/* スマホで 1 カラムに */
@media (max-width: 768px) {
    body {
        grid-template-columns: 1fr;
    }
    aside { border-left: none; border-top: 1px solid #ccc; }
}

main 要素を使う前と後

<!-- ❌ HTML4 時代の書き方 -->
<body>
  <div id="header">...</div>
  <div id="content">
    <div id="article">...</div>
    <div id="sidebar">...</div>
  </div>
  <div id="footer">...</div>
</body>

<!-- ✅ HTML5 セマンティック -->
<body>
  <header>...</header>
  <main>
    <article>...</article>
  </main>
  <aside>...</aside>
  <footer>...</footer>
</body>

JavaScript で main を活用

// 本文抽出
const mainContent = document.querySelector('main');
const text = mainContent.innerText;
console.log('本文文字数:', text.length);

// 読了時間計算
const wordsPerMinute = 400;  // 日本語の場合
const minutes = Math.ceil(text.length / wordsPerMinute);
console.log(`読了目安: ${minutes} 分`);

// 印刷時に main だけ表示
function printArticleOnly() {
    const original = document.body.innerHTML;
    document.body.innerHTML = mainContent.outerHTML;
    window.print();
    document.body.innerHTML = original;
}

// SPA でルート切替時にフォーカス移動(a11y)
function navigateTo(path) {
    history.pushState({}, '', path);
    const main = document.querySelector('main');
    main.focus();   // スクリーンリーダーが新しいコンテンツを読み始める
}

ブラウザ対応

ブラウザ対応
Chrome / Edge26+(実質ほぼ全バージョン)
Firefox21+
Safari7+
IE 11レンダリングは可、CSS スタイル不可。main { display: block } 必要

IE11 向けには CSS で display: block を明示するのが安全:

/* IE 11 対応 (HTML5 セマンティック要素を block 化) */
header, footer, main, nav, aside, article, section, figure, figcaption {
    display: block;
}

FAQ

Q: <main> を使わずに <div role="main"> でも OK?
A: HTML4 / 古いブラウザ向けには OK。HTML5 では <main> の方が短くて意味も明確です。

Q: ランディングページのように主役が複数ある場合は?
A: 1 つの <main> の中で <section><article> を並べてください。<main> を複数置くのは仕様違反です。

Q: SPA で URL 切替ごとに main を入れ替えても良い?
A: OK。むしろ a11y 上、画面遷移後に <main> にフォーカスを移すのが推奨です。

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. html要素
  2. head要素
  3. body要素
  4. title要素
  5. base要素
  6. meta要素
  7. div要素
  8. span要素
  9. header要素
  10. HTML5 footer 要素の使い方(フッター・コピーライト・連絡先)
  11. main要素
  12. address要素

最近更新/作成されたページ