work.log

元エンジニアの備忘録的ブログ

TwentyTwelveの微妙なメニューボタンをカスタマイズする

投稿:

WordPress のテーマ TwentyTwelve のメニューボタンをカスタマイズしたのでそのメモ書きです。

スマートフォン・タブレットで TwentyTwelve を表示すると下記のようなメニューボタンが表示されます。

TwentyTwelveのメニューボタン

twentytwelve-customize-019-01

ちょっと微妙と思ったのでこれを下記のようにカスタマイズしました。

カスタマイズしたTwentyTwelveのメニューボタン

twentytwelve-customize-019-02

今回のカスタマイズ方法を以下に記載していきます。

TwentyTwelveのメニューボタンを削除する

TwentyTwelve デフォルトのメニューボタンが不要になるのでまずはこれを取り除きます。

このメニューボタンは header.php の 43 行目 (デフォルトの場合) から呼び出されているのでこの行を削除します。

<nav id="site-navigation" class="main-navigation" role="navigation">
    <h3 class="menu-toggle"><?php _e( 'Menu', 'twentytwelve' ); ?></h3>
    <a class="assistive-text" href="#content" title="<?php esc_attr_e( 'Skip to content', 'twentytwelve' ); ?>"><    ?php _e( 'Skip to content', 'twentytwelve' ); ?></a>
    <?php wp_nav_menu( array( 'theme_location' => 'primary', 'menu_class' => 'nav-menu' ) ); ?>
</nav><!-- #site-navigation -->

WordPress 関数メモ

_e() はロケールに応じた翻訳テキストを表示する WordPress 関数です。
‘Menu’ → ‘メニュー’ のように自動翻訳されていますが、この機能が不要な場合は _e() 関数を取り除いていくのが良いと思います。

これで TwentyTwelve オリジナルのメニューボタン が削除できました。

TwentyTwelve のメニューボタンを入れ替える

削除したボタンの代わりに新しいメニューボタンを追加します。メニューボタンの入れ替えは下記の順で作業していきます。

  1. CSS スプライトを使用してメニューボタンを作成する。
  2. 親テーマの navigation.js を無効化する。
  3. スタイルシートを調整する。

CSS スプライトを使用したメニューボタンを作成する

header.php を修正してメニューボタンを追加します。

header.php はカスタマイズ後の状態なのでデフォルトにはないコードが含まれています。合わせて下記記事もご参照ください。

work.log – TwentyTwelveにCSSスプライトを使ったメニューを作成する

下記のように header.php の <hgroup> ? </hgroup> 間にメニュー用のリストを追加します。

<hgroup>
.
.
.
    <div id="hdr-menu" class="hdr-menu">
        <ul>
            <li><span class="menu-toggle"></span></li>
            <li><a class="sprite-author" href="<?php echo esc_url( home_url( '/' ) ); ?>" title="Profile" rel="author"></a></li>
            <li><a class="sprite-company" href="http://www.drive.ne.jp/" title="Drive Network" target="_blank"></a></li>
            <li><a class="sprite-mail" href="<?php echo esc_url( home_url( '/contact' ) ); ?>" title="Contact" rel="nofollow"></a></li>
            <li><a class="sprite-feed" href="<?php echo esc_url( home_url( '/feed' ) ); ?>" title="Feed" rel="nofollow"></a></li>
        </ul>
    </div>
.
.
.
</hgroup>

前回に作成したリストの 5 行目に id を追加し、7 行目にメニューボタン表示用のコードを加えたものとなります。

header.php の修正はこれで以上です。

TwentyTwelve navigation.js の入れ替え

今回はメニューボタンの装飾を変更するだけなので、ボタンアクションは変更しませんが、新しいメニューボタンにこのボタンアクションを継承させるために navigation.js に手を入れる必要があります。

手っ取り早い方法としては親テーマ内にある navigation.js を編集するのが一番ですが、子テーマを利用したカスタマイズが台無しになってしまいます。

なので、子テーマの functions.php で親テーマの navigation.js を無効化し、新たに子テーマ内から navigation.js を呼び出す事にしました。

ちなみに navigation.js は親テーマ functions.php 103 行目で読み込む設定がされています。

wp_enqueue_script( 'twentytwelve-navigation', get_template_directory_uri() . '/js/navigation.js', array(), '1.0', tru    e );

これを無効化するためのコードはこれです。

wp_deregister_script('twentytwelve-navigation');

上記に合わせ、子テーマで navigation.js を読み込む設定を下記のように行います。

if (!is_admin()) {
    function register_script(){
        wp_deregister_script('twentytwelve-navigation');
        wp_register_script('twentytwelve-navigation', get_stylesheet_directory_uri().'/js/navigation.js', array(), '1.0', true);
    }
    function add_script() {
        register_script();
        wp_enqueue_script('twentytwelve-navigation');
    }
    add_action('wp_print_scripts', 'add_script');
}

次に、親テーマディレクトリ内にある navigation.js を子テーマの js/ ディレクトリにコピーし下記を修正します。

