てくすた

ピクスタ株式会社のエンジニア・デザイナーがつづるよもやまテクニカルブログです

JavaScript不使用!HTML/CSSで作成するギャラリー

こんにちは、デザイナーの瀬戸口です(・ω・) 関西から関東に出てきて1年......我ながら思い切った決断をしたなぁと改めて感じています。(ご興味ある方は「大阪でデザイナーをしていた僕が家族を連れて上京、ピクスタに転職した理由」をご覧ください。)

さて、今回は「JavaScript」を使わず「HTML/CSS」のみでギャラリーを作成しました。
今回はそのコードをご紹介していきたいと思います。
(「JavaScriptを使わないことでどんなメリットがあるの?」という方は前の記事「JavaScript不使用!HTML/CSSで作成するアコーディオン」をご覧ください。)

目次:

どうやって作るの?

今回はHTMLの「input」「label」タグ、CSSの「〜:checked」が重要な役割を担います。
「fotowa」の「photobook紹介ページ」で作成しました。

ギャラリーイメージ
(URL:https://fotowa.com/goods

実際のコード

「 HTML」(該当部分のみ抜粋)

<div class="intro">
  <input type="radio" id="story1" class="story1" name="〜" checked><input type="radio" id="story8" class="story8" name="〜">
  <div class="intro__gallery">
    <div class="main">
      <img src="〜" class="main__img main__img--1"><img src="〜" class="main__img main__img--8">
    </div>
    <ul class="thumbnail">
      <li>
        <label for="story1">
          <img src="〜" class="image">
        </label>
      </li><li>
        <label for="story8">
          <img src="〜" class="image">
        </label>
      </li>
    </ul>
  </div></div><div class="intro">
  <input type="radio" id="joy1" class="joy1" name="〜" checked><input type="radio" id="joy8" class="joy8" name="〜">
  <div class="intro__gallery">
    <div class="main">
      <img src="〜" class="main__img main__img--1"><img src="〜" class="main__img main__img--8">
    </div>
    <ul class="thumbnail">
      <li>
        <label for="joy1">
          <img src="〜" class="image">
        </label>
      </li><li>
        <label for="joy8">
          <img src="〜" class="image">
        </label>
      </li>
    </ul>
  </div></div>

<input type=”radio”>を使用することで、ユーザーがサムネイルの画像をクリックすると<input>に紐づいた<label>をクリックしたことになり、該当の<input>がchecked状態となって、ユーザーがそれを選択したか検知できるようになります。複数選択を可能としたい場合は(ギャラリーではないと思いますが......)<type=”checkbox”>で構築する必要があります。

「CSS(Sass)」(該当部分のみ抜粋)

&__gallery {

  .main {

    &__img {
      opacity: 0;
    }
  }

  input[type="radio"] {
    display: none;
  }

  // galleryAnimation 定義
  @mixin galleryAnimation($name, $items) {

    @for $i from 1 through $items {

      .#{$name}#{$i}:checked {

        & ~ .intro__gallery {

          .main {

            &__img {

              &--#{$i} {
                opacity: 1;
              }
            }
          }

          .thumbnail {

            li:nth-child(#{$i}) {

              .image {
                opacity: 0.8;
              }
            }
          }
        }
      }
    }
  }
}

まずはmain画像の部分ですが、デフォルトでは{opacity:0;}にして全ての画像を一箇所に重ねて配置します。(デザインソフトで例えるならば、レイヤーを重ねるイメージです。)
また、<input type=”radio”>はユーザーの行動検知に使いますが、見た目上は<label><img>で作成しますので{display:none;}で非表示にしておきます。
次にサムネイルがクリックされたら、対応するmain画像が{opacity:1;}になるようにfor関数を利用して繰り返し処理を作成します。(for関数について詳しく知りたい方はこちら
最後に選択された(されている)サムネイル画像がどれか認識できるように、{opacity}{border}などを使って調整してあげれば完成です。

まとめ

いかがでしょうか?想像よりもHTMLタグ / CSSプロパティが少なく感じたのではないでしょうか?
動作の部分だけを抜粋しているので、実際に作るときは横並びにしたりとCSSの記述量は増えると思いますが、それでも思った以上にシンプルで簡単に作成できると思いますので、皆さんも是非チャレンジしてみてください ٩( 'ω' )ﻭ オー
また実務で何か作ることがあればご紹介したいと思います。