Colorboxをカスタマイズして両サイドに表示されるアイコンをコンテンツの外側に配置する

Colorboxをカスタマイズして両サイドに表示されるアイコンをコンテンツの外側に配置する

デフォルトのページネーションの配置ではNG

ある案件で、今まではサムネイル画像と拡大画像が1対1の関係で拡大画像をモーダルウインドウで見せていたのだが、コンテンツの更新によりサムネイル画像1に対して拡大画像複数をスライダー方式で見せたいという事になった。

となると、これまで使っていたモーダルウインドウ系プラグインにこだわって「モーダルウインドウ系+スライダー(スライドショー、カルーセル)系プラグイン」の組み合わせでいくよりも、「Lightbox系のプラグイン」を使った方が早いということで、「Colorbox」を久々に扱うことに。

この記事はその時のカスタマイズについて備忘録を兼ねたもので、このカスタマイズではJavaScriptをいじることはなくCSSのみの変更で対応が可能である。

jQuery – Lightbox系プラグイン「Colorbox」

まずは、カスタマイズの元となるデザインを公式サイトで公開されている「View Demos」の5つパターンの中から選定する。Colorboxのデザイン部分は付属の「colorbox.css」で成り立っているため、想定するデザインに近いものを5つの中から選択しそれを改変すれば時間の節約になるからだ。もちろん、CSSそのものをイチから作成してもいいけどね(個人的には、文字列の画像置換で「text-indent:-9999px;」を使っているのがイヤ~な感じなので、時間があればイチから作成してもいいがw)。

ここで想定されるデザインというのは、モーダルウインドウに表示された拡大画像(コンテンツ)の両サイド“外側”に「戻る」と「次へ」のアイコンが表示されるというもの。というわけで、そのデザインに一番近い「タイプ (3)」をチョイスし、これに付属する「colorbox.css」の設定を上書きしていく。

サンプルページ

以下、重要だと思う(思われる)コードだけ抜き出して解説している。全体のHTMLソースは各自でチェックして欲しい。尚、今回はColorboxで拡大画像(コンテンツ)を見せるという趣旨により、ドキュメントの最小横幅も700pxとしスマホでの見え方は一切考慮していない。

HTML & JavaScript

サンプルページには4つのサムネイル画像が並んでいるが、それそれ以下の内容となっている。

  1. Colorbox タイプ (3) 初期バージョン
    一切手を加えていないバージョン。最低限のJavaScript関連の設定をしただけのもの。よって、「戻る」「次へ」「閉じる」の各アイコンが拡大画像(コンテンツ)に被さるように配置される。
  2. Colorbox タイプ (3) 修正バージョン 1
    「戻る」「次へ」「閉じる」の各アイコンが、拡大画像(コンテンツ)に被さらないように配置し、モーダルウインドウを閉じるためのクリック領域を拡大したバージョン。
  3. Colorbox タイプ (3) 修正バージョン 2
    「戻る」「次へ」「閉じる」の各アイコン画像が、拡大画像(コンテンツ)に被さらないように配置し、「戻る」「次へ」のクリック領域を拡大したバージョン。
  4. Colorbox タイプ (3) 修正バージョン 3
    「修正バージョン 2」を元に、「戻る」「次へ」「閉じる」の各アイコンを変更したバージョン。

1.の「初期バージョン」のままでは、ある意味“余計なモノ”が画像に被さるため、特に商業案件ではNGを喰らうことになる。Colorboxのデザインパターンでは、タイプ (3)以外のページネーションの各アイコンは、画像の上部か下部に被さらないように表示されるため問題ないが、両サイドにページネーションが配置されるタイプ (3)だけが画像に被さるようになっている。

そのため、この状態をCSSの修正で想定したデザインにするわけだが、その前にJavaScriptについてちょっと解説を。今回分かりやすいようにと思って、各バージョンでモーダルウインドウの背景色を別々にしているのだが、そのための記述が433行目からの部分になる。

//  クリック箇所それぞれに対応するクラスを#cboxOverlayに付与
    $('.modal-open-1').on('click', function(){
      $('#cboxOverlay').addClass('customization-1');
    });
    $('.modal-open-2').on('click', function(){
      $('#cboxOverlay').addClass('customization-2');
    });
    $('.modal-open-3').on('click', function(){
      $('#cboxOverlay').addClass('customization-3');
    });

