CSS 変数に未対応の Google クローラに PHP で対策

GooglebotにCSS変数を適用する方法

Akira

福岡在住ウェブデザイナー。Web サイト制作に役立つ情報を「見やすさ」と「使いやすさ」にこだわり紹介しています。

WordPress で運営している当サイトでは、 CSS 変数を使っています。

ただ、 Google クローラが CSS 変数に対応していないため、 CSS を PHP で置き換える必要がありました。

CSS 変数のメリットはほぼ維持しながらも、 Google クローラに対応する方法のご紹介です。

CSS 変数とは?

CSS 変数とは、指定した CSS の値を再利用するための仕組みです。

CSS 変数は、このように書きます。

:root {
  --main-color: red;
}

.example {
  color: var(--main-color);
}

.sample {
  background: var(--main-color);
}

まず、 :root などに対し、変数を定義します。

あとは、変数を使いたいところで使用します。上記の例では、 .example のフォントカラー、 .sample の背景色が red になります。

redpink に変更する場合には、 --main-color に指定した red の 1 ヶ所のみを変更すれば OK 。 .example のフォントカラーも .sample の背景色も、自動的に pink に変わります。

ものすごく開発効率もメンテナンス効率も上がるのが、 CSS 変数です。

CSS 変数の注意点

ただ、現時点の CSS 変数には、 2 つのデメリットがあります。

  • IE が未対応
  • Google クローラまで未対応

IE は、まだ分かります。サイトによっては、無視できます。

ただ、 Google クローラが対応していないのは、致命的にまずい。

Google のメインのクローラである Googlebot は、現在 Chrome 41 の性能を持っています。

ただ、 CSS 変数に対応している Chrome のバージョンは、 49 以降です。

つまり、 Google クローラは CSS 変数に未対応。モバイルフレンドリーテストや Test My Site 、 PageSpeed Insights などを使うと、ものの見事に CSS 変数が反映されません。

そこで、当サイトでは、 CSS 変数を PHP で置き換えました。

str_replace() での置き換え

CSS 変数を Google クローラに対応するための手順は、次のとおりです。

  1. style.css ファイルに書いている CSS を取得する
  2. 取得した CSS の中にある CSS 変数を str_replace() で置き換える
  3. 置き換えた CSS の保存先となる style-bot.css ファイルを自動的に作成
  4. 置き換えた CSS を style-bot.css ファイルに自動的に保存
  5. style-bot.css ファイルを読み込みサイトに適用

これを実現するために参考にしたのが、「WordPressでCSSを自動で圧縮して用いる」

function.php に、下記のコードを追加しました(親テーマの使用を想定しています)。

<?php

// WP_Filesystemの使用
require_once( ABSPATH . 'wp-admin/includes/file.php' );

add_action( 'get_header', function() {

    if( WP_Filesystem() ) {
        global $wp_filesystem;
        
        $css_file          = get_template_directory() . '/style.css';
        $css_bot_file      = get_template_directory() . '/style-bot.css';
        $css               = '';
        $css_file_date     = filemtime( $css_file );
        $css_bot_file_date = '';
        $css_bot_file_date = filemtime( $css_bot_file );
        $css_flag          = false;
        
        // style-bot.cssがなければ作成
        if( file_exists( $css_bot_file ) === false ) {
            $wp_filesystem->touch( $css_bot_file );
            $css_flag = true;
        }
        
        // style.cssの更新時刻がstyle-bot.cssの更新時刻より新しいかを確認
        if( $css_bot_file_date < $css_file_date ) {
            $css_flag = true;
        }
        
        // 置き換え処理
        if( $css_flag ) {
            // style.cssの中身を取得
            $css = $wp_filesystem->get_contents( $css_file );
            
            // CSS変数を通常のCSSの値に変更
            $search = array(  
                'var(--site-color)'      => '#161825',
                'var(--accent-color)'    => '#ff4081',
                'var(--main-background)' => 'linear-gradient(to right top, #161825, #212031, #2f273c, #3e2e47, #4e3551)',
            );
            // CSSの置き換え
            $css = str_replace( array_keys( $search ), array_values( $search ), $css );
            
            // style-bot.cssに保存
            $wp_filesystem->put_contents( $css_bot_file, $css );
        }
    }
});

WP_FileSystem の使い方は、「WordPressテーマなどでは、PHP関数で直接ファイル操作をするのは非推奨、WP_FileSystemを使って操作するのが望ましいらしい」をご参考ください。

