【UI/jQuery】画像の上にチェックボックスを重ねて表示する方法

画像の上にチェックボックス重ねて表示する方法を紹介します。まあなんというか、WordPressの「メディアを追加」のような感じのUIです。

動作はChrome(43.0.2357.134)とFirefox(39.0)で確認しました。

作成物イメージ

動作デモ

以下のように画像が並んでいて、クリックすると画像が選択状態になります。

別ウィンドウで表示する場合はこちらをクリックしてください。

作成の流れ

この記事では、以下の流れでサンプルの作成を進めていきます。

  1. 画像リストページを作成する
  2. 画像リストにチェックボックスを配置する
  3. 画像が選択状態のときのデザインを設定する
  4. 画像クリックで選択できるようにする

なお、ソースをシンプルにするため、サンプルでは画像を1つだけ表示するように作成します。

画像リストページを作成する

最初にチェックボックスを設置する前の段階の、画像を横に並べたページを作成します。

画像表示周りのソースは以下のように、シンプルなコード担っているかを思います。

<ul class="image_list">
  <li>
    <div class="image_box">
      <img class="thumbnail" src="./foo1.png" alt="foo" />
    </div>
  </li>
</ul>

このliタグを横並びにするため、CSSファイルにdisplay: inline-block;を記述しています。表示する画像を増やす場合は、liタグをまるごと増やしていきます。

これで、チェックボックスを配置する前の、画像リストページが作成できました。といっても、見た目は以下のように、画像が1つ表示されるだけです。

画像リストページ

ソース全体

この段階の、ソースの全体像は以下の通りです。

index.html

<!DOCTYPE html>
<html>
  <head>
    <link rel="stylesheet" href="./style.css" />
  </head>
  <body>
    <div id="main">
      <ul class="image_list">
        <li>
          <div class="image_box">
            <img class="thumbnail" src="./foo1.png" alt="foo" />
          </div>
        </li>
      </ul>
    </div>
  </body>
</html>

style.css

ul.image_list li {
  /* liが横並びになるようにします。 */
  display: inline-block;
}
ul.image_list li .image_box {
  width: 200px;
  height: 200px;
}
.image_box img.thumbnail {
  width: 100%;
  height: 100%;
}

チェックボックスを設置する

画像リストを作成したら、次はチェックボックスを設置します。下記コードのように、imgタグの次にチェックボックスを表示するinputタグを置いています。

<ul class="image_list">
  <li>
    <div class="image_box">
      <img class="thumbnail" src="./foo1.png" alt="foo" />
      <!-- これを追加します。 -->
      <input class="disabled_checkbox" type="checkbox" checked />
      <!-- これを追加します。 -->
    </div>
  </li>
</ul>

これでチェックボックスが表示されるようになりました。ただし、この段階ではチェックボックスが画像の横に表示されているので、CSSで画像と重なって表示するようにします。

CSSを修正してチェックボックスを画像に重ねる

チェックボックスを画像と重ねて表示するために、まずはチェックボックスの親要素にposition: relativeを追加します。

ul.image_list li .image_box {
  width: 200px;
  height: 200px;
  /* これを追加します。 */
  position: relative;
  /* これを追加します。 */
}

そして、チェックボックスにposition: abosoluteを指定して、親要素に対して絶対位置で配置できるようにします。また、位置はtop: 12pxright: 12pxで、親の右上から12pxの位置にしています。

.image_box .disabled_checkbox {
  /* チェックボックスの位置は絶対位置にします。 */
  position: absolute;
  /* チェックボックスは、親要素の右上から12pxの位置に配置します。 */
  top: 12px;
  right: 12px;
}

これで、以下のように、画像にチェックボックスが重なって表示されるようになりました。

チェックボックスを配置

ソース全体

この段階の、ソースの全体像は以下の通りです。

index.html

<!DOCTYPE html>
<html>
  <head>
    <link rel="stylesheet" href="./style.css" />
  </head>
  <body>
    <div id="main">
      <ul class="image_list">
        <li>
          <div class="image_box">
            <img class="thumbnail" src="./foo1.png" alt="foo" />
            <input class="disabled_checkbox" type="checkbox" checked />
          </div>
        </li>
      </ul>
    </div>
  </body>
</html>

style.css