.modal-open-0はデフォルトのままでいいため指定はしていない。.modal-open-1.modal-open-2.modal-open-3をクリックした際にそれぞれに対応した.customization-1.customization-2.customization-3というクラスが付与されるようにし、さらに443行目からの記述によって付与したクラスが削除される仕組みとなっている。

//  モーダルが閉じられたら付与したクラスを削除
    $('.modal-open-1, .modal-open-2, .modal-open-3').colorbox({
      onClosed:function(){
        $('#cboxOverlay').removeClass('customization-1');
        $('#cboxOverlay').removeClass('customization-2');
        $('#cboxOverlay').removeClass('customization-3');
      }
    });

onClosedというのは、「Callback that fires once Colorbox is closed.」と説明があるため、Colorboxのモーダルウインドウが閉じ終わったタイミング実行される動作ということになる。

この仕組み自体そのものは、同一ページでコンテンツに合わせて背景色を変えるという特殊な需要に応えられるかもしれないw

それでは、話を元に戻そう。

CSS

──何故、両サイドにページネーションが配置されるタイプ (3)だけが画像に被さるようになっているのかというと、Colorboxが生成するモーダルウインドウでは、背景部分の「#cboxOverlay」とコンテンツを内包する「#colorbox」がそれぞれあり、#colorboxに対してはoverflow: hidden;が設定されている。そしてこの指定により「#colorboxの横幅 = 内包するコンテンツの横幅」となり、コンテンツの横幅よりも外側に要素を配置してもブラウザ上は見えない。

ではどうするかというと、コンテンツの幅を広げてあげればいいという事になるw それが各修正バージョンに共通した設定となる。

/* *****
 * モーダルウインドウ関連の設定 */
/* -----
** 共通 */
.customization-1 + #colorbox #cboxContent,
.customization-2 + #colorbox #cboxContent,
.customization-3 + #colorbox #cboxContent {
  background-color: transparent;
  padding: 8px 44px;
}

デフォルトでは、#cboxContentbackground:#000;が指定されているため、背景をbackground-color: transparent;としたうえで、padding: 8px 44px;を追加する。これでコンテンツの上下には8px、左右には44pxの“空き”が出来ることになり、最終的に#colorboxの横幅がコンテンツの横幅+88pxとなる。padding値については任意で問題ない。まぁ、お好みで。

続けてデフォルトでは、コンテンツ部分を5pxのborderで囲っているが、それを止めてbox-shadowを付けた。これもお好みで。

.customization-1 + #colorbox #cboxLoadedContent,
.customization-2 + #colorbox #cboxLoadedContent,
.customization-3 + #colorbox #cboxLoadedContent {
  border: none;
  box-shadow: 0 0 12px -6px rgba(0, 0, 0, 1);
}

133~151行目の各指定は、拡大画像(コンテンツ)上部に表示される画像名などのテキストに関する設定なので割愛。

一応、これだけで「戻る」「次へ」「閉じる」の各アイコンは拡大画像(コンテンツ)に被ることはなくなる。しかしこのままだと、paddingで拡大した部分はクリックできない領域となってしまう。

そこで「修正バージョン 1」では、その空白の領域に#cboxClose(閉じる)を広げてみる。その前にこの方法では要素の重なり順をコントロールしなければならないので、拡大画像(コンテンツ)の直接の親要素である「#cboxLoadedContent」にposition: relative;この値を指定しないと「z-index」が利かない)とz-index: 21;を指定し、#cboxPrevious#cboxNextz-index: 11;を指定する。z-indexの値は、#cboxClose < #cboxPrevious ≤ #cboxNext ≤ #cboxLoadedContentになればいい、数値は任意で。

.customization-1 + #colorbox #cboxLoadedContent {
  position: relative;
  z-index: 21;
}
/* ページネーション設定*/
.customization-1 + #colorbox #cboxPrevious,
.customization-1 + #colorbox #cboxNext {
  z-index: 11;
}
.customization-1 + #colorbox #cboxClose {
  background: none;
  width: 100%;
  height: 100%;
  top: 0;
  right: 0;
  z-index: 1;
}

