😈

WordPressで画像ブロックをボタンにしたい(role="button")

に公開

こんにちは!デザインカンプ見てて「あ、このボタン画像じゃん...」ってなることない?
例えばこんなやつ。

  • ロゴ入りの凝ったデザインボタン
  • グラデーションやテクスチャがゴリゴリ入った画像
  • 手書き風のイラストボタン

CSSで再現できないこともないけど、素直に画像使った方が早いし綺麗なこともあるよね。
でもそのまま画像リンクにしちゃうとアクセシビリティ的に問題があるかも。

何が問題なの?

画像にリンクを貼っただけだと、HTMLとしては「画像付きのリンク」でしかない。

<a href="/contact/">
	<img src="contact-button.png" alt="お問い合わせ">
</a>

これ、見た目は完全にボタンなのに、スクリーンリーダーでは「お問い合わせ、リンク」って読み上げられちゃうんですよね🤔

ユーザーからすると:

  • ボタンとして認識されない
  • 「これクリックしていいやつ?リンク?」って混乱する
  • キーボード操作のときもボタンっぽい挙動を期待するのに、ただのリンクだから違和感

本来はボタンブロックを使うべきなんだけど、どうしても画像を使いたいケースってあるよね。

解決策: role="button"でセマンティクスを確保

こういうとき、HTMLにrole="button"を追加すると、「これはボタンですよ」って明示的に伝えられる。

<a href="/contact/" role="button">
	<img src="contact-button.png" alt="お問い合わせ">
</a>

これでスクリーンリーダーが「お問い合わせ、ボタン」って読み上げてくれる! 🎉
でも、WordPressのブロックエディタで画像ブロック使うと、このrole属性って普通つけられないんだよね…

WP_HTML_Tag_Processorを使おう

WordPress 6.2から使えるWP_HTML_Tag_Processorを使えば、出力されるHTMLに後から属性を追加できるよ!
これはHTML文字列を安全にパースして、特定のタグに属性を追加したり変更したりできるAPIだよ。直接preg_replaceとかで無理やり書き換えるより、はるかに安全で確実! 👍

サンプルコード

<?php
/**
 * 画像ブロック内のリンクにrole="button"を追加する
 *
 * 特定のクラスを持つ画像ブロックのリンクに、
 * ボタンロールを付与してアクセシビリティを向上させます。
 *
 * @param string $block_content ブロックのHTML出力.
 * @param array  $block         ブロックの情報.
 * @return string 変更後のHTML.
 */
function add_button_role_to_image_link( $block_content, $block ) {
	// 画像ブロック以外は何もしない
	if ( 'core/image' !== $block['blockName'] ) {
		return $block_content;
	}

	// 特定のクラスがある場合のみ処理
	// (例: 'is-style-button-image'というカスタムスタイルを作った場合)
	if ( empty( $block['attrs']['className'] ) || false === strpos( $block['attrs']['className'], 'is-style-button-image' ) ) {
		return $block_content;
	}

	// HTML Tag Processorでパース
	$processor = new WP_HTML_Tag_Processor( $block_content );

	// 最初のaタグを探す
	if ( $processor->next_tag( 'a' ) ) {
		// role="button"を追加
		$processor->set_attribute( 'role', 'button' );
	}

	return $processor->get_updated_html();
}
add_filter( 'render_block', 'add_button_role_to_image_link', 10, 2 );

コードの解説

  1. render_blockフック: ブロックがHTMLとして出力される直前に実行される
    2 .WP_HTML_Tag_Processor: 安全にHTMLを解析・変更できる
  2. next_tag(): 指定したタグを検索
  3. set_attribute(): 属性を追加・変更
  4. get_updated_html(): 変更後のHTMLを取得

使い方

  1. functions.phpに上記コードを追加
  2. 画像ブロックに「is-style-button-image」クラスを追加
  3. リンク先URLを設定
  4. 完成! 🎊

ブロックエディタの追加CSSクラスで「is-style-button-image」って入れるだけだから、記事ごとに使い分けられるよ!

さらにアクセシビリティを高めるには

role="button"だけじゃ実は不十分(要素がキーボードでフォーカス可能にならない)で、本物のボタンっぽい挙動も必要なんだ。

キーボード操作への対応

ボタンって、EnterキーだけじゃなくてSpaceキーでも押せるよね。リンクはEnterしか効かないから、JavaScriptで対応しよう。

document.addEventListener( 'DOMContentLoaded', function() {
	const buttonImages = document.querySelectorAll( 'a[role="button"]' );

	buttonImages.forEach( function( link ) {
		link.addEventListener( 'keydown', function( e ) {
			// Spaceキーで動作
			if ( e.key === ' ' ) {
				e.preventDefault();
				link.click();
			}
		} );
	} );
} );

これで、キーボードユーザーもスムーズに操作できる!🙌

注意点:こういう時は使わないで

  • 外部サイトへのリンク: ボタンじゃなくてリンクとして認識させた方がいい
  • テキストで表現できる場合: 素直にボタンブロック使おう
  • 複雑なインタラクション: JavaScriptでのイベント処理が必要なら、最初からbuttonタグで実装を

あくまで「デザイン上どうしても画像を使いたい」ときの最終手段だよ!

まとめ

  • 画像をボタンとして使うなら、role="button"でセマンティクスを明示
  • WP_HTML_Tag_Processorを使えば、ブロックの出力を安全にカスタマイズできる
  • キーボード操作にも配慮すると、さらにアクセシビリティUP!

見た目だけじゃなくて、誰にとっても使いやすいサイトを作っていこうね! 🌈

あとがき

この記事は大筋をbissyが、文体を整えるのをAI(Claude)が担当したよ!そしてZennのAIレビューでさらに良い記事になったはず!感謝!

Discussion