お問い合わせはコチラから

Cocoonの吹き出しブロックのアイコンにwidthとheightを追加するカスタマイズ

サイト運営

WordPress5.5からNative Lazylodに対応しました。同時に、Wordpressの機能を使って追加された画像には自動的にwidthとheightが追加されるようになりました。これはNative Lazyload実行時にimgタグにwidth/heightを追加することでCLSを悪化させないための対策になっています。

ところがCocoonの吹き出しブロックのアイコンにはwidthとheightの指定がありません。その影響でLazyload有効時にレイアウトシフトが発生してCLSが悪化する場合があります。

この記事では、Wordpress 5.5以上になってもimgタグにwidthとheightが追加されない要素に対して独自にwidthとheightを追加するカスタマイズをご紹介します。

Cocoonの吹き出しブロックのアイコンにwidthとheightが設定されない理由

WordPress5.5以降でimgタグにwidth/heightが自動的に追加される条件は?

WordPressの該当部分のソースコードを確認します。

条件:imgタグのclassにwp-image-{画像ID}が追加されているかどうか

imgタグのclassにwp-image-{画像ID}が追加されている場合に、widthとheightが自動的に追加されます。

WordPressでは、画像のwidthとheightを取得する時に画像IDを使用します。HTML内に画像IDがわかる情報としてwp-image-{画像ID}を使用しているので、それが無いものは対象外としているようです。

なので、wp-image-{画像ID}のclassが追加されていないimgタグはwidth/heightの追加対象外になっています。

ブロックエディタで画像を追加している場合は、wp-image-{画像ID}が自動的に追加されますので問題ありませんが、テーマやプラグインの独自機能などで挿入される画像にwp-image-{画像ID} classが無いものがあるとwidth/heightが追加されません。

Cocoonの吹き出しブロックのHTML

WordPress5.5以降のimgタグへwidth/heightを自動追加する条件(wp-image-{画像ID}がclassにある)に合致していません。

<div class="speech-wrap sb-id-9 sbs-stn sbp-l sbis-cb cf">
  <div class="speech-person">
    <figure class="speech-icon"><img loading="lazy" class="speech-icon-image" src="https://xxxx.com/wp-content/uploads/2019/02/man.png" alt="" data-ll-status="loaded"></figure>
  </div>
  <div class="speech-balloon">
    <p>吹き出しの内容</p>
  </div>
</div>

これは吹き出しブロックで画像を参照するときにDBの画像IDを見ていないので、classが追加されないためです。

WordPressの仕組みでwidth/heightを追加するならwp-image-{画像ID} classを追加することになります。

そうでない場合は、widthとheightを自分で追加することになります。

カスタマイズコード

WordPressの仕組みと同じようにフックを使ってimgタグのwidth/heightを追加するカスタマイズを行います。

考え方はシンプルで、wp-image-{画像ID}の代わりに、speech-icon-imageを検索して、widthとheightは決め打ちで100にしているだけです。

add_filter( 'the_content', '_image_dimensioning_filter_content_tags' );
add_filter( 'the_excerpt', '_image_dimensioning_filter_content_tags' );
add_filter( 'the_category_content', '_image_dimensioning_filter_content_tags' );
add_filter( 'the_category_tag_content', '_image_dimensioning_filter_content_tags' );
//add_filter( 'widget_text_content', '_image_dimensioning_filter_content_tags' );

/**
 * Filters specific tags in post content and modifies their markup.
 *
 * @param string $content The HTML content to be filtered.
 * @param string $context Optional. Additional context to pass to the filters. Defaults to `current_filter()` when not set.
 * @return string Converted content with images modified.
 */
function _image_dimensioning_filter_content_tags( $content, $context = null ) {
	if ( null === $context ) {
		$context = current_filter();
	}

	if ( false === strpos( $content, '<img' ) ) {
		return $content;
	}

	if ( ! preg_match_all( '/<img\s[^>]+>/', $content, $matches ) ) {
		return $content;
	}

	$images = array();

	foreach ( $matches[0] as $image ) {
		if ( preg_match( '/speech-icon-image/i', $image) ) {
				$images[ $image ] = 1;
				continue;
		}

		$images[ $image ] = 0;
	}

	foreach ( $images as $image => $attachment_id ) {
		if ( $attachment_id ) {
			$size = array();
			$filtered_image = $image;

			if ( false === strpos( $filtered_image, ' width=' ) && false === strpos( $filtered_image, ' height=' ) ) {

				if ( preg_match( '/src\s*=\s*[\"|\'].*?-([0-9]{2,4})x([0-9]{2,4})\.(jpe?g|png|gif)[\"|\']/i', $image, $s ) ) {
					$size = array( $s[1], $s[2] );
				} else {
						$size = array( 100, 100 );
				}

				if ( $size ) {
					$filtered_image = str_replace( '<img', '<img width="' . $size[0] . '" height="' . $size[1] . '"', $filtered_image );
					$content = str_replace( $image, $filtered_image, $content );
				}
			}
		}
	}

	return $content;
}

width:100%が指定してある場合、width/heightはアスペクト比があっているのであれば重要ではありませんので、100じゃなくても何でも大丈夫です。

まとめ

Cocoon公式サイトでは吹き出しブロックはLazyload対象外になっていて今回の様なwidth/heightの問題は出ていません。Lazyload対象にしたい人は、width/heightは必須なのでご自分で追加しましょう、というカスタマイズでした。

タイトルとURLをコピーしました