デフォルトでは#cboxCloseに「×」のアイコンが指定されており、上記の方法で#cboxClose領域を拡大したままだと各種アイコンがCSSスプライト化されている関係で「×」以外のもの見えてしまう。CSSスプライト化されていな場合でも、background-positionで目的の位置にアイコンを配置するのは難しい。そこで、#cboxCloseに指定してあるアイコンはbackground: none;で思い切って消してしまう。そして、#cboxCloseの疑似要素である#cboxClose::beforeに改めて「×」のアイコンを指定する。

.customization-1 + #colorbox #cboxClose::before {
  background: url(img/ex-controls.png) top center no-repeat;
  content: '';
  display: block;
  width: 38px;
  height: 19px;
  position: absolute;
  top: 5px;
  right: 5px;
}

マウスカーソルのホバーについては、以下のように。

.customization-1 + #colorbox #cboxClose:hover::before {
  background-position: bottom center;
}

但し、この設定では#cboxClose:hoverが前提となり、#cboxClose::beforeのアイコン部分だけでなく、paddingで拡大した部分全体が#cboxClose領域になっているため、拡大画像(コンテンツ)の左横幅44pxの部分についてもマウスカーソル・ホバーの対象となってしまう。つまり、全然違う位置にマウスカーソルがあっても「×」のアイコンが変化する領域がある事になる。

だからといって、#cboxClose::before:hoverというのは無意味な記述で、CSS2CSS3では疑似要素に擬似クラスは設定できないとなっている(CSS4では出来るようになるらしい──)。

てなわけで、このバージョンはこれ以上どうしようもない。逆に考えて、モーダルウインドウの背景部分をクリックしてもウインドウは閉じないようにし、#cboxClose部分だけが反応するという仕様にすれば、そもそも#cboxCloseの領域を拡大する必要はなくなる。そうしたい場合には、下記のようにoverlayClose: falseを追加すればよい。

    $('.modal-open-0').colorbox({
      rel: 'modal-open-0',
      maxWidth: '90%',
      overlayClose: false
    });

しかしながら、モーダルウインドウの作法を考えるとウインドウを閉じるための領域が「×」のアイコンだけというのもアレなので、「修正バージョン 2」では左右の余白部分をそれぞれ「戻る」「次へ」の領域に割り当ててみた。

/* ページネーション設定*/
.customization-2 + #colorbox #cboxPrevious,
.customization-2 + #colorbox #cboxNext {
  background: none;
  width: 44px;
  height: 100%;
  margin-top: 0;
  top: 0;
}
.customization-2 + #colorbox #cboxPrevious {
  left: 0;
}
.customization-2 + #colorbox #cboxNext {
  right: 0;
}

この設定により、元来余白となっていた拡大画像(コンテンツ)の左右部分は、それぞれ「戻る」「次へ」のクリック領域となる。background: none;としたのは、CSSスプライト化されている各種アイコンが丸見えになるのを防ぐため。

.customization-2 + #colorbox #cboxPrevious::before,
.customization-2 + #colorbox #cboxNext::before {
  content: '';
  display: block;
  width: 28px;
  height: 65px;
  margin-top: -32px;
  position: absolute;
  top: 50%;
}
.customization-2 + #colorbox #cboxPrevious::before {
  background: url(img/ex-controls.png) top left no-repeat;
  left: 5px;
}
.customization-2 + #colorbox #cboxNext::before {
  background: url(img/ex-controls.png) top right no-repeat;
  right: 5px;
}

209行目からの#cboxPrevious::before#cboxNext::beforeという疑似要素に改めて「戻る」「次へ」のアイコンを配置している。

これも、一応「修正バージョン 1」で言及したアイコン領域外であってもマウスカーソル・ホバーの対象となるという問題は孕んでいるが、拡大画像(コンテンツ)の左右の外側狭い範囲で、「戻る」「次へ」のアイコンそれぞれに対応した天地の延長線上と考えられるので流石に許容範囲でしょうw

最後に「修正バージョン 3」であるが、これは「修正バージョン 1、2」共に敢えてデフォルトのアイコンを使用していたので、そのアイコンを差し替えたバージョンで、サムネイル画像が3つしかないとページのバランスが悪いのでオマケで追加したもの。

特に解説は必要ない…かな。