Tumblrテーマ「effector」をブログっぽくカスタマイズする。

すっきりした見た目が好きでTumblrテーマのApolloを使っていたのだが、サイドバーがないのがどうしても物足りなかった(「そもそもそういうテーマじゃねえよ」? 仰るとおり)のでテーマ替えし、全面的にサイトをいじることにした。

サイトに欲しかった要件

自分が欲しかった要件は次のような感じ。

  1. 記事+サイドバーの2カラム
  2. 記事は最新記事をメインページに表示し、その下に次以降の記事のサマリーを表示
  3. tumblrを使うが、あまりtumblr臭さは出したくない(投稿種別のアイコンとかは不要、リブログ/ライクボタンは小さくていい、ノートも表示しない)
  4. サイドバーに最新記事一覧
  5. サイドバーにカテゴリー別リンク
  6. 記事600〜800px
  7. サイドバー300px
  8. いわゆるレスポンシブデザイン
  9. 各種SNS、ソーシャルブックマークサービスへの共有機能
  10. スマホ表示の際はメニューバーを最上部に
  11. 記事下にGoogle Adsenseのレクタングル中×2を配置

カスタマイズ元として――「effector」テーマ

サイドバー含む2カラムでいろいろとテーマを探してみたのだが、完璧にこれでフィットというものが見つからない。
そこでカスタマイズしやすいと評判の(もう古いのかもしれんが)「effector」をベースに色々と弄ってみることにした。
cssなんてほとんど触ったこともないレベルからのスタートだったのと、tumblrのテーマカスタマイズで参考になるサイトが意外と少なかったため、かなりつまづいた。

後者は、敢えてtumblrでいわゆるブログっぽい外見にせんでもよかろうと思ってる人が多いということかもしれん。
が、素人だけどちょっと登録されてるテーマに手を加えてオリジナリティ出したいなあ、というニーズはそれなりにあるんじゃないかと思い、備忘録も兼ねて書いておくことにする。

カスタム内容一覧

「effector」の構造はまずどうなっている?

「effector」をインストールして「テーマの編集」>「htmlを編集」から中身を見てみるまでは普通にたどり着けるのだが、その先が詰まりやすいと思う。
Tumblrサイトをいじっていく上で見逃されやすい機能として、テーマアセットというものがある。
cssなんかを書いたテキストファイルをアップロードできる機能だ。

カスタマイズ___Tumblr

デフォルトの状態でも、4種類のアセットがテーマ内に含まれている。
つまり実際には、テーマ「effector」は

  • html(内部css含む)
  • 各種カスタマイズ項目(背景色、サイドバーの左右など。これはhtml内にカスタムできるよう記述されている)
  • テーマアセットファイル(CSSファイルなど)

という三重構造で構成されているということ(他のテーマも同様だろう)。
これを理解していないと、htmlをいくら読んでも定義されてない項目があったり、内容を変更しても意図通り反映されなかったりで非常に苦労する(した)。

effectorのhtml構造

「effector」のhtml構造はおおまかに次のようになっている。

  • head(ページ全体に関連する要素を置く)
    • title
    • meta(テーマオプションでのカスタマイズ用)
    • link(CSSファイルやjquery fancybox?等へのリンク)
    • css
  • body(本体。サイトの基本的な構造はここで決定)
    • header
      • inner
    • page
      • banner
      • content(投稿部分)
        • post(一投稿単位)
          • post-panel(記事囲みパネル。今回は削除した)
            • copy
              • body(記事本文)
      • sidebar(サイドバー)
        • blog-info
          • description(このブログについて)
          • search(検索バー機能)
          • side-box ruled top(各種ソーシャル系サービス関連)
      • footer(フッター)

htmlでは上位のclass要素などにに加えた記述は下位の要素にも適用される。上のhtml構造を念頭に置きつつ、どの範囲にどのような追加修正をかけたいかを考えるとよいかもしれない。

余白が多すぎるのをどうにかしたい(post-panel削除と横幅調整)

配置はわかりやすいんだがとにかく余白が多い気がするこのテーマ。スッキリしてこれはこれでいいけど、もう少し密度を上げたい、サイドバーや記事幅を広げたいと思った。

post-panel削除

このテーマ、デフォルトでは記事エリアがパネル型になってるんだが(要素post-panel)、記事間にボーダーラインあればええやろと思い、div:post-panelを削除してpostのbottomにボーダーライン入れた。これで十分。post-panelに関連する記述はすべて削除しても問題なく動く。

全体の横幅調整

「effector」では、記事部分の幅をテーマオプションで500px/600px/700pxから選択できるようになっている。サイドバーは180px固定。
これらのレイアウト設定はすべてアセットのCSSファイルに含まれている。
単純にpostやsidebarのwidthを増やすと、全体の幅に収まりきれなくなってsidebarがページ下部に回り込んでしまう。