ul.image_list li {
  /* liが横並びになるようにします。 */
  display: inline-block;
}
ul.image_list li .image_box {
  width: 200px;
  height: 200px;
  /* チェックボックスの親要素にrelativeを指定しておきます。 */
  position: relative;
}
.image_box img.thumbnail {
  width: 100%;
  height: 100%;
}
.image_box .disabled_checkbox {
  /* チェックボックスの位置は絶対位置にします。 */
  position: absolute;
  /* チェックボックスは、親要素の右上から12pxの位置に配置します。 */
  top: 12px;
  right: 12px;
}

画像が選択状態のときのデザインを設定する

画像のデザイン

後ほどJavaScriptで、画像を選択するとimgタグのクラスにcheckedが追加されるようにします。そのため、画像が選択状態のときのデザインは、.image_box img.thumbnail.checkedの中に書いていきます。書く内容は、画像の周りに枠線を引くだけです。

.image_box img.thumbnail.checked {
  /* チェックが入った状態だと、枠が表示されるようにします。 */
  border: 6px solid blue;
  /* 線をwidthとheightに含めるようにします。 */
  box-sizing: border-box;
}

チェックボックスのデザイン

チェックボックスは、画像が選択状態でない場合は非表示、選択状態の場合は表示されるようにします。

まずは、画像が選択状態でない場合です。以下のように、チェックボックスは常にdisplay: noneで表示されないようにしておきます。

.image_box .disabled_checkbox {
  ...
  /* チェック前は非表示にしておきます。 */
  display: none;
}

そして、画像が選択状態になったら、display: blockでチェックボックスを表示してあげます。

.image_box img.thumbnail.checked + .disabled_checkbox {
  /* 画像にcheckedクラスが指定されたときは、
  チェックボックスの非表示を解除します。 */
  display: block;
}

