Hiratake Web ロゴ

ブログの投稿一覧ページのマークアップを見る

投稿した日
更新した日
書いたひと
icon
ひらたけ

一般的なブログのウェブサイトにはブログ投稿の一覧ページが存在していると思います。その ブログの投稿一覧ページのマークアップってみんなどうしてるんだ というのがふと気になったので、いくつかのブログなどのサービスのコードを見に行くなどしてゆるーく調べてみることにしました。

たぶん「これが正解」というのは無いし、違うからといって大きな問題が起こるということも無いとは思いますが、可能な限りブラブザや検索エンジンが理解しやすいマークアップにしたい所存。

MDN Blog

まずはウェブのエンジニアならお馴染みの MDN Web Docs のブログ。HTML のタグや CSS のプロパティなどについての詳しい説明が載ってるウェブサイトのブログなので、HTML の仕様に則った正しいマークアップがされているに違いない(たぶん)。

この投稿を執筆している時点でのブログ投稿一覧部分のマークアップは以下のような感じ(2024 年 9 月時点のものです)。省略している <article> の中身については後に書いています。

<main lang="en-US">
  <header>
    <h1>Blog it better</h1>
  </header>

  <section>
    <article><!-- 省略 --></article>
    <article><!-- 省略 --></article>
    <article><!-- 省略 --></article>
  </section>
</main>

ページのメイン部分が <main> タグで囲まれているのは当然として、その下に <header> タグがありページのタイトルが入った <h1> タグが配置されています。<header> タグは決してグローバルナビゲーションなどがあるウェブサイト全体のヘッダーでしか使えないタグなどではなく、ページ内で複数記述が可能です。

その次に記述されているのは <section> タグで、この要素の中に各ブログの内容が入った <article> タグが複数配置されています。特徴的なのは、各ブログの投稿を <article> タグで囲んでいて、このタグがブログの投稿の数の分だけ並んでいることでしょうか。

<article> タグというとブログの個別ページ(本文を読む画面)で全体を囲むのに使うのが一般的なイメージですが、ドキュメント には以下のように書かれており、たしかにそれぞれのコンテンツは別の投稿の内容で自己完結しているので使い方が間違っていることは無さそうです。

HTML の要素で、文書、ページ、アプリケーション、サイトなどの中で自己完結しており、(集合したものの中で)個別に配信や再利用を行うことを意図した構成物を表します。

<section> の直下にあるのは <article> タグのみで、見出しタグはありません。一般的にはセクションには見出しを置かなければならないルールですが、<article> 内に見出しがあるから OK ということなのか、ドキュメント にもある「少数の例外」に当てはまるものなのかは謎。

<article>
  <header>
    <figure>
      <a href="">
        <img alt="" src="" height="200">
      </a>
    </figure>
    <h2>
      <a href="">投稿のタイトル</a>
    </h2>
    <div>
      <a href="" target="_blank" rel="noreferrer">
        <img src="" alt="Author avatar">
        著者の名前
      </a>
      <time>日付</time>
      <span>XX minute read</span>
    </div>
  </header>
  <p>投稿の概要</p>
  <footer>
    <a href="" target="_self">
      <span>Read more →</span>
    </a>
  </footer>
</article>

続いては各ブログの投稿の内容が書かれている <article> タグの中身。中身は <header> 要素と、投稿の内容についての概要の文章、それから <footer> 要素です。

<article> の中身全体をリンクにはせず、アイキャッチ画像とタイトルのテキスト、下のほうにある「Read more」のボタンを押したときに個別ページへ遷移するように <a> タグが設定されていました。これは投稿の著者の方の名前部分にそれぞれの SNS やプロフィールページなどのページへのリンクが設定されていて、<a> の中に <a> を入れることは許容されていないためこのようにしているのでしょうか。

個人的に驚いたのは <time> 要素に datetime 属性が指定されていないこと。これ必須だと思っていたのですが、無くてもいいっぽい。

ただし、datetime 属性がない場合は <time> の中に子孫要素を持つことはできず、中に記述したテキストの内容が datetime 属性の値として適用されるみたい。

あと、マークアップからは少し話がそれますが、CSS の サブグリッド が多用されているのが気になりました。わりと新しめな機能なはずですが、MDN が使ってるならもう普通に使って大丈夫なのかな?最新のブラウザであれば対応してそうだし。

The Mozilla Blog

こちらは Firefox などで有名な Mozilla のブログ。先ほどの MDN Blog も Mozilla が運営するものですが、こちらの The Mozilla Blog のほうは WordPress で動いているようです。

この投稿を執筆している時点でのブログ投稿一覧部分のマークアップは以下のような感じ(2024 年 9 月時点のものです)。省略している <section> の中身については後に書いています。

<main>
  <div>
    <header>
      <h2>Latest Posts</h2>
    </header>

    <div>
      <section><!-- 省略 --></section>
      <section><!-- 省略 --></section>
      <section><!-- 省略 --></section>
    </div>

    <nav>
      <div>
        <span aria-current="page">1</span>
        <a href="">2</a>
        <a href="">3</a>
        <span>…</span>
        <a href="">151</a>
        <a href="">next</a>
      </div>
    </nav>
  </div>
</main>

基本的な構造としては MDN Blog と同じですが、<section> で各投稿の一覧を囲んでいた部分が <div> 要素に、各投稿は <article> ではなく <section> になっているなど、使われているタグが異なります。

