今回はCSSのみを使用して、かなりイイ感じのスライディング・イメージ・パネルの作成方法をご紹介したいと思います。これはパネルに背景画像をセットして、ラベルをクリックすればアニメーション化されるというものです。ラベルにはラジオボタンを使用し、ターゲットはそれそれのパネル部分とし間接セレクタ(general sibling selector)を使っていきます。

SlidingImagePanelsCss3 2 CSS3 イメージスライドパネルショー

今回使用する美しいな画像はJoanna Kustraさんによるもので、Attribution-NonCommercial 3.0 Unported Creative Commons Licenseの元に帰属しています。

同じ様なテクニックを使って、画像をホバーするとスクリーンがかかる効果をFilter Functionality with CSS3でご紹介しておりますので、こちらも併せてご覧くださいね。

※CSS transitionとアニメーションをサポートしているブラウザでのみ正常に動作します。お気を付け下さいね。

この記事は、http://tympanus.net/codrops/の許可を得て、翻訳しています。一部変更して翻訳している部分もある場合があります。オリジナルの記事はここよりご覧いただけます。

HTMLマークアップ

HTMLは大分すると「ラジオボタンとラベル」「パネル用コンテナと各画像のスライス」「タイトル」という3つのパートから成り立っています。「cr-bgimg」クラスを割り当てたコンテナは各パネルを含有しています。更に各パネルは4枚にスライスされており、各スライスは正しい場所に配置されるようにSPANタグで囲まれています。すなわち1つ目のパネルは4枚のスライスから成り、1つ目のスライスは背景画像として最も左側に配置されます。2つ目のパネルも勿論4枚のスライスから成りますが、背景画像の配置場所は「次」の部分へと移行されます。

<section class="cr-container">           

    <!-- radio buttons and labels -->
    <input id="select-img-1" name="radio-set-1" type="radio" class="cr-selector-img-1" checked/>
    <label for="select-img-1" class="cr-label-img-1">1</label>

    <input id="select-img-2" name="radio-set-1" type="radio" class="cr-selector-img-2" />
    <label for="select-img-2" class="cr-label-img-2">2</label>

    <input id="select-img-3" name="radio-set-1" type="radio" class="cr-selector-img-3" />
    <label for="select-img-3" class="cr-label-img-3">3</label>

    <input id="select-img-4" name="radio-set-1" type="radio" class="cr-selector-img-4" />
    <label for="select-img-4" class="cr-label-img-4">4</label>

    <div class="clr"></div>

    <!-- panels -->
    <div class="cr-bgimg">
        <div>
            <span>Slice 1 - Image 1</span>
            <span>Slice 1 - Image 2</span>
            <span>Slice 1 - Image 3</span>
            <span>Slice 1 - Image 4</span>
        </div>
        <div>
            <span>Slice 2 - Image 1</span>
            <span>Slice 2 - Image 2</span>
            <span>Slice 2 - Image 3</span>
            <span>Slice 2 - Image 4</span>
        </div>
        <div>
            <span>Slice 3 - Image 1</span>
            <span>Slice 3 - Image 2</span>
            <span>Slice 3 - Image 3</span>
            <span>Slice 3 - Image 4</span>
        </div>
        <div>
            <span>Slice 4 - Image 1</span>
            <span>Slice 4 - Image 2</span>
            <span>Slice 4 - Image 3</span>
            <span>Slice 4 - Image 4</span>
        </div>
    </div>

    <!-- titles -->
    <div class="cr-titles">
        <h3>
            <span>Serendipity</span>
            <span>What you've been dreaming of</span>
        </h3>
        <h3>
            <span>Adventure</span>
            <span>Where the fun begins</span>
        </h3>
        <h3>
            <span>Nature</span>
            <span>Unforgettable eperiences</span>
        </h3>
        <h3>
            <span>Serenity</span>
            <span>When silence touches nature</span>
        </h3>
    </div>

</section>

タイトル用のH3要素には2つのSPANタグがあり、1つはメインヘッドライン用でもう1つはサブヘッドライン用です。

それではCSSスタイリングに移りましょう!

CSSスタイリング

ベンダープリフィックスは省略しています。ご了承ください。

私たちの目的は、第1にラベルでカバーしてラジオボタンを隠すことです。WEBブラウザ上でラベルをクリックすれば、それぞれのチェックボックスかラジオボタンが選択された状態になります。なので、インプットにIDを与えればラベルの「for = 参照ID」属性を使って、それぞれのインプットを参照することが可能となります。

次に全ての背景画像を適切な部分に配置すること。第3にラベルがクリックされたら、それぞれのスライス画像とタイトルがきちんと表示されるようにすることです。