35 行目から 37 行目で、 CSS 変数を通常の CSS の値に置き換えています。

今後、定義した CSS 変数を変更する場合には、スタイルシートと function.php の 2 ヶ所を変更します。 1 つ手間は増えますが、 CSS 変数のメリットは最低限は守れるはずです。

あとは自動的に作成される style-bot.css を読み込めば完了です。

<link rel="stylesheet" href="<?php echo get_template_directory_uri(); ?>/style-bot.css">

WordPress 流で読み込む場合は、下記のコードを function.php に追加します(親テーマの使用を想定しています)。

add_action( 'wp_enqueue_scripts', function() {
    wp_enqueue_style( 'style-bot', get_template_directory_uri() . '/style-bot.css' );
});

サイト運営者に対しては置き換え前の CSS を適用

PHP で置き換えた style-bot.css を読み込むと、 Google クローラだけではなくサイト運営者にも置き換え後の CSS が適用されます。

デベロッパーツールで CSS 変数を確認できないため、ちょっと不便です。

そこで、私自身(ログインユーザー)に対しては、置き換え前の CSS を適用しています。

<?php if( is_user_logged_in() === true ) : ?>
<link rel="stylesheet" href="<?php echo get_template_directory_uri(); ?>/style.css">
<?php else : ?>
<link rel="stylesheet" href="<?php echo get_template_directory_uri(); ?>/style-bot.css">
<?php endif; ?>

WordPress 流で読み込むなら、下記のコードを function.php に追加します。

add_action( 'wp_enqueue_scripts', function() {
    if( is_user_logged_in() === true ) {
        wp_enqueue_style( 'style-css', get_template_directory_uri() . '/style.css' );
    } else {
        wp_enqueue_style( 'style-bot', get_template_directory_uri() . '/style-bot.css' );
    }
});

条件分岐には、 WordPressの is_user_logged_in() を使っています。

上手くいかなかったユーザーエージェントでの条件分岐

最初は is_user_logged_in() ではなく、ユーザーエージェントで条件分岐をしていました。

ただ、 Google Search Console の「 Fetch as Google 」で、不具合が出てしまいました。

やったことは、下記のコードを function.php に追加し、ユーザーエージェントの判別関数を定義。

function is_bot() {
    $bot = array(
        'Googlebot',           // Google
        'Page Speed Insights', // Google
        'Y!J',                 // Yahoo!
        'Slurp',               // Yahoo!
        'msnbot',              // Microsoft
        'bingbot',             // Microsoft
        'Hatena',              // Hatena
        'Yeti/',               // Never
        'NaverBot',            // Never
        'ichiro',              // goo      
    );
    
    $ua = isset( $_SERVER['HTTP_USER_AGENT'] ) ? $_SERVER['HTTP_USER_AGENT'] : '';
	
    foreach( $bot as $value ) {
		if( stripos( $ua, $value ) !== false ) {
		    return true;
		}
	}
	return false;
}

定義した関数を使い、スタイルシートを読み込み。

<?php if( is_bot() === false ) : ?>
<link rel="stylesheet" href="<?php echo get_template_directory_uri(); ?>/style.css">
<?php else : ?>
<link rel="stylesheet" href="<?php echo get_template_directory_uri(); ?>/style-bot.css">
<?php endif; ?>

これで最初は上手くいったと思っていました。しかし、 Fetch as Google の「レンダリング」が、下の画像の状態になってしまいました。

ユーザーエージェントで条件分岐した際のFetch as Googleの不具合

「 Googlebot ではこのページを以下のように認識しました。」の方は、上手くいっています。きちんと Googlebot を判別し、置き換え後の CSS が適用されています。

ただ、「貴サイトへの訪問者にはこのページが以下のように表示されます。」の方は、スタイルが崩れました。 Googlebot ではない、かつバージョン 49 未満の Chrome を使っているということでしょうか。

実害はないかもしれませんが、 ユーザーエージェントでの条件分岐は止めました。


モダンブラウザでは問題なく使える CSS 変数。

2017 年に新デザインとなったデスクトップ版 YouTube は、大々的に CSS 変数を使っています。

しかし、少なくとも Googlebot がバージョンアップされるまでは、何かしらの対策が必要です。

今回ご紹介した方法は、 Googlebot がバージョンアップされるまでの対策として使えます。また、 IE への対策としても有効です。

対策が不要になった時は、 function.php に追加したコードを削除し、スタイルシートの読み込みを元に戻すだけ。

簡単に元通りになるのも、今回の方法のメリットだと思っています。