alt="" WordPressの画像alt属性を
自動補完するプラグインを作った話

WordPressで運営しているサイトの過去記事を見直していたとき、多くの画像にalt属性が設定されていないことに気づきました。

きっかけ:過去記事のメンテナンス alt=”” alt=”” alt=”” 100記事以上のalt属性が未設定 手作業での修正は現実的でない 自動補完プラグインを作成

alt属性は画像の代替テキストで、視覚障害のある方がスクリーンリーダーを使用する際や、画像が表示されない環境で重要な役割を果たします1

100記事以上ある過去記事を一つずつ手作業で修正するのは現実的ではありません。そこで、alt属性を自動補完するプラグインを作ることにしました。

関連記事

1. 最初の課題:何をalt属性に設定するか

alt属性を自動設定するといっても、画像の内容を自動認識できるわけではありません。適切な代替テキストを推測する必要があります。

alt属性の自動設定ロジック 1 キャプション なし 2 直前の見出し なし 3 記事タイトル 文脈に沿った代替テキストを自動設定

私が考えたロジックは次のようなものです。

1.1. 本文内の画像には見出しを活用

WordPress記事では、画像は通常<figure>タグで囲まれています。この画像に対して、優先順位をつけてalt属性を設定することにしました。

  1. 画像に付けられたキャプション(<figcaption>)があればそれを使う
  2. キャプションがなければ、直前の見出し(h2またはh3)のテキストを使う
  3. どちらもなければ、記事タイトルを使う

このロジックなら、多くの場合で文脈に沿った代替テキストを設定できそうです。

1.2. アイキャッチ画像には記事タイトル

アイキャッチ画像については、基本的に記事タイトルをalt属性として設定します。アイキャッチ画像は記事全体を象徴する画像なので、記事タイトルが代替テキストとして適切だと判断しました。

2. DOMDocumentを使った実装

実装にあたって、PHPのDOMDocumentクラスを使用することにしました2。正規表現でHTMLを解析すると、ネストした構造や特殊な文字に対応するのが困難です。DOMDocumentを使えば、HTML構造を正確に解析できます。

DOMDocumentを使った実装 メリット ✓ HTML構造を正確に解析 ✓ ネスト構造に対応 $dom = new DOMDocument(); $dom->loadHTML($html); $xpath = new DOMXPath($dom); HTML 読み込み DOM解析 XPath処理 alt属性 設定完了 正規表現ではなくDOM APIを使用することで 複雑なHTML構造にも対応可能
function set_auto_alt_text_for_all_images($content) {
    // 管理画面やフィードでは処理しない
    if (is_admin() || is_feed()) return $content;
    
    // 画像がなければ何もしない
    if (stripos($content, '<img') === false) return $content;
    
    $dom = new DOMDocument('1.0', 'UTF-8');
    // 本文をラップして読み込む
    $wrapper_id = '__altwrap__' . wp_generate_password(8, false, false);
    $html = '<!DOCTYPE html><html><head><meta charset="utf-8"></head><body><div id="' . $wrapper_id . '">' . $content . '</div></body></html>';
    
    $dom->loadHTML($html, LIBXML_NOWARNING | LIBXML_NOERROR);
    // 以下、DOM操作の処理...
}
Code language: PHP (php)

2.1. 遭遇した問題:ショートコードが展開されない

最初のバージョンでは、ショートコードが展開される前にalt属性を設定していました3

遭遇した問題:ショートコード展開 × 初期バージョン ショートコード内の画像が漏れる プラグイン 優先度: 10 = ショートコード 優先度: 10 現在の運用 デフォルト優先度を維持 ※ショートコード使用が 少ないため実用上問題なし

WordPressでは、ショートコードの展開はthe_contentフィルターの優先度10で実行されます。私のプラグインも同じ優先度で実行していたため、ショートコード内の画像が処理対象から漏れていました。

この問題は、フィルターの優先度を調整することで解決しました。
ただし、他のプラグインとの競合を避けるため、デフォルトの優先度のままにしています。
実際の運用では、ショートコードを使った画像挿入をあまり行っていないため、現状では大きな問題にはなっていません。

3. アイキャッチ画像のパフォーマンス改善