また、MDN Blog では投稿数が少なくて表示されていませんでしたが、こちらにはページネーションが設置されていて 2 ページ目、3 ページ目と移動することができるようになっています。

ページネーション全体がナビゲーションのセクションであることを示す <nav> 要素で囲まれ、現在表示中のページ番号が記述された <span> タグには aria-current 属性が付与され、値に page が指定されています。

最も古い投稿がある 151 ページ目まで移動するリンクも表示されていますが、ここは「わざわざ一番古い投稿を見ようとする人ってそんなに居るのか?」という部分の考え方次第で出す・出さないが分かれるところな気はします。個人的には要らないかな派。

<section>
  <a href="">
    <div>
      <img width="800" height="800" src="" alt="" decoding="async" fetchpriority="high" srcset="" sizes="">
    </div>
    <div>
      <div>
        <div>
          <div>カテゴリ名</div>
        </div>
        <h2>投稿のタイトル</h2>
        <span>Read More</span>
      </div>
    </div>
  </a>
</section>

各ブログ投稿の内容が書かれている <section> タグの中は、まず全体が <a> で囲まれどこをクリックしても個別ページへ遷移するようになっています。内容は画像とカテゴリ名とタイトル、それから「Read More」のテキストのみとシンプル。

画像の <img> タグには、様々な属性が付与されているのが確認できます。decoding 属性が指定されている他、現在閲覧中のページ内で最も新しい投稿にある画像にのみ fetchpriority 属性が付与されているようでした。これは WordPress 側が勝手にいい感じに付けてくれるものなのかな?

このへんの画像の遅延読み込みとかの部分、どうするのが良いのかイマイチよく分かってないので難しいなーというお気持ち。

Zenn

ブログではないですが、投稿の一覧があるサービスとして多くの技術系のコンテンツが集まる Zenn のコードものぞいてみます。

この投稿を執筆している時点でのブログ投稿一覧部分のマークアップは以下のような感じ(2024 年 9 月時点のものです)。省略している <article> の中身については後に書いています。

<section>
  <div>
    <div>
      <h3>Tech</h3>
      <span aria-label="プログラミングなどの技術についての知見" role="tooltip">
        <span aria-label="詳細を確認する">?</span>
      </span>
    </div>

    <div>
      <div>
        <article><!-- 省略 --></article>
      </div>
      <div>
        <article><!-- 省略 --></article>
      </div>
      <div>
        <article><!-- 省略 --></article>
      </div>
    </div>
  </div>
</section>

「Tech」「Ideas」「Books」などのカテゴリに分かれているトップページの内容のうちのひとつ、「Tech」の部分を見てみると、外側は <section> で囲まれ各投稿は <article> で囲まれていることが分かります。

見出しの隣にある「?」のアイコンには aria-label 属性が付与されていて、ウェブアクセシビリティを考慮した実装がされていることが分かります。

<article>
  <a href="">
    <span>
      <span style="background-image: url(絵文字の画像のURL);"></span>
    </span>
    <span>🍄</span>
  </a>
  
  <div>
    <a href="">
      <h2>投稿のタイトル</h2>
    </a>
    <div>
      <div>
        <a href="">
          <img alt="著者の名前" height="26" loading="lazy" referrerpolicy="no-referrer" src="" width="26">
        </a>
      </div>
      <div>
        <div>
          <a href="">著者の名前</a>
        </div>
        <div>
          <time datetime="">XX日前</time>
          <span>
            <svg x="0px" y="0px" viewBox="0 0 110 110" xml:space="preserve" aria-label="いいねされた数" height="14" width="14"></svg>
            XXX
          </span>
        </div>
      </div>
    </div>
  </div>
</article>

各投稿の内容が書かれている <article> タグの中には、投稿のタイトルや著者の情報などに加えて Zenn といえばの絵文字が入っています。

カテゴリの「Tech」が書かれた見出しが <h3> だったのに対して、投稿のタイトルが <h2> で記述されているのがちょっと気になりました。HTML の構造的にはカテゴリの見出しよりも投稿のタイトルのほうがより深い位置にあるけれど、ページを見る順番としてはこちらが先ということでしょうか。ちょっと意図を聞いてみたさある。

Google Japan Blog

ネットで調べ物をするときに大多数のユーザが利用するであろう Google 社の検索エンジン。そんな Google さんのブログ。Wagtail という Python(Django)製の CMS で動いているようです。

コードを見てみると、何やら <uni-article-feed> やら <uni-article-card> といった見慣れない要素が多数。Lit という Google 社が開発している Web Components を簡単に扱えるようにするライブラリがあるようなので、そちらを使って実装されているのかもしれません。

あと何年かすれば、Web Components を使うのが一般的になるとかするんですかね…。


いくつか見てみましたが、それぞれサイトの見た目が異なるのでスタイリング用の <div> などが適宜入っていてマークアップも異なるのは当然のこととして、各投稿は <article> もしくは <section> で囲んであるものが多そうだなという印象。

個人的には MDN Blog のマークアップが良さげに感じましたが、実装上の都合とか CSS でのスタイリングの都合とかもあるでしょうし、ターゲットとするユーザの違いによっても変わるのかも。今後も他のサービスやウェブサイトのコードを覗き見するなどして情報を収集していきたい所存。