ということでアセットのCSSをこのように変更した。

#page,.inner{width:760px}
.banner img{max-width:760px}
#content{width:500px}
#sidebar{float:left;width:180px;margin-bottom:80px}

 ↓
#page,.inner{max-width:980px}
.banner img{max-width:980px}
#content{max-width:600px;padding:0,20px,20px,0;margin-right:    50px;}
#sidebar{float:left;width:300px;margin-left:30px;margin-    bottom:80px}</code>

PCビューだと狙い通りのレイアウトとなったが、モバイルが完全に崩れてしまったので対応中。2015.12.07対応完了。

また、500px/600px/700pxから700pxだけ残して他の関連記述はすべて削除した。あとからテーマオプションで選択できる必要もないし、となればメンテナンス上邪魔になるだけなので。
一応700pxは残したが、この辺りも冗長になっていると思われるので、問題が出たら整理しようと思う。
「Effector」のデフォルトだとiPhoneのSafariでの上部バータップによる「最上部に戻る」も無効になっていたので、scroll関係の記述をすべて削除した。infinite scrollを使う予定がなければ削除してしまって問題ないはず。

新着記事一覧の追加

元ネタはここを参考にした。

ただしいくつか修正を入れている。

まず、そのままエフェクターのサイドバーにつっこんでもリストの先頭記号が表示されない。
これはcssで

liststyle:none

と指定されているため。これはnone→disc(黒丸)に変更すればよい。
ただし、リスト全体にこれを適用してしまうと、今度は通常の記事中のリストにも黒丸が二重に付加されてしまう。
また、単純にliststyleを変更するだけでは、先頭記号の黒丸がサイドバーの外に出てしまう。

サイドバーの中のリスト部分だけに調整を適用するためには、もとのJavascript部分を下のように修正し、sidebar内の要素”blog”にclassを追加する。