alt属性の設定と並行して、アイキャッチ画像のパフォーマンス改善にも取り組みました。

アイキャッチ画像のパフォーマンス改善 Before フルサイズ 3000×2000px ⚠ 重い 2-3MB After largeサイズ 1024px幅 ✓ 軽量 200-400KB 表示サイズは維持したまま 読み込むファイルだけ軽量化 → レイアウトシフト(CLS)を防止

以前のテーマ設定では、アイキャッチ画像にフルサイズ(例:3000×2000px)の画像を使用していました。ページの読み込み速度が遅く、特にモバイル環境でのパフォーマンスが悪化していました。

3.1. 解決策:表示サイズを維持したままファイルを軽量化

単純に画像サイズを小さくすると、デザインが崩れる可能性があります。そこで、次のような処理を実装しました。

  1. 実際に読み込むファイルはlargeサイズ(例:1024px幅)に変更
  2. HTML上のwidthheight属性はフルサイズのまま維持
  3. ブラウザが自動的に縮小表示する
function customize_thumbnail_size_and_attr($html, $post_id, $post_thumbnail_id, $size, $attr) {
    // largeサイズの画像を取得
    $large_image = wp_get_attachment_image_src($post_thumbnail_id, 'large');
    // fullサイズの寸法情報を取得
    $original_size = wp_get_attachment_image_src($post_thumbnail_id, 'full');
    
    if ($large_image) {
        // 読み込むファイルはlarge
        $attr['src'] = $large_image[0];
        
        // 表示サイズはfullのまま
        if ($original_size) {
            $attr['width'] = $original_size[1];
            $attr['height'] = $original_size[2];
        }
        
        // srcsetでレスポンシブ対応
        $attr['srcset'] = wp_get_attachment_image_srcset($post_thumbnail_id, 'medium');
        $attr['sizes'] = '(max-width: 1920px) 100vw, 1920px';
    }
    
    return $html;
}
Code language: PHP (php)

この方法により、ファイルサイズを大幅に削減しながら、レイアウトシフト(CLS)を防ぐことができました。

3.2. 実装上の矛盾と今後の課題

現在のコードには矛盾があります。src属性にはlargeサイズを使用していますが、srcset属性はmediumサイズをベースにしています。

これは試行錯誤の過程で生まれた矛盾です。レスポンシブ画像の仕組みを考えると、srcsetlargeに統一すべきかもしれません。ただし、現在の設定でもページの読み込み速度は改善されており、実用上の問題はありません。

より最適な画像配信を実現するには、画像の使用状況を詳しく分析し、各サイズの役割を再検討する必要があります。

4. プラグイン化の決断

当初は子テーマのfunctions.phpに直接コードを書いていました。しかし、機能が増えるにつれて、プラグインとして独立させることにしました。

プラグイン化の決断 functions.php 直接記述 プラグイン化 独立した機能 テーマ変更に 影響されない 機能のON/OFF が簡単 他サイトでも 再利用可能 バージョン管理 がしやすい

プラグイン化のメリットは次の通りです。

  • テーマの変更に影響されない
  • 機能のオン・オフが簡単
  • 他のサイトでも再利用できる
  • バージョン管理がしやすい

実際にプラグインとして分離してみると、コードの見通しが良くなり、メンテナンスもしやすくなりました。

5. 運用してわかったこと

このプラグインを実際に運用して数ヶ月が経ちました。いくつかの発見がありました。

5.1. 自動設定の限界

alt属性の自動設定は便利ですが、完璧ではありません。画像の内容と見出しが必ずしも一致するわけではないからです。

たとえば、「WordPressのインストール方法」という見出しの下に、設定画面のスクリーンショットがあるとします。自動設定では「WordPressのインストール方法」がalt属性になりますが、理想的には「WordPress管理画面の一般設定」のような、より具体的な説明が望ましいです。

それでも、alt属性が空のままより、文脈に関連したテキストが設定されている方がずっと良いと考えています。

6. 処理の対象を限定した理由

このプラグインは、<figure>タグ内の画像のみを処理対象としています4。本文中の<figure>外の画像は処理しません。

これには理由があります。装飾目的の画像(区切り線やアイコンなど)は、意図的にalt属性を空にすることが推奨されています。すべての画像にalt属性を設定すると、かえってアクセシビリティを損なう可能性があります。

