rcmdnk's blog
Last update

20141126_mobilefriendly_200_200

先日までこのブログでは右側のサイドバーを常に残すような設定にしてましたが、 スマホで見ると結構邪魔くさい感じになってました。 まあ、内容上あまりスマホから見るものでもないかもしれませんが、 Googleの Mobile-Friendly Test なるものを見つけて試したらダメだと言われたので せっかくなのでこれに合格するよう設定変更してみました。

Sponsored Links

Octopressでのレスポンシブな設定

そもそもOctopressでのデフォルトclassicテーマではレスポンシブな設定になっています。 横幅が短くなるとサイドバーが下に行ったり、 サイドバーにボタンが付いていて大きな画面でも下に持って行けたり。

なんとなく、表示が変わるのが嫌だな、と思ったりして、 これをわざわざ変更して残すようにしていました。

Octopressでサイドバーを残そうとしてハマった所

ですが、心変わりでやっぱりそうなってた方が楽しいな、ということで classicなテーマを参考に同じような動きを再現してみます。

Octograyの中での設定

classicを参考にしながら再導入した部分が殆どですが、いくつか 苦労したところや変更点等。

残すか残さないかの設定

サイドバーを常に残す以前の状態もとっておきたかったので、 sass/custom/_layout.scssの中で$sidebar-remainという値を設定し、 これがtrueなら常に残す、falseならレスポンシブなものにするようにしました。

以降で

@if $sidebar-remain == true {
...
} @else {
...
}

みたいな設定が出来る様になります。

幅などのデフォルト値の設定

上の様に@if ...で幅を設定するにあたって、これらの中で

$sidebar-width-medium: 300px !default;

みたいにして、 一旦if文を終えてから後でこれらの値を使おうとすると、

Undefined variable: $sidebar-width-medium:

と怒られてしまいます。

当然と言えば当然なんですが、先にこの変数を宣言して@if文の中で値を設定する必要 があります。

1
2
3
4
5
6
$sidebar-width-medium: 0px;
@if $sidebar-remain == true {
  $sidebar-width-medium: 300px;
} @else {
  $sidebar-width-medium: 400px;
}

みたいにします。ここで!defaultを使うことが出来ないのが悩み。 最初の宣言のところでは使えますが、その値は意味なし。 下の実際に設定している所で使いたいわけですが、 先に宣言してしまってるので、!defaultを使うと上書きできずに 宣言の時の値になってしまいます。

仕方が無いのでこれらを直接変更する値として、 sass/base/_layout.scssからsass/custom/_layout.scssに 移しています。

片方だけを固定にしてしまって良いのなら、

1
2
3
4
$sidebar-width-medium: 400px !default;
@if $sidebar-remain == true {
  $sidebar-width-medium: 300px;
}

みたいにする方が正しいのかな?とも。

collapse-sidebar

sass/base/_layout.scssには@mixin collapse-sidebaが設定されています。

classicテーマの場合

sass/base/_layout.scss
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@mixin collapse-sidebar {
  float: none;
  width: auto;
  clear: left;
  margin: 0;
  padding: 0 $pad-medium 1px;
  background-color: lighten($sidebar-bg, 2);
  border-top: 1px solid lighten($sidebar-border, 4);
  section {
    &.odd, &.even { float: left; width: 48%; }
    &.odd { margin-left: 0; }
    &.even { margin-left: 4%; }
  }
  &.thirds section {
    width: 30%;
    margin-left: 5%;
    &.first {
      margin-left: 0;
      clear: both;
    }
  }
}

こんな感じになっています。

source/javascripts/octopress.jsの中で、addSidebarTogglerという関数があって、 この中でサイドバーのセクションに一つ置きにoddevenクラスを与え、 更に、三つ置きに、firstというクラスを与えています。

また、サイドバーをボタンで閉じた時にはcollapse-sidebarというクラスを bodyに追加しています。

source/javascripts/octopress.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function addSidebarToggler() {
  if(!$('body').hasClass('sidebar-footer')) {
    $('#content').append('<span class="toggle-sidebar"></span>');
    $('.toggle-sidebar').bind('click', function(e) {
      e.preventDefault();
      $('body').toggleClass('collapse-sidebar');
    });
  }
  var sections = $('aside.sidebar > section');
  if (sections.length > 1) {
    sections.each(function(index, section){
      if ((sections.length >= 3) && index % 3 === 0) {
        $(section).addClass("first");
      }
      var count = ((index +1) % 2) ? "odd" : "even";
      $(section).addClass(count);
    });
  }
  if (sections.length >= 3){ $('aside.sidebar').addClass('thirds'); }
}