/**
 * navigation.js
 *
 * Handles toggling the navigation menu for small screens.
 */
( function() {
        var nav = document.getElementById( 'site-navigation' ), button, menu;
        if ( ! nav )
                return;
        button = nav.getElementsByTagName( 'h3' )[0];
        menu   = nav.getElementsByTagName( 'ul' )[0];
.
.
.

修正後はこのようになります。

/**
 * navigation.js
 *
 * Handles toggling the navigation menu for small screens.
 */
( function() {
        var nav = document.getElementById( 'site-navigation' );
        var hdr = document.getElementById( 'hdr-menu' );
        var button, menu;
        if ( ! nav )
                return;
        button = hdr.getElementsByTagName( 'span' )[0];
        menu   = nav.getElementsByTagName( 'ul' )[0];

        if ( ! button )
                return;

        // Hide button if menu is missing or empty.
        if ( ! menu || ! menu.childNodes.length ) {
                button.style.display = 'none';
                return;
        }

        button.onclick = function() {
                if ( -1 == menu.className.indexOf( 'nav-menu' ) )
                        menu.className = 'nav-menu';

                if ( -1 != button.className.indexOf( 'toggled-on' ) ) {
                        button.className = button.className.replace( ' toggled-on', '' );
                        menu.className = menu.className.replace( ' toggled-on', '' );
                } else {
                        button.className += ' toggled-on';
                        menu.className += ' toggled-on';
                }
        };
} )();

これで navigation.js の入れ替えは完了です。

新しいメニューボタンをスタイルシートで調整する

最後に、スタイルシートの調整を行います。メニューボタンを入れ替えたので最初に下記クラス名を取り除いていきます。

  • menu-toggle
  • menu-toggle:hover
  • menu-toggle:active
  • menu-toggle.toggled-on

具体位的には、デフォルトのスタイルシート “238, 262, 273, 288, 289″ 行目が該当します。

削除完了後、下記コードを “@media screen and (max-width: 660px)” の範囲内に追記します。

※ デフォルトの状態は “@media screen and (max-width: 600px)” です。

@media screen and (max-width: 660px) {
.
.
.
    .site-header {
            padding: 24px 0 0;
            padding: 1.714285714rem 0 0;
    }
    .menu-toggle {
        width: 28px;
        height: 28px;
        background: url(images/sprite.png) -224px 0px no-repeat;
        display:block;
    }
    .menu-toggle {
        cursor: pointer;
    }
    .menu-toggle:active,
    .menu-toggle.toggled-on {
        width: 28px;
        height: 28px;
        background: url(images/sprite.png) -252px 0px no-repeat;
        display:block;
    }
.
.
.
}

site-header はタブレット・スマートフォン表示の際に margin-bottom が気になったのでついでに修正したのものです。

これでカスタマイズ作業は完了です。表示・動作を確認して不具合がないかをチェックします。

タブレット・スマートフォンでの表示例

twentytwelve-customize-019-02

タブレット・スマートフォンでボタンクリック後の表示例

twentytwelve-customize-019-03

うまくカスタマイズができました。

備考: タブレット・スマートフォンでの hover について

カスタマイズ中に、タブレット・スマートフォンで “hover” 時の動作について気付いた点がありましたので合わせて記載します。

CSS スプライトを使用したメニューアイコンを作成した時、”a” と “a:hover” で色を変えるという設定をしたのですが iPhone5 の実機で動作がおかしい事に気付きました。

タップ時に “a:hover” で色が変わるのは想定通りなのですが、ブラウザの “戻る” を押した場合にアイコンの色が戻らないという点です。

iPhone5 で確認した表示不具合

twentytwelve-customize-019-04

このようにが戻りません。

そもそも “hover” はマウスカーソルが触れた時の動作なので、タブレット・スマートフォンのタッチパネル操作では同じように考えてはいけないみたいです。

とりあえず、“@media screen and (max-width: 660px)” の範囲内に下記コードを追加して、659px 以下の場合だけですが色を統一しごまかしました。

@media screen and (max-width: 660px) {
.
.
.
    a.sprite-author { width: 28px; height: 28px; background: url(images/sprite.png) -28px 0px no-repeat; display:block; }
    a.sprite-company { width: 28px; height: 28px; background: url(images/sprite.png) -84px 0px no-repeat; display:block; }
    a.sprite-feed { width: 28px; height: 28px; background: url(images/sprite.png) -140px 0px no-repeat; display:block; }
    a.sprite-mail { width: 28px; height: 28px; background: url(images/sprite.png) -196px 0px no-repeat; display:block; }
.
.
.
}

解決策としては javascript で onTouchStart, onTouchEnd あたりを使えば良いみたいです。
ここでは詳しく説明しませんが参考 URL のみを載せて置きます。

onTouchStart, onTouchEnd 参考ページ

iPhone/Androidなどwebkitのa:hover後、もとの状態に戻らないバグを修正したい
スマートフォン(iPhone/Android)でhover (rollover) を実装したい

長くなりましたが TwentyTwelve のメニューボタンをカスタマイズする方法はこれで以上になります。