私の HTML 定型部分 2026年

My HTML boilerplate in 2026(www.matuzo.at) の記事がおもしろかったので真似てみます。

この記事では本ブログの事例を紹介するのですが、このブログは私個人の技術的検証の場(公園の砂場)を兼ねているので、一般的な Web サイトにおけるベストプラクティスとは言えない箇所もあるのでご注意ください。

2026年8月20日現在における本ブログの記事ページ(URL が /entry/ID 形式のページ)の HTML 定型部分は以下のとおりです。

<!doctype html>
<html lang="ja" prefix="og: https://ogp.me/ns#">
  <head>
    <meta name="viewport" content="width=device-width,initial-scale=1" />
    <meta name="text-scale" content="scale" />

    <link rel="alternate" href="/feed" type="application/atom+xml" title="「富永日記帳」の新着フィード" />

    <link rel="stylesheet" href="/style/blog.css" />
    <link rel="stylesheet" href="/style/layout_full.css" title="通常表示" />
    <link rel="alternate stylesheet" href="/style/layout_reader.css" title="リーダー表示" />
    <link rel="stylesheet" href="/style/layout_reader.css" media="print" />

    <script src="/script/blog.mjs" type="module"></script>
    <script src="https://analytics.w0s.jp/matomo/matomo.js" async=""></script>
    <script src="/script/analytics.js" defer=""></script>

    <title>記事タイトル</title>

    <meta property="og:title" content="記事タイトル" />
    <meta property="og:type" content="article" />
    <meta property="og:image" content="https://blog.w0s.jp/entry/image/XXX.jpg" />
    <meta property="og:url" content="https://blog.w0s.jp/entry/ID" />
    <meta property="og:locale" content="ja_JP" />
    <meta property="og:site_name" content="富永日記帳" />
    <script type="application/ld+json">
      {
        "@context": "https://schema.org/",
        "@type": "BlogPosting",
        "datePublished": "投稿日時",
        "dateModified": "最終更新日時",
        "headline": "記事タイトル",
        "image": "https://blog.w0s.jp/entry/image/XXX.jpg"
      }
    </script>
  </head>
  <body>
    ...
  </body>
</html>

DOCTYPE

§

<!doctype html>

DOCTYPE は DOCTYPE を大文字、html を小文字で表記するのが好みです。過去に Polyglot Markup において DOCTYPE は大文字で書くように推奨(W3C)されており、また実際に XHTML、それも本物の application/xhtml+xml で配信していた期間がそれなりに長かったこともあり、いまでも DOCTYPE を小文字で書くことには心理的な抵抗があるからです。

しかし実際には上記のようにすべて小文字となっています。これは本ブログでビルド時に使用している Prettier が2023年のバージョン 3.0 以降、DOCTYPE 部分を強制的に小文字に変換するようになったからです[1]。HTML は Web でのみ使われる技術ではなく、例えば EPUB 分野では XML MIME タイプ(いわゆる XHTML)が今も現役なので、フォーマッターがそれを無視する方針を採ることには HTML の可能性を狭める懸念もあります。ただし本ブログのビルドに限って言えば強制小文字化で困ることもないため、渋々それに従っている次第です。

将来的に大文字・小文字を任意に選択できるフォーマッターに乗り換えるならば <!DOCTYPE html> にするつもりです。

<html> 要素の開始タグ

§

<html lang="ja" prefix="og: https://ogp.me/ns#">

lang 属性のほかに後述する OGP のために prefix 属性を設定しています。もっとも実際には prefix 属性を書かずとも主要な SNS サービスには問題なく認識されますから、省略している Web サイトも多く見られます。

<head> 要素内の順序

§

<meta name="XXX" content="XXX" />
<link rel="XXX" href="XXX" />
<script src="XXX"></script>
<title>XXX</title>
<meta property="og:XXX" content="XXX" />
<script type="application/ld+json"></script>

まず OGP 以外の <meta> 要素を配置します。<meta> 要素による文字エンコーディング宣言(WHATWG)を行う場合、HTML ドキュメントの冒頭 1024 バイト以内に含める必要があるなど、他の要素より優先すべき理由があるためです。

次に <link> 要素、そして JSON-LD 以外の <script> 要素を配置します。これはスクリプトよりスタイルシートの読み込みを先に開始した方が好都合だからです。

<title> 要素を挟んで最後の方には OGP や JSON-LD など重要性の低いものを置きます。OGP より JSON-LD を後に配置していることに深い意味はありません。

文字エンコーディング宣言

§

<!-- 記述なし -->

本ブログでは <meta charset="UTF-8"> を書いていません。文字エンコーディングの宣言で重要なのは HTTP の Content-Type ヘッダーで charset パラメーターを含めることであり、<meta> 要素の記述は HTML 仕様的にもブラウザの挙動からしても任意だからです。

任意といえど以下のケースではメリットがあります。

  • サーバー設定の意図せぬ変更で Content-Type ヘッダーの charset パラメーターが送出されなくなった場合の保険的対策
  • ユーザーが HTML をファイルとしてローカルに保存し、file:// URI スキームで閲覧する場合