上のcollapse-sidebarのmixinは、

@media only screen and (min-width: 750px) {
  aside.sidebar{ @include collapse-sidebar; }
}

な感じで読み込まれる様になっているので、横幅が長い時かつ ボタンで閉じた時に上のクラスの内容が適用されます。

ここで、3つ以上ある場合、750px程度の大きさでもcollapseした時、 それぞれの幅が全体の1/3の幅にされてしまいます。 これがちょっと嫌なので(それぞれ356px程度に設定しているので)、 &.thirds section {の部分は除いて Octograyに追加しました。

これで、ある程度幅があるときは、ボタンを押して下にやった場合に 2列組になり、幅が短くなって下に降りてきた時には1列になります。

また、sectionevenoddの設定がevenの時だけ左に4%のマージンを取るように なってましたが、 縦が短いものと長いものが混同してると、 2つ連続で縦に入ってevenoddの左右がずれることもあるので、

sass/base/_layout.scss
1
2
3
4
5
section {
  &.odd, &.even { float: left; width: 48%; }
  &.odd { margin-left: 2%; }
  &.even { margin-left: 2%; }
}

な感じで両方左に2%のマージンに変更しました。 (この時点でevenoddも同じなのでわざわざ分けなくても良い状態ですが、 あとで比べるのになるべくclassicに近いほうが便利なので残しておきます。 JavaScriptの関数のところとともに後で統一するかもしれませんが。)

後はbackground-color: lighten($sidebar-bg, 2); を消してバックグラウンドを同じ色に残したり等好みで。

後、色関係ではサイドバーとの間の線を以前は消してましたが、 下に書くボタンを配置したりする関係上、 合ったほうがいい感じなので区切り線を出すようにしました。

ボタンが現れない

画面が広い時に、サイドバーを閉じたり広げたりするボタンは sass/partials/sidebar/_base.scss.toggle-sidebarで定義されていて、 このクラスは上のaddSidebarTogglerで加えられてる事が分かります。

空け閉じのボタンは

content: "\00BB";

と定義されていて>>みたいな記号です。

button

これが最初表れなくて困ってましたが、悪さをしていたのは footnote-inline プラグインの中の source/javascripts/footnote.jsの中で、

jQuery.noConflict();

を使っているところでした。

これはjQueryで$()の関数定義が他のライブラリとコンフリクトを避けるため、 これを使用不可にするものですが(もしくは上の関数の返り値が代替関数として使用可能)、 source/javascripts/octopress.jsの中で$()をjQueryとして使ってるのと、 他のライブラリを使用してコンフリクトするような状況には今のところなっていないので、 この部分をfootnote-inline側でコメントアウトして使う様にしました。

jQueryと他のライブラリのコンフリクトを避ける方法

scroll fixをやめた

以前は jquery.ex-flex-fixed にあるJavaScriptを使って、サイドバーの下2個ほどをスクロールと同時に着いて来る 様な状態にしていましたが、これが上手くはめられなかったので辞めました。

まず、これを使うために、plugins/include_array.rbのなかで、 着いて行かせたい個数だけscroll-fixedというクラスを持つdiv要素で囲う様にしていました 1

これによって、上のaddSidebarTogglerと言う関数の中で 与えているevenoddfirstが正しく与えられていませんでした。

これを回避するため、 それらのクラスを与える所で、もう一段階深くに行ったsectionも調べて evenとかを与える様にしました。

source/javascripts/octopress.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
  var sections = $('aside.sidebar > section');
  var sl = sections.length;
  if (sl > 1) {
    sections.each(function(index, section){
      if ((sl >= 3) && index % 3 === 0) {
        $(section).addClass("first");
      }
      var count = ((index +1) % 2) ? "odd" : "even";
      $(section).addClass(count);
    });
  }
  var sectionsSF = $('aside.sidebar > div > section');
  var slSF = sectionsSF.length;
  if (slSF > 1) {
    sectionsSF.each(function(index, sectionSF){
      if ((sl + slSF >= 3) && sl + index % 3 === 0) {
        $(sectionSF).addClass("first");
      }
      var count = ((sl + index +1) % 2) ? "odd" : "even";
      $(sectionSF).addClass(count);
    });
  }
  if (sl + slSF >= 3){ $('aside.sidebar').addClass('thirds'); }

もしくは、他のdiv要素とかで囲う可能性もあり、かつ、 sectionの子section、見たいのは無い、と言う状態なら、 単に最初の所で、

var sections = $('aside.sidebar section');

とするだけでも出来ます。

ここまでは良かったものの、 着いて来る様にするためにscroll-fixedを持つ要素に与えている関数のON/OFFが 上手く出来ずに断念。 ボタンを押して下に追いやった時にまだ有効で、他のSectionにかぶるような状態に なってしまいました。

やってることは、source/javascrips/utils.jsの中で、

source/javascripts/utils.js
1
2
3
4
5
6
7
8
9
10
jQuery(function($){
  if(!$('body').hasClass('collapse-sidebar')) {
    if($('.scroll-fixed').length > 0){
      $('.scroll-fixed').exFlexFixed({
        watchPosition: true,
        container : '#content'
      });
    }
  }
});

として、collapse-sidebarが無いとき(サイドバーがボタンで下に行って無い時)、 scroll-fixedがあればそれにexFlexFixed関数を加える、ということ。

これを、上のaddsidebartogglerの中のtoggle-sidebarボタンの所で

source/javascripts/octopress.js
1
2
3
4
5
6
7
8
9
10
11
12
$('.toggle-sidebar').bind('click', function(e) {
  e.preventDefault();
  $('body').toggleClass('collapse-sidebar');
  if($('body').hasClass('collapse-sidebar')) {
    $('.scroll-fixed').unbind();
  }else{
    $('.scroll-fixed').exFlexFixed({
      watchPosition: true,
      container : '#content'
    }));
  }
});