それでは、まずは最も外側のコンテナのスタイリングです。白いボーダー線を引いて、ボックスシャドウでほんのり影もつけましょう。

.cr-container{
    width: 600px;
    height: 400px;
    position: relative;
    margin: 0 auto;
    border: 20px solid #fff;
    box-shadow: 1px 1px 3px rgba(0,0,0,0.1);
}

きちんと目的のスライス画像とタイトルに辿りつくように間接セレクタ(general sibling selector)を使用したいので、ここでまずラベルを適切に配置しておく必要があります。z-indexを使ってレイヤーが最上部に来るようにし、トップマージンを350px確保して下の方に配置します。

.cr-container label{
    font-style: italic;
    width: 150px;
    height: 30px;
    cursor: pointer;
    color: #fff;
    line-height: 32px;
    font-size: 24px;
    float:left;
    position: relative;
    margin-top: 350px;
    z-index: 1000;
}

ラベルに小さな円を加えて、ちょっとかわいくデコりましょう。疑似要素を使って丁度テキストの背後に来るように配置します。

.cr-container label:before{
    content:'';
    width: 34px;
    height: 34px;
    background: rgba(130,195,217,0.9);
    position: absolute;
    left: 50%;
    margin-left: -17px;
    border-radius: 50%;
    box-shadow: 0px 0px 0px 4px rgba(255,255,255,0.3);
    z-index:-1;
}

パネル間にもちょっと細工を施してみましょう。ラベル用に別の疑似要素を用意して、パネル状に縦線を描きます。グラデーションを使っているので上の方に行くにつれ線が薄く消えていくよう見えるはずです。

.cr-container label:after{
    width: 1px;
    height: 400px;
    content: '';
    background: linear-gradient(top, rgba(255,255,255,0) 0%,rgba(255,255,255,1) 100%);
    position: absolute;
    bottom: -20px;
    right: 0px;
}

最後のパネルに縦線は不要なので、幅を0pxにしています。

.cr-container label.cr-label-img-4:after{
    width: 0px;
}

ラベルの設定が完了したので、安心してインプットを隠してしまいましょう。

.cr-container input{
    display: none;
}

これでラベルをクリックすれば、対応するインプットがチェックされた状態になります。では今度はラベルに間接セレクタ(general sibling selector)を使用して細工していきましょう。下記のようにコーディングすると、選択されたラベルの色を変更することができます。

.cr-container input.cr-selector-img-1:checked ~ label.cr-label-img-1,
.cr-container input.cr-selector-img-2:checked ~ label.cr-label-img-2,
.cr-container input.cr-selector-img-3:checked ~ label.cr-label-img-3,
.cr-container input.cr-selector-img-4:checked ~ label.cr-label-img-4{
    color: #68abc2;
}

それから円部分の疑似要素の背景色とボックスシャドウも変更します。

.cr-container input.cr-selector-img-1:checked ~ label.cr-label-img-1:before,
.cr-container input.cr-selector-img-2:checked ~ label.cr-label-img-2:before,
.cr-container input.cr-selector-img-3:checked ~ label.cr-label-img-3:before,
.cr-container input.cr-selector-img-4:checked ~ label.cr-label-img-4:before{
    background: #fff;
    box-shadow: 0px 0px 0px 4px rgba(104,171,194,0.6);
}

画像パネルのコンテナはabsoluteで絶対配置し、幅はいっぱいいっぱいに使います。このコンテナは「現在選択されている画像」に背景画像を設定する為、後程使用します。これはデフォルトとして何らかの画像が表示された状態を維持する為です。なので幾つかの背景プロパティを追加しておきましょう。

.cr-bgimg{
    width: 600px;
    height: 400px;
    position: absolute;
    left: 0px;
    top: 0px;
    z-index: 1;
    background-repeat: no-repeat;
    background-position: 0 0;
}

表示用の画像(パネル)は4枚に分割しているので、1つのパネルの幅は150pxです。(600÷4)。パネルはフロートで左に配置し、スライドインして来る時に余計な部分まで表示したくないのでオーバーフロー分はhiddenで隠します。

.cr-bgimg div{
    width: 150px;
    height: 100%;
    position: relative;
    float: left;
    overflow: hidden;
    background-repeat: no-repeat;
}

SPANタグで囲まれた各スライスはabsoluteで絶対配置し、左側-185pxに配置することにより最初は隠された状態であるようにします。

.cr-bgimg div span{
    position: absolute;
    width: 100%;
    height: 100%;
    top: 0px;
    left: -150px;
    z-index: 2;
    text-indent: -9000px;
}