しかし今どきはフレームワークが Content-Type ヘッダーに charset=utf-8 を強制的に付与しますし(検証で意図的に外す際はむしろ苦労する)、 <meta> 要素なしの HTML ファイルを file:// URI スキームで開いた際も文字化けには滅多に遭遇しません。そのため <meta> 要素を記述する必要性は昔と比べて限りなく低くなったといえるでしょう。

なおそれでも charset パラメーターを送出できずに HTML で文字エンコーディング宣言を行わざるを得ない場合は、互換性の観点から <meta charset> ではなく昔ながらの <meta http-equiv="Content-Type"> を採用すべきです。charset 属性に対応していない環境[2]はごく稀なケースではあるものの、しかしそもそも <meta> を必要とするケースそのものが稀なのですから、<meta> を書きつつ100%の環境が対応しているとは言い切れない charset 属性に頼る(おそらくは記述が簡素という理由だけで)のは中途半端な方針に思います。

本ブログではこれらを考慮のうえ、そもそも Content-Type ヘッダーで charset パラメーターを指定しているため、<meta> 要素による文字エンコーディング宣言は不要と判断しています。

<meta> 要素の viewporttext-scale

§

<meta name="viewport" content="width=device-width,initial-scale=1" />
<meta name="text-scale" content="scale" />

主にスマートフォンでの表示最適化とアクセシビリティ向上(ユーザー設定尊重)のために上記2つの <meta> 要素を入れています。

initial-scale=1 はもう要らないと思うのですが、それを検証していない(消しても問題ないか確証が持てない)ので消極的な理由で残している次第です。まあでもさすがにそろそろ消すかも。

text-scale の導入は時期尚早に思います。2026年8月現在、対応環境が限定的なので Android と iPhone の2台持ちユーザーがタブの共有(送信)機能を使うなどして端末間を行き来しながら閲覧する場合、OS の環境を合わせていてもブラウザ内の文字サイズが変わってしまうことは混乱を引き起こす懸念があるからです。冒頭に記したように本ブログは実験場を兼ねているため新しい技術をいち早く取り入れることがあり、これもその一例となります。一般的なサイトにおける text-scale の導入は慎重な検討が必要でしょう。

ちなみに思想的には <meta> 要素を一切入れたくない(fedibird.com)と思っており、複雑な想いを抱えながらの導入ではあります。100年後には人類はいくつの <meta> 要素を書いている(書かざるを得ない)のだろう……。

タイトル

§

<title>記事タイトル</title>

<title> 要素のテキストはあくまでページタイトル(記事タイトル)のみとしています。他の多くのサイトがやっているように縦線区切りでサイト名を含めていた時期もあったのですが、近年は多くの検索サービスでサイト名を自動的に取得、提示してくれるので、もはやそのような工夫は不要と考えています。

一方でカテゴリーごとの記事一覧ページ等ではサイト名を先頭に含めています。具体例を挙げると「HTML」の記事一覧のページにおいて、<h1> 要素の文言と同じく <title>「HTML」の記事一覧</title> としてしまうとむしろ不正確です。世界中の HTML に関する記事をまとめているわけではなく、あくまで本ブログの中での HTML 記事一覧に過ぎないので、タイトルは <title>富永日記帳: 「HTML」の記事一覧</title> としているのです。この場合はむしろサイト名がまず重要なので末尾ではなく先頭に挿入しています。

区切り記号をコロンにしていることにこだわりはないのですが、一般に行われているページタイトルとサイト名の区切りとは意味合いが違うため、それらで採用されがちな縦線やハイフン、ダッシュ等を避けて別の記号文字の中から選んだ次第です。ただし U+003A はファイル名に使用できない文字であり、場合によっては別の文字に変換されてしまう事象があります[3]。そういったデメリットは承知のうえで、それでもコロンが適当かなあと。

フィード

§

<link rel="alternate" href="/feed" type="application/atom+xml" title="「富永日記帳」の新着フィード" />

すべてのページにおいて <link rel="alternate"> によるフィードのリンクを提示しています。

しかしこうすることには未だ心理的な抵抗があります。HTML4 時代の alternate 値はその名のとおりリンクのある Web ページの代替となりうることのみを意味するものだったのに対して、代替とは限らないフィードへのリンクに alternate 値を使うのは不適切であり、feed(W3C) を使うべきとの意見が HTML5 初期には存在しました。ただし rel=feed を実装したブラウザは Firefox のみだったと言われており、2010年3月には W3C HTML5 仕様(Working Draft)から削除された経緯があります。

本ブログの場合、ブログのトップページからフィードへリンクする際は HTML の代替表現として alternate 値を使うのは本来の意味からしても適切なのですが、個別の記事ページに対してフィードは「代替」たり得ません。そのため一時期は意味合いを重視してトップページからのみフィードリンクを張っていた時期がありました。しかし上記のとおり HTML 仕様において feed 値が廃止されて alternate 値に一本化されたため、もはや alternate の本来の意味に固着することもあるまいと思い直し、すべてのページにリンクを張るようにした次第です。