みたいな雰囲気でON/OFFしたかったわけですが、 多分、この辺理解が間違ってるので上手く行きませんでした。

まあ、どうしても必要なものでもないし、無ければ無いで軽くなるわけで、 そのうちまた気が向いたら見てみよう、という状態で現在はOFFにしてあります。

下に来た時だけ表示する設定

サイドバーにあるときと下にある時で表示を少し変えたい場合があります。

例えば、サイドバーに在るときは表示したくないけど 下に来た時には表示したいものがある場合、 その要素を

<div class="only-footer">
...
</div>

で囲って(要素自体にクラスを与えられるならそれでもOK)、 まず、

sass/base/_layout.scss
1
2
3
4
5
6
7
8
9
10
aside.sidebar {
  ...
  .only-footer {
    font-family: $serif;
    color: $text-color;
    font-size: 1.25em;
    display: block;
  }
  ...
}

の様に、何もない場合にはdisplay: blockで表示する様にしておきます。

次に、表示が大きい場合には表示しないようdisplay: noneに設定。 さらに、.collapse-sidebarがある場合には display: blockで再び見せる様に設定。

sass/base/_layout.scss
1
2
3
4
5
6
7
8
9
10
11
12
13
@if $sidebar-remain == false {
@media only screen and (min-width: 750px) {
  aside.sidebar {
    .only-footer {
      display: none;
    }
    .collapse-sidebar & {
      .only-footer {
        display: block;
      }
    }
  }
}

これで、幅が短くてサイドバーが下に来ている場合と、 ボタンを押して下に持っていった場合には表示され、 右側に表示されてる状態では表示されないものが作れます。

逆にサイドに有るときだけ表示させたいものがあれば、上の displaynoneblockを入れ替えてあげれば出来ます。

結果

Awesome! This page is mobile-friendly.

ということでOKをもらうことが出来たみたいです。

mobilefriendly

Mobile-Friendly Test

多分、幅さえ収まる様になればOKを貰えるだけな感じもしますが、 これでスマホでも少しは見やすくなったかな、と。 (とは言ってもやっぱりコードとか横長のが多いのでPCのが断然見やすいわけですが。)

Sponsored Links
Sponsored Links

« シェルスクリプトを簡単にチェックできるShellCheck, Vimでも使える Bootstrap 3でモニタ用的なテンプレートを作ってみた »