それから次に画像コンテナの背景と、それぞれの画像スライスの設定です。

.cr-container input.cr-selector-img-1:checked ~ .cr-bgimg,
.cr-bgimg div span:nth-child(1){
    background-image: url(../images/1.jpg);
}
.cr-container input.cr-selector-img-2:checked ~ .cr-bgimg,
.cr-bgimg div span:nth-child(2){
    background-image: url(../images/2.jpg);
}
.cr-container input.cr-selector-img-3:checked ~ .cr-bgimg,
.cr-bgimg div span:nth-child(3){
    background-image: url(../images/3.jpg);
}
.cr-container input.cr-selector-img-4:checked ~ .cr-bgimg,
.cr-bgimg div span:nth-child(4){
    background-image: url(../images/4.jpg);
}

ここで背景ポジションはパネルによって配置場所が異なるので、間違わないように気をつけながら設定します。

.cr-bgimg div:nth-child(1) span{
    background-position: 0px 0px;
}
.cr-bgimg div:nth-child(2) span{
    background-position: -150px 0px;
}
.cr-bgimg div:nth-child(3) span{
    background-position: -300px 0px;
}
.cr-bgimg div:nth-child(4) span{
    background-position: -450px 0px;
}

ラベルがクリックされたら、全てのスライス全てが右側へとスライドアウトするように設定します。

.cr-container input:checked ~ .cr-bgimg div span{
    animation: slideOut 0.6s ease-in-out;
}
@keyframes slideOut{
    0%{
        left: 0px;
    }
    100%{
        left: 150px;
    }
}

選択された背景画像は-150pxから0pxへとスライドインしてきます。

.cr-container input.cr-selector-img-1:checked ~ .cr-bgimg div span:nth-child(1),
.cr-container input.cr-selector-img-2:checked ~ .cr-bgimg div span:nth-child(2),
.cr-container input.cr-selector-img-3:checked ~ .cr-bgimg div span:nth-child(3),
.cr-container input.cr-selector-img-4:checked ~ .cr-bgimg div span:nth-child(4)
{
    transition: left 0.5s ease-in-out;
    animation: none;
    left: 0px;
    z-index: 10;
}

最後にH3のタイトル要素とSPANタグのスタイリングを行います。H3には透過度のトランジッションを適用させ、対応するラベル(インプット)が選択されたら透過度が0から1へと増加するよう設定します。

.cr-titles h3{
    position: absolute;
    width: 100%;
    text-align: center;
    top: 50%;
    z-index: 10000;
    opacity: 0;
    color: #fff;
    text-shadow: 1px 1px 1px rgba(0,0,0,0.1);
    transition: opacity 0.8s ease-in-out;
}
.cr-titles h3 span:nth-child(1){
    font-family: 'BebasNeueRegular', 'Arial Narrow', Arial, sans-serif;
    font-size: 70px;
    display: block;
    letter-spacing: 7px;
}
.cr-titles h3 span:nth-child(2){
    letter-spacing: 0px;
    display: block;
    background: rgba(104,171,194,0.9);
    font-size: 14px;
    padding: 10px;
    font-style: italic;
    font-family: Cambria, Palatino, "Palatino Linotype", "Palatino LT STD", Georgia, serif;
}
.cr-container input.cr-selector-img-1:checked ~ .cr-titles h3:nth-child(1),
.cr-container input.cr-selector-img-2:checked ~ .cr-titles h3:nth-child(2),
.cr-container input.cr-selector-img-3:checked ~ .cr-titles h3:nth-child(3),
.cr-container input.cr-selector-img-4:checked ~ .cr-titles h3:nth-child(4){
    opacity: 1;
}

もしモバイルデバイスではラベルのトリックを使用したくなかったら、メディアクエリーを使って以下のように設定します。

@media screen and (max-width: 768px) {
    .cr-container input{
        display: inline;
        width: 24%;
        margin-top: 350px;
        z-index: 1000;
        position: relative;
    }
    .cr-container label{
        display: none;
    }
}

これはとてもシンプルな解決方法なので、必要あらばif the label trick is supportedもチェックしてみてください。

これで完成です!他にも色々実現可能な効果があるかと思います。幾つかデモをご用意しましたので、そちらも併せてご覧くださいね。

DEMO

  1. Demo 1: Slide to right(右側へスライド)
  2. Demo 2: Odd/even slide to left/right(奇数と偶数でそれぞれ右側と左側へ)
  3. Demo 3: Odd/even slide up/down(奇数と偶数で上と下へ)
  4. Demo 4: Scale up/down(縮小拡大)

今回はここまでです。みなさんのご参考になれば幸いです。