レスポンシブサイドバー – スライドでサイドバーを出現させる

簡素なレスポンシブサイドバー

で、そろそろこのあたりでいいかなということころまで簡素なレスポンシブサイドバーが出来上がってきましたのでここにメモっておきます。その前に前提ですが…

ベースはtwentyseventeen

自分はテンプレートテーマの根っこを常にtwentyseventeenに置いています。もう長年こればっかやってるのでカスタムも洗練されてきました。レスポンシブサイドバーもtwentyseventeenベースにおいていますので、これ以降の記述もそれを前提にしています。前提にしてもしなくてもあまり関係ない話ではありますが具体例としてtwentyseventeenを挙げますので。

jQuery

WordPressでは5.5〜5.7にかけてjQueryの最新バージョンへの置き換えを目論んでいるそうです。これまでバージョン違いや事前準備でぐだぐだでしたのでこれはいいことです。古いプラグインなどで互換性の問題が起きているようですが、これまでぐだぐだ感のせいでjQueryから逃げていた人(わしじゃわしじゃ)には安寧が訪れます。即ち、何も考えなくてもjQueryを使えることが約束されました。自動的に読み込んでくれているので準備については一切考えなくてもいいんです。

ということでjQueryを利用します。PHPとは別の書き方ですから高度と言えば高度ですが基本的な使用に留めますので恐れなくてもいいと己に言い聞かせます。

テンプレートでカスタムするところ

twentyseventeenベースでサイドバー#secondaryを丸ごとレスポンシブスライドメニューウインドウに押し込みます。

改造する部分はなるべく少ないのが理想。というか必須条件です。

header.php

header.phpが主な舞台です。headerですからすべてのページに影響を及ぼします。

header.phpの最後のほう、<div class=”site-content-contain”> からコンテントがはじまりますね。

<div class="site-content-contain">
    <div id="content" class="site-content">

こんな風にheader.phpは終わります。site-content-containとsite-content の、この固まりを閉じるのはfooter.phpです。

ここに二つの固まりを追加します。

<div class="site-content-contain">
    <div id="fixed_back"></div>
    <div id="content" class="site-content">
        <div class="open1"></div>

2行目 <div id=“fixed_back”></div>
4行目 <div class=“open1”></div>
このふたつを追加しました。どちらも即閉じの簡素なdivにしています。テンプレートでhtmlを改造するのは基本これだけです(他にも細々とあります。例えばfront-pageやpageに get_sidebar();を仕込みます)

1個めの <div id=“fixed_back”></div> は、レスポンシブメニューを出しているときの背景として使用します。

2個目の <div class=“open1”></div> はハンバーガーボタンです。.open1 などという変な名前じゃなく判りやすく賢そうなclass名を付けたほうが良いとちょっと思います。

仕組み

簡単に仕組みを述べますとこうです。

.open1と名付けた部分をクリックすると横からスライドしてサイドバーがせり出てきます。
そのウインドウの下に #fixed_back が出現して、こいつが縦横100%でその下のページコンテンツを暗く覆います。

jQueryの動きはこうです。

.open1をクリックすると次のことを発生させます。

・素の状態のとき
1  #secondaryにclass “open” を付与、ウインドウ端からせり出します
2 #fixed_backにclass “open” を付与
3 .open1 にもclass “open” を付与

・レスポンシブサイドバーが表示中のとき
1 #secondaryから class “open” を削除、ウインドウ端に消します
2 #fixed_backから class “open” を削除
3 .open1 から class “open” を削除
(※ open1のボタン以外に、#fixed_backクリックでも同様の措置)

#secondaryをせり出したし消したりさせる以外はclassを与えたり消したりしているだけです。

<script type="text/javascript">
    // スライド #secondary
    jQuery(function(){
        jQuery(".open1").click(function(){
            if(jQuery("#secondary").hasClass("opn")) {
                jQuery("#secondary").animate({right:"-80%"},300,"swing").removeClass("opn");
                // 幅を80%にしているのでこちら-80%で見えない位置に
                jQuery("#fixed_back").removeClass("opn");
                jQuery(".open1").removeClass("opn");
            }else {
                jQuery("#secondary").animate({right:0,},300,"swing").addClass("opn");
                jQuery("#fixed_back").addClass("opn");
                jQuery(".open1").addClass("opn");
            }
        });
    });
    // 背景もボタンに
    jQuery(function(){
        jQuery("#fixed_back").click(function(){
            jQuery("#secondary").animate({right:"-80%"}).removeClass("opn");
            jQuery("#fixed_back").removeClass("opn");
            jQuery(".open1").removeClass("opn");
        });
    });
</script>

 

CSS

CSSではclass”open”のあるなしで「画面を覆う」とか「消す」とか「アイコンを変更」などを制御します。ほぼCSSの仕事です。

CSSをそのままここに載せても雑に見えるだけなのでポイントだけ。

open1と名付けたハンバーガーボタンです。
/* ハンバーガーボタン */
.open1 {
    position: fixed;
    /* ボタンサイズや位置など */
    top:2px;
    right: 2px;
    width: 44px;
    height: 44px;
    /* admin-barより上に */
    z-index: 999999;
    cursor: pointer;
    /* 装飾 */
    background: #42576b;
    color: #fff;
    margin: 0 0 0 auto;
    text-align: center;
    padding: 8px;
    border-radius: 2px;
    border: 1px solid rgba(255, 255, 255, 0.2);
    box-sizing: border-box;
}
.open1:hover {
    /* hover てきとうに*/
}
.open1:active {
    /* active お好きに */
}

.open1:before {
    /* アイコンフォント お好きに */
    content: "\f228";
    font-family: dashicons;
    transition: all .3s;
}
.open1.open:before {
    /* open時のアイコンフォント */
    content: "\f335";
    transition: all .3s;
}

ハンバーガーボタンですからボタン的な装飾をしています。スマホでは右上に表示、大きさは44px角、スマホ用だから意味ないのですがhoverなども設定しています。activeもあります。スマホでもタップしたときに色が変わるのは確認できますし。

アイコンフォントはdashiconsで、これについてはは先の記事にも書いていますのでここでは割愛。
.open が加わるとアイコンフォントが変更されます。

ということで .open1 は普通のハンバーガーメニューです。

レスポンシブサイドバーを表示中の背景 fixed_back
#fixed_back.open{
    /* open時の背景を覆う背景 */
    position: fixed;
    top: 0;
    left: 0;
    display: block;
    width: 100%;
    height: 100%;
    /* 暗く覆う色、カーソル */
    background: rgba(121, 121, 121, 0.5);
    z-index: 4;
    cursor: pointer;
}