ちなみに、.image_box img.thumbnail.checked + .disabled_checkboxは、「checkedが入ったimgタグの直後にあるチェックボックス」を示しています。(MDN 隣接セレクタ

これで画像が選択状態のときのデザインを作成できました。imgタグのクラスに「checked」を追加すると、以下のように選択状態の確認できます。

チェックされた状態

ソース全体

この段階の、ソースの全体像は以下の通りです。

index.html

変更なし

style.css

ul.image_list li {
  /* liが横並びになるようにします。 */
  display: inline-block;
}
ul.image_list li .image_box {
  width: 200px;
  height: 200px;
  /* チェックボックスの親要素にrelativeを指定しておきます。 */
  position: relative;
}
.image_box img.thumbnail {
  width: 100%;
  height: 100%;
}
.image_box img.thumbnail.checked {
  /* チェックが入った状態だと、枠が表示されるようにします。 */
  border: 6px solid blue;
  /* 線をwidthとheightに含めるようにします。 */
  box-sizing: border-box;
}
.image_box .disabled_checkbox {
  /* チェックボックスの位置は絶対位置にします。 */
  position: absolute;
  /* チェックボックスは、親要素の右上から12pxの位置に配置します。 */
  top: 12px;
  right: 12px;
  /* チェック前は非表示にしておきます。 */
  display: none;
}
.image_box img.thumbnail.checked + .disabled_checkbox {
  /* 画像にcheckedクラスが指定されたときは、
  チェックボックスの非表示を解除します。 */
  display: block;
}

画像クリックで選択できるようにする

最後はJavaScriptで動きを付けます。JavaScriptのコードを記述する、base.jsをbodyの閉じタグの直前で読み込みます。また、jQueryも使うので、それも読み込みます。

<html>
    ...
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
    <script src="./base.js"></script>
  </body>
</html>

そして、読み込むbase.jsに処理を記述していきます。

画像クリックで選択状態にする

画像がクリックされたら、checkedクラスを持つ、つまり現在選択中の画像の選択を解除します。そして、チェックされた画像自身にcheckedクラスを追加しています。

// 画像がクリックされた時の処理です。
$('img.thumbnail').click(function() {
  var $imageList = $('.image_list');

  // 現在の選択を解除します。
  $imageList.find('img.thumbnail.checked').removeClass('checked');

  // チェックを入れた状態にします。
  $(this).addClass('checked');
});

チェックボックスを押せないようにする

チェックボックスがクリックされたときに、return falseでチェックを入れる処理を中断しています。

// チェックボックスのクリックを無効化します。
$('.image_box .disabled_checkbox').click(function() {
  return false;
});

完成形コード

最後に完成形のコードを掲載します。なお、上記手順では省略しましたが、CSSに以下の内容を追加しています。

  • 画像・チェックボックスにカーソルを合わせたときに指のマークになるようにしました。
  • チェックボックスを大きくしました。

index.html

<!DOCTYPE html>
<html>
  <head>
    <link rel="stylesheet" href="./style.css" />
  </head>
  <body>
    <div id="main">
      <ul class="image_list">
        <li>
          <div class="image_box">
            <img class="thumbnail" src="./foo1.png" alt="foo" />
            <input class="disabled_checkbox" type="checkbox" checked />
          </div>
        </li>
      </ul>
    </div>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
    <script src="./base.js"></script>
  </body>
</html>

style.css

ul.image_list li {
  /* liが横並びになるようにします。 */
  display: inline-block;
}
ul.image_list li .image_box {
  width: 200px;
  height: 200px;
  /* チェックボックスの親要素にrelativeを指定しておきます。 */
  position: relative;
}
.image_box img.thumbnail {
  width: 100%;
  height: 100%;
  /* 画像にカーソルを合わせたときに、
  カーソルが指のマークになるようにします。 */
  cursor: pointer;
}
.image_box img.thumbnail.checked {
  /* チェックが入った状態だと、枠が表示されるようにします。 */
  border: 6px solid blue;
  /* 線をwidthとheightに含めるようにします。 */
  box-sizing: border-box;
}
.image_box .disabled_checkbox {
  /* チェックボックスの位置は絶対位置にします。 */
  position: absolute;
  /* チェックボックスは、親要素の右上から12pxの位置に配置します。 */
  top: 12px;
  right: 12px;
  /* チェック前は非表示にしておきます。 */
  display: none;
  /* チェックボックスを大きくします。 */
  transform: scale(2);
  /* チェックボックスにカーソルを合わせたときに、
  カーソルが指のマークになるようにします。 */
  cursor: pointer;
}
.image_box img.thumbnail.checked + .disabled_checkbox {
  /* 画像にcheckedクラスが指定されたときは、
  チェックボックスの非表示を解除します。 */
  display: block;
}

base.js

$(function() {
  // チェックボックスのクリックを無効化します。
  $('.image_box .disabled_checkbox').click(function() {
    return false;
  });

  // 画像がクリックされた時の処理です。
  $('img.thumbnail').click(function() {
    var $imageList = $('.image_list');

    // 現在の選択を解除します。
    $imageList.find('img.thumbnail.checked').removeClass('checked');

    // チェックを入れた状態にします。
    $(this).addClass('checked');
  });
});

画像を複数選択できるようにする

問い合わせがあったので追記しておきます。

画像を複数選択できるようにするためにはbase.jsを修正します。具体的には以下の部分を削除します。

    // 現在の選択を解除します。
    $imageList.find('img.thumbnail.checked').removeClass('checked');

上記部分を削除すると、画像をクリックしたときに、全ての画像の選択を一旦解除するという処理が削除されます。その結果、画像を複数選択できるようになります。

ただし、今度は解除ができなくなります。そのため、選択されている画像をクリックするとチェックが外れるというように仕様を変更しておきます。その場合のbase.jsは以下のようになります。

base.js

$(function() {
  // チェックボックスのクリックを無効化します。
  $('.image_box .disabled_checkbox').click(function() {
    return false;
  });

  // 画像がクリックされた時の処理です。
  $('img.thumbnail').on('click', function() {
    if (!$(this).is('.checked')) {
      // チェックが入っていない画像をクリックした場合、チェックを入れます。
      $(this).addClass('checked');
    } else {
      // チェックが入っている画像をクリックした場合、チェックを外します。
      $(this).removeClass('checked')
    }
  });
});

また、ソースは記述しませんが、大抵の場合は「画像を一括で選択・解除する仕組み」があった方が使い勝手はよくなると思われます。

デモ

別ウィンドウで表示する場合はこちらをクリックしてください。

この記事が役に立った場合、シェアしていただけると励みになります!!