(html)
<script type="text/javascript">
function tumblr(resp) {
var posts = resp.posts;
  $('#blog .loading').replaceWith('<ul class=blog-c/>');

(中略)

<div id="blog" class="blog-c">
            <h2>RecentPost</h2>
            <span class="loading">Loading...</span>

そしてCSS(どこでもよい)に下記を追加。

ul.blog-c {
  list-style: disc;
  padding-left: 1.5em;
}

“blog-c"というのがサイドバーの部分のクラス名。
これでサイドバーの新着記事部分にだけ変更が適用される。

カテゴリー別リンクの追加(タグクラウド)

tumblrにはカテゴリーという概念がない。しかし記事にタグを設定することはできるので、これを擬似的にカテゴリーの代わりとして運用することとする。
実装は簡単で、このサイトで作ったコードをつっこめばOK。

リストマーカーが重複する問題の修正

「effector」は初期設定のままだと、「羅列リスト>順列リスト」というような入れ子構造のリストを記述した際、下の画像のように文頭のリストマーカーが重複してしまう。
カスタマイズ___Tumblr
原因は、「effector」元々設定されているアセットCSSでの、"div:copy"内のリストマーカーの記述にある。

.copy ol{list-style-type:decimal;margin-left:20px;list-style-position:outside}
.copy ol li,.copy ul li{padding:1px}
.copy ol ol,.copy ul ul{margin-bottom:-1px;padding:1px 0 0}
.copy ol ol li{list-style-type:lower-alpha}
.copy ol ol ol li{list-style-type:lower-roman}
.copy ul li{padding-left:20px}
.copy ul li:before{content:"25CF";font-weight:400;padding-right:10px;margin-left:-18px}
.copy ul ul li:before{content:"25CB"}
.copy ul ul ul li:before{content:"2014"}

マーカーについて、list-styleで記述しているところとbefore擬似要素で挿入しているところが混在しているため、重複が発生するわけだ。
なので、この部分を次のように修正した。

.copy li{list-style-type:disc;margin-left:20px;list-style-position:outside}
.copy ol li{list-style-type:decimal;margin-left:20px;list-style-position:outside}
.copy ol ol{margin-bottom:-1px;padding:1px 0 0}
.copy ol ol li{list-style-type:lower-alpha}
.copy ol ol ol li{list-style-type:lower-roman}
.copy ul ol{margin-bottom:-1px;padding:1px 0 0}
.copy ul ol li{list-style-type:decimal}
.copy ul ul{margin-bottom:-1px;padding:1px 0 0}
.copy ul ul li{list-style-type:circle}

すべてlist-styleでの記述にしてしまえば重複は発生しない。

記事下にGoogle Adsense広告を配置(レクタングル中×2)

当初は広告サイズを「レスポンシブ」にしていたが、レクタングル中×2の方が訪問者がクリックしてくれる率が高いらしいと聞いて変更した。
これが簡単そうに見えて意外と難しかった。最初は次のようにテーブルで単純に並べる方法を取ったのだが、

<table>
<tr>
<td>1個目のアドセンスタグ(左側)</td>
<td>2個目のアドセンスタグ(右側)</td>
</tr>
</table>

これだとスマホなどで見たときに2個目のアドセンス広告が画面の右側に飛び出してしまう。かといってfloatプロパティで2個目が1個目の下に回り込むようにすると見た目にも邪魔だし、Google Adsenseの規約上もスマホ画面で見たさいに2つ以上のアドセンス広告が入り込んでしまうような配置はアウトのようだ(いまいちはっきりしないが……)。

解決策としては、

  • PC、タブレットでは2つ横並びで表示
  • スマホでは一つだけ表示

とするのがよさそうだ。そのためには、デバイスの画面サイズに応じて2個目のアドセンス広告の表示/非表示を切り替えればよい。これはCSSのメディアクエリを設定することで可能である。サイト全体をレスポンシブデザインにするのと同じだ。

具体的にはhtml/css上で次のように設定すればよい。

  1. 記事下の位置に個別のclass名を指定したdivを2つ用意し、それぞれのdiv内にアドセンス広告のコードを配置する
  2. デバイスのスクリーン幅が600px以下(=レクタングル中×2)のとき、2個目のアドセンス広告が含まれるdivを非表示(none)にする

ということで、このブログではそれぞれ次のようなコードになっている。
クラス名「l」「r」のdivを用意し、スクリーン幅が480px以下のとき「r」を非表示にするよう指定している。

(html側)
<div class="l">
 <script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js">
 </script>
  <!-- 300*250#33a6b8 -->
  <ins class="adsbygoogle"
       style="display:inline-block;width:300px;height:250px"
       data-ad-client="ca-pub-XXXXXXXX"
       data-ad-slot="XXXXXX">
  </ins>
 <script>
  (adsbygoogle = window.adsbygoogle || []).push({});
 </script>
</div>

<div class="r">
 <script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js">
 </script>
   <!-- 300*250#33a6b8-2 -->
   <ins class="adsbygoogle"
       style="display:inline-block;width:300px;height:250px"
       data-ad-client="ca-pub-XXXXXXXX"
       data-ad-slot="XXXXXX"></ins>
  <script>
   (adsbygoogle = window.adsbygoogle || []).push({});
  </script>
</div>

(css側)
@media screen and (max-device-width: 480px) 
{
.r{display: none}
}

ここではスクリーンサイズの切り替え値を480pxで指定しているが、それぞれのサイトにあわせて300〜600pxの範囲で変更すればよいはずだ。(が、あれ、600px以下と厳密に指定したほうがよいのか?)

メディアクエリ(Media Queries)の単位をpxからemに変更

(css側)
@media screen and (max-device-width: 30em) 
{
.r{display: none}
}

上記のようにメディアクエリの他にをem(=16px)へと変更した。
変更の理由だが、メディアクエリに使用できるpx、em、remの3単位のうち、pxとremはブラウザにより意図しない挙動が発生しうるため。
詳細は下記リンク先参照。
[CSS]Media Queriesで使う単位はpx, Em, Remのどれが適しているか検証 -px指定は注意が必要 | コリス

Autopagerize対応

上でも書いたが、「Effector」のデフォルトだとiPhoneのSafariでの上部バータップによる「最上部に戻る」が無効になっていたため、scroll関係の記述をすべて削除した。
iPhoneにはこれで対応できたのだが、今度はブラウザ側のAutopagerizeへの対応で不具合が出た。次頁をサイドバーの中に読み込んでしまう……。
ということで次のようにして対応させた。

(html側)
{block:Posts}
(中略){/block:Posts}

(中略)
<a href="{PreviousPage}">
(中略)
<a href="{NextPage}"> 

これを

<span class="autopagerize_page_element">{block:Posts}
(中略){/block:Posts}</span>

(中略)
<a href="{PreviousPage}"  rel="prev">
(中略)
<a href="{NextPage}"  rel="next"> 

こうすることで、記事部分をAutopagerizeに判別させることができる。


追記
(2016.01.07)記事の項目順を変更
(2016.01.07)「リストマーカーが重複する問題の修正」の項を追加
(2016.02.29)「記事下にGoogle Adsense広告を配置(レクタングル中×2)」の項を追加
(2016.03.29)「メディアクエリ(Media Queries)の単位をpxからemに変更」の項を追加
(2016.03.31)「Autopagerize対応」の項を追加