fuxed_back と名付けた半透明の背景です。サイドバー表示中(.open付与時)に、サイドバーと本体コンテンツの間で暗い膜を張ります。
このdivはopen時にだけ必要で、openがついていないときは表示を消していていいです。

尚、レスポンシブのこの仕組みには素人臭いところがあって、背景のコンテンツをスクロール出来てしまいます。暗い膜で覆いますがナンチャッテで覆ってるだけで操作できてしまうんですね。普通は操作出来ないように処置するものだと思います。その仕組みを付けようとも考えましたが難しそうで面倒そうなので放置しました。

肝心のサイドバー、secondary 部分

#secondary {
    /* 通常画面の外に放り出しておく */
    position: fixed;
    right: -80%;
    background: #fff;
    z-index: 9;
    height: 100vh;
    width: 80%;
    overflow-y: auto;
    overflow-x: hidden;
    padding: 0 1em 0 1em;
    top: 0;
    box-shadow: none;
}

#secondary.open {
    /* 移動はjQueryでやってるのでopen時影をつけるくらいの装飾 */
    box-shadow: 0px 0px 37px black;
}

@media screen and  (min-width: 48em) {
    .open1 {
        /* PCサイズでは非表示 */
        display: none
    }
    
    #secondary {
        /* PCサイズでは通常通り */
        display: block;
        background: #fff;
 		height: auto;
        padding: 1em 0 2em;
        top: inherit;
        box-shadow: none;
    }
}

肝心要のサイドバー、secondary部分です。肝心な部分ですが、htmlは触ってもいないし特別なクラスも付けてないし何にもしていません。CSSの変更をちょっぴりわずかに行うのみです。この最小限ぷりが自分で気に入ってる部分です。最小限ですが、がっつり変更しています。

スマホ表示時、position: fixed で位置を固定、縦スクロールを許可、ワイドは80%にしています。もちろん70%でも75%でも何でもいいです。ワイド80%にして位置を-80%、つまりギリギリ画面の外に放り出している状態ですね。放り出していて見えません。display:none で消しているわけではないです。

今これを書きながら「はて。場所を横にずらすだけで見えなく出来たっけ?どこか上の階層でoverflow-x:hiddenって書いてたっけ?」と己に疑問もわいておりますが未検証です。

openが付くと影を付けています。位置を0にすれば現れるのでCSSでそう書いてもいいかもしれませんが、style変更をjQueryに担当させています。styleとしてリアルタイムに変更させることが大事と思ったのかもしれません。jQueryのstyle変更を使ってみたかっただけなのかもしれません。

メディアクエリ(ここでは48em)ではPCサイズの設定をちゃんと書いてデフォルトの表示に戻しています。

こんな感じが基本かなと(何かが抜けていたらご免)

ということで、マイルール「弄るのは最小限」に基づいた簡素・簡潔・簡易・感動のレスポンシブサイドバーが出来上がりました。

留意点

簡単簡素はいいけれど、他にいくつか留意する点があります。

has-sidebar

twentyseventeenでは body class が page-two-column であったり has-sidebar がなかったりすることもありますので、ページでは page-one-column 、そしてすべてに has-sidebar があったほうがいいかもしれません。

さらに、テンプレートではすべてに <?php get_sidebar(); ?> を付け加えます。これは必須です。front-page にも固定ページもすべて get_sidebar() が必要です。でないとハンバーガーメニューはあるのに何も出てこない状態になります。

ページの1コラム 2コラムは「カスタマイザ」でできるかもしれません。has-sidebar は うまく自動で付かなければテンプレートで無理矢理付けてもいいです…

…と、ここまで書いてテストサイト調べてみたら、body class に has-sidebar がなくても上手く動いてますね。get_sidebar()さえあれば他は気にしなくていいかもしれません。なくても動くなら面倒いことは極力避けよう(突っ込んだ検証していなくてすいません)

ということで、最低限の改変で実現する「レスポンシブサイドバー」でした。いろいろ未検証なので、真っ新な子テーマで一度テストして何かあればこっそり追記したり記事を改竄したりしておきます(日本人の有権者の方には通じにくいかもしれませんが書き換えることを改竄と言います)

で、これにまだオマケ的な続きがあるわけですが、その続きはすでに書かれています。

ただサイドバーを置くだけでは何かが足りない。それはグローバルナビゲーション、いわゆるメニューですね、それを付け足します。

折りたたみが最も簡単 details と summary をjQueryに置き換えるメモ/3 のあらすじの後に続きました。