<figure>タグは、本文の流れの中で意味を持つ画像を示すHTMLタグです。ここに含まれる画像だけを対象にすることで、装飾画像と区別しています。

7. プラグインの構成

最終的なプラグインは、3つの主要な機能を持っています。

  1. 本文内の<figure>画像のalt属性自動設定
  2. アイキャッチ画像のalt属性自動設定
  3. アイキャッチ画像のサイズ・属性最適化

これらの機能は、それぞれ独立したフィルター関数として実装されています。
必要に応じて個別に有効化・無効化できる設計です。

// フィルターの登録
add_filter('the_content', 'set_auto_alt_text_for_all_images');
add_filter('post_thumbnail_html', 'set_auto_alt_text_for_featured_image', 10, 5);
add_filter('post_thumbnail_html', 'customize_thumbnail_size_and_attr', 20, 5);
Code language: JavaScript (javascript)

フィルターの優先度も考慮しています。アイキャッチ画像については、まずalt属性を設定し(優先度10)、次にサイズと属性を調整します(優先度20)。

8. 得られた知見

このプラグインを作る過程で、いくつかの技術的な知見を得ました。

8.1. DOMDocumentの文字化け対策

DOMDocumentでHTMLを読み込む際、文字エンコーディングの問題が発生することがあります。特に日本語を含むHTMLでは注意が必要です。

解決策は、HTMLの先頭に適切なDOCTYPEとmetaタグを付加することです。

$html = '<!DOCTYPE html><html><head><meta charset="utf-8"></head><body>' . $content . '</body></html>';
Code language: HTML, XML (xml)

8.2. フィルターの重複登録を防ぐ

プラグインやテーマの競合を避けるため、フィルターの重複登録をチェックしています。

if (!has_filter('the_content', 'set_auto_alt_text_for_all_images')) {
    add_filter('the_content', 'set_auto_alt_text_for_all_images');
}
Code language: JavaScript (javascript)

この記述により、同じフィルターが複数回登録されることを防げます。

8.3. 関数の存在チェック

他のプラグインやテーマとの名前空間の衝突を避けるため、関数定義の前に存在チェックを行っています。

if (!function_exists('customize_thumbnail_size_and_attr')) {
    function customize_thumbnail_size_and_attr($html, $post_id, ...) {
        // 処理
    }
}
Code language: PHP (php)

9. 実際の効果

プラグインを導入して、サイトのアクセシビリティとパフォーマンスが改善されました。

アクセシビリティチェックツールで検証したところ、画像関連のエラーが大幅に減少しました。すべてのエラーが解消されたわけではありませんが、自動処理できる範囲では十分な効果が得られています。

ページ読み込み速度も改善され、ユーザー体験の向上につながりました。特にモバイル環境での改善が顕著でした。

10. まとめ

WordPressサイトの画像にalt属性を自動設定するプラグインを作成しました。完璧ではありませんが、過去記事のメンテナンスを大幅に軽減できました。

アクセシビリティは、一度設定すれば終わりというものではありません。継続的な改善が必要です。このプラグインは、その改善を自動化する一つの手段として機能しています。

コードは試行錯誤の跡が残っていますが、それも含めて実際の開発の記録です。今後も運用を続けながら、少しずつ改善していく予定です。

  1. alt属性はWCAG(Web Content Accessibility Guidelines)の達成基準1.1.1で要求されており、ADAやSection 508などの法律でも義務付けられています – WordPress Alt Text Best Practices – Equalize Digital
  2. DOMDocumentはHTML4パーサーを使用しており、PHP 8.4以降ではHTML5標準に準拠した新しいDom\HTMLDocumentクラスが利用可能です – PHP: DOMDocument::loadHTML – Manual
  3. WordPressのショートコードはdo_shortcode関数により優先度11で処理されます。ショートコード展開後に処理を行うには、優先度12以上を指定する必要があります – WordPress – add content filter after shortcode execution – InfoHeap
  4. 装飾目的の画像には空のalt属性(alt=””)を設定することが推奨されています。これによりスクリーンリーダーが装飾画像をスキップし、ユーザー体験が向上します – Alt Text, alternative text for images – Make WordPress Accessible