コンパクトな月間アーカイブメニューを作ってみる

Category : CSS, jQuery

よくブログのサイドバーやフッターなんかで見かける月間アーカイブメニューですが、ちょっとスペース取りすぎだと思っています。
そんなアーカイブメニューですが、素敵なデザインを見かけましたので、そのデザインを参考にして自分なりにコンパクトなアーカイブメニューを作ってみました。
参考にしたのは以下のサイトです。

どんなコードかまでは確認していませんが、こういう方法があったか、と思いました。
自分で作ってみたものは以下です。

Compact Archive w/ jQuery

デモファイルをダウンロード

HTML 部分は次の通り。
ちょっとマークアップがアレな感じでごめんなさい。

<div class="archives">
  <div class="year-select">
    <ol>
      <li><a href="#year2011">2011</a></li>
      ......
    </ol>
  </div>
  <div class="monthly-archives">
    <ol id="year2011">
      <li><a href="#">Jan</a></li>
      <li><a href="#">Feb</a></li>
      <li><a href="#">Mar</a></li>
      <li><a href="#">Apr</a></li>
      <li><a href="#">May</a></li>
      <li><span>Jun</span></li>
      <li><span>Jul</span></li>
      <li><span>Aug</span></li>
      <li><span>Sep</span></li>
      <li><span>Oct</span></li>
      <li><span>Nov</span></li>
      <li><span>Dec</span></li>
    </ol>
    ......
  </div>
</div>

次は CSS を。
関係ない部分とベンダープレフィックス付きのプロパティは省略しています。

.archives {
  margin   : 0 auto 10px;
  width    : 940px;
  font-size: 16px;
}

.archives ol {
  list-style: none;
}

/* clearfix */
.archives:after {
  display: block;
  clear  : both;
  content: "";
}

.archives a,
.archives span {
  display        : block;
  line-height    : 40px;
  text-align     : center;
  text-decoration: none;
}

.year-select,
.monthly-archives li {
  border-radius: 0 0 10px 10px;
}

.year-select ol,
.monthly-archives a,
.monthly-archives span {
  border-radius: 0 0 8px 8px;
}

.year-select,
.monthly-archives li {
  box-shadow: 0 0 5px rgba(0, 0, 0, 0.5);
}

.year-select {
  float     : left;
  border    : 3px solid #fff;
  border-top: 0;
  width     : 94px;
}

.year-select ol,
.monthly-archives a {
  background-image: linear-gradient(
                      top,
                      rgba(255, 255, 255, 0.2),
                      rgba(255, 255, 255, 0)
                    );
}

.year-select ol {
  background-color: #d33682;
  text-shadow     : 0 0 0 transparent, /* Windows Chrome 対策 */
                    -1px -1px 0 rgba(0, 0, 0, 0.2);
}

.year-select a {
  color: rgba(255, 255, 255, 0.5);
}

.year-select ol .active a,
.year-select ol a:hover {
  color: #fff;
}

.monthly-archives {
  float: left;
}

.monthly-archives ol {
  position: absolute;
}

.monthly-archives li {
  float      : left;
  margin-left: 10px;
  border     : 3px solid #fff;
  border-top : 0;
  width      : 54px;
}

.monthly-archives a {
  color           : #fff;
  background-color: #268bd2;
  text-shadow     : 0 0 0 transparent,
                    -1px -1px 0 rgba(0, 0, 0, 0.2);
  transition      : all 0.2s;
}

.monthly-archives a:hover {
  padding-top     : 10px;
  background-color: #cb4b16;
}

.monthly-archives span {
  color           : #bbb;
  background-color: #f0f0f0;
  background-image: linear-gradient(
                      top,
                      transparent,
                      rgba(0, 0, 0, 0.08)
                    );
  text-shadow     : 0 0 0 transparent,
                    1px 1px 0 #fff;
}

最後に jQuery で色々します。
今回「jQuery でやらなくてもいいんじゃね」と思ったアニメーションは CSS でやっています。

jQuery(function ($) {

  var $years      = $('.year-select').children(),
      $yearLists  = $years.children('li'),
      $selectYear = $yearLists.children('a'),
      $months     = $('.monthly-archives').children();

  // 年リストのアイテム1つ分と全部表示しているときの高さ
  var singleHeight = $yearLists.height(),
      totalHeight  = singleHeight * $yearLists.length;

  // 年リストの最初に active というクラス名をつける
  $yearLists.eq(0).addClass('active');

  // 年リストと年別アーカイブの最初以外を隠す
  $yearLists.filter(':gt(0)').hide();
  $months.filter(':gt(0)').hide();

  // 年リストの高さをアイテム1つ分に
  $years.css('height', singleHeight);

  // 年リストにホバーしたときの動作
  $years.hover(
    function () {
      // 年リストを全表示
      $yearLists.show();
      // 年リストの高さを全表示分まで変更
      $(this).stop().animate({'height': totalHeight});
    },
    function () {
      // 年リストで active というクラスがないものは非表示に
      $yearLists.filter(':not(.active)').hide();
      // 年リストの高さをアイテム1つ分に変更
      $(this).stop().animate({'height': singleHeight});
    }
  );

  // 年リストのアイテムをクリックしたときの動作
  $selectYear.click(function (e) {

    // リンクを無効にする
    e.preventDefault();

    // 表示中のアイテムだったら何もしない
    if($(this).parent().hasClass('active')) return;

    // クリックした a の親 li のインデックス番号
    var target = $(this).parent().index();

    // active というクラス名を全体から削除
    $yearLists.removeClass('active');
    // クリックした a の親 li に active というクラス名をつける
    $(this).parent().addClass('active');

    // 年別アーカイブの表示しいている部分をフェードアウト
    $months.filter(':not(:hidden)').fadeOut();
    // 年リストと同じインデックス番号の年別アーカイブを表示
    $months.eq(target).fadeIn();
  });

});

これでとりあえずは動くと思います。
CSS transition 非対応ブラウザでも同じアニメーション使いたい場合は自分で追加してください。
あと、古い IE 対策はしていませんので、その辺も対応する場合は CSS 書き直してください。

WordPress に対応させる場合には Compact Archives を改造して作るといいんじゃないでしょうか。
改造といっても出力する HTML を書き換えるだけですので、このプラグインの場合はそんなに難しくないと思います。

Leave a Reply