とはいえ心の片隅にもやっとしたものが拭えないのも事実です。きっとこの想いは一生消えないでしょう。HTML というものはこうやって徐々に闇を増やしつつ進化してゆく(しかない)ものなのです。

ファビコン

§

<!-- 記述なし -->

ファビコンは SVG 形式にしたうえでファイルパスを /favicon.ico とすることで <link rel="icon"> を省略しています。ファビコンは HTML リソースにとってのみ必要なのではなく、画像を単体で表示したときや PDF、プレーンテキスト等でも表示されるものですから、それらとの整合性を考えると <link> 要素に頼らずファイルパスベースで提供する方が好ましいと考えます。

ただし理屈はそうであっても、SVG ファビコンは2026年現在もいまだブラウザや検索サービスの対応が不安定であり[4]、現時点では PNG や ICO へフォールバックする(すなわち <link> 要素を書く)ほうが安全です。

繰り返しますが本ブログは技術的な実験場を兼ねているので、不安定な手法はむしろ積極的に採用してそのデメリットも含めて検証している面があります。

CSS

§

<link rel="stylesheet" href="/style/blog.css" />
<link rel="stylesheet" href="/style/layout_full.css" title="通常表示" />
<link rel="alternate stylesheet" href="/style/layout_reader.css" title="リーダー表示" />
<link rel="stylesheet" href="/style/layout_reader.css" media="print" />

代替スタイルシート(WHATWG)を使ってリーダー表示を提供しています。今では各ブラウザにリーダービューが実装されているので、あえて制作者スタイルシートで提供する意味合いは薄いのですが、本ブログでは上記コードのとおり印刷用スタイルとリーダー表示を同一スタイルとしており、この提供に際しての管理コストがゼロに近いため残している次第です。

もうひとつの理由として、昨今のフロントエンドフレームワークは代替スタイルシートに対応していない……というかおそらく存在すら忘れ去られていて今後の対応見込みも皆無なため、せめて自分のサイトに実例として残すことで、ブラウザの実装状況に変化があったときにすぐに気づける体勢を整えている面もあります。これぞ個人サイトの醍醐味と言えるでしょう。

JavaScript

§

<script src="/script/blog.mjs" type="module"></script>
<script src="https://analytics.w0s.jp/matomo/matomo.js" async=""></script>
<script src="/script/analytics.js" defer=""></script>

Web ページで使用する JavaScript は基本的に Module script として type=module を設定しているのですが、それができない機能(現時点ではアクセス解析のみ)は async ないし defer 属性を設定しています。

両属性のないクラシックスクリプト、すなわち読み込み・実行中に HTML のパースを中断するタイプのスクリプトは使用していません。また <body> 要素の終了タグ直前に <script> 要素を配置するテクニックも使用しません。

OGP

§

<meta property="og:title" content="記事タイトル" />
<meta property="og:type" content="article" />
<meta property="og:image" content="https://blog.w0s.jp/entry/image/XXX.jpg" />
<meta property="og:url" content="https://blog.w0s.jp/entry/ID" />
<meta property="og:locale" content="ja_JP" />
<meta property="og:site_name" content="富永日記帳" />

画像のある記事のみ OGP を設定しています。

世の中にはサイト全体で一律の画像を og:image に設定しているケースも多く見られますし、本ブログでも以前そうしていた時期があったのですが、そのような利用法は不適切と捉える考え方もあります[5]

またページタイトルや著者名などを含めた画像を自動生成しているサービスもあるものの、ページタイトルは <title> 要素、著者情報は <link rel=author><meta name=author> などで提示することができるのですから、それらを画像情報として提示するメリットを感じません。そのため本ブログでは画像のない記事に OGP を設定することはせず、単に省略しています(この記事もそのひとつです)。

なお一時期 Twitter Card 用の <meta name="twitter:card"><meta name="twitter:site"> を設定していたのですが、2023年7月にログインをしないと閲覧に制限が付くようになって以来、Twitter は情報を広く共有する性質のサービスではなくなったこと、そして自分自身がメインで使うのを止めたことから廃止しています。

JSON-LD

§

<script type="application/ld+json">
  {
    "@context": "https://schema.org/",
    "@type": "BlogPosting",
    "datePublished": "投稿日時",
    "dateModified": "最終更新日時",
    "headline": "記事タイトル",
    "image": "https://blog.w0s.jp/entry/image/XXX.jpg"
  }
</script>

Schema.org による構造化データを提供しています。とくに datePublisheddateModified は検索サービスでの表示時に日付が表示され、ユーザーがリンクを選択するか(このブログに訪問してくるか)どうかの判断基準となる効用が期待できます。もっとも実際にどれほどの効果があるのかの測定はしていません。

以前は <time datetime="XXX" itemprop="datePublished"> のようなマークアップをしていた時期もあったのですが、普通の HTML 要素の中に構造化データが混じると見通しが悪いため、JSON-LD として独立させた次第です。

脚注