Lightbox ぽいモーダルウィンドウをCSSだけで

Lightbox ぽいモーダルウィンドウをCSSだけで

サムネイル画像をクリックすると大きいサイズの画像がモーダルウィンドウ表示される、あの効果。従来、jQuery プラグインの Lightbox などを導入することが多いと思いますが、今回は CSSのみで実装してみましょう。

サンプルコード

<!-- HTML -->
<div id="sample">
  <a href="#figure"><img src="//picsum.photos/100?image=0" alt=""></a>
  <figure id="figure">
    <a id="overlay" href="#overlay">
      <img src="//picsum.photos/600?image=0" alt="">
      <figcaption>どこかをクリックするとモーダルウィンドウを閉じます</figcaption>
    </a>
  </figure>
</div>
/* CSS */
#sample figure{
  margin: 0;
  display: none;
}
#sample figure:target{
  display: block;
  position: fixed;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 9999;
}
#sample figure:target #overlay{
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  background: rgba(255, 255, 255, 0.7);
  text-decoration: none;
  color: inherit;
}
#sample figure:target img{
  animation: fadein .3s;
}
@keyframes fadein{
  0%{
    transform: scale(0.2);
    opacity: 0.2;
  }
  100%{
    transform: scale(1);
    opacity: 1;
  }
}

サンプルDEMO

上のサムネイル画像をクリック(タップ)すると、大きな画像をモーダルウィンドウ表示します。

クリックイベントのトリガーに :target 擬似クラスを利用してみる

コード解説の前に。

サンプルコードで使用した :target 擬似クラスは、アンカーリンク(ページ内リンク)で移動した先の要素に対して適用されます。主要ブラウザの対応状況も、現在においては問題ありません。

:target 擬似クラスの活用方法を考えてみることが、このエントリーの本当の目的です。

コード解説 HTML編

HTML の3行目はサムネイル画像で、オーバーレイ表示させる要素に対してアンカーリンクを張ってあります。

4-9行目の figure 要素は、サムネイル画像がクリックされたときに表示させる部分です。なお figure 要素は、本文から参照される自己完結した図表を表す HTML要素です。div に置き換えても動作に支障はありません。

figure 要素の中に大きいサイズの画像とキャプションが入っています。それらを内包するアンカー要素 a は、オーバーレイの背景にします。同時に、アンカーリンクを自己に差すことで、モーダルウィンドウ表示を解除するリンクにもなります。

/* HTML L4-9 */

  <figure id="figure">
    <a id="overlay" href="#overlay">
      <img src="//picsum.photos/600?image=0" alt="">
      <figcaption>どこかをクリックするとモーダルウィンドウを閉じます</figcaption>
    </a>
  </figure>

コード解説 CSS編

まずは figure 要素を、初期状態では非表示にします。また、ブラウザデフォルトでは margin に値が設定されるため、0にします。

/* CSS L2-5 */

#sample figure{
  margin: 0;
  display: none;
}

次に figure:target をみてみましょう。サムネイル画像がクリックされたときに適用されます。

初期状態で非表示にした figure 要素を、display: block で表示します。また、position: fixed で表示領域に対して絶対配置で全面に固定し、z-index で最前面に表示されるようにしています。スクロールしても追従せず、ブラウザウインドウに固定されます。

/* CSS L6-14 */

#sample figure:target{
  display: block;
  position: fixed;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 9999;
}

さらに、figure 要素の中のアンカー要素 a#overlay をみてみます。

オーバーレイの背景にするため、親要素 figure に対して全面に絶対配置し、また背景色に透過の白色を指定しています。また、a#overlay の子要素を縦に並べた上で上下左右中央寄せしたいので、display: flex 以下の4行を指定してあります。

なお、このアンカー要素は HTML上で自己アンカーリンクしているので、クリックすると :target 擬似クラスが figure 要素から外れ、CSSの適用も外れます。

/* CSS L15-28 */

#sample figure:target #overlay{
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  background: rgba(255, 255, 255, 0.7);
  text-decoration: none;
  color: inherit;
}

サムネイル画像がクリックされたとき、大きな画像が浮かび上がるように表示されるよう動きをつけます。

画像要素 img に、縮小かつ透過させた状態から元に戻すアニメーションを設定しています。

/* CSS L29-41 */

#sample figure:target img{
  animation: fadein .3s;
}
@keyframes fadein{
  0%{
    transform: scale(0.2);
    opacity: 0.2;
  }
  100%{
    transform: scale(1);
    opacity: 1;
  }
}

:checked 擬似クラスを使う手も

:target 擬似クラスはほかにも、タブ表示切替などに使えそうです。

ただ、アンカーリンクのクリック時にページ表示位置も移動してしまうこと、:target 擬似クラスを外すためのアンカーリンクも別途必要なことに注意が必要です。今回のサンプルコードでは、アンカーリンク先の要素を表示領域のトップに固定しているので、クリックしてもページ内での移動が生じないというわけです。

CSSのみでクリックイベントを実装する場合、以前記事にした :checked 擬似クラスの方が使い勝手がよいかもしれません。ケースバイケースでしょうか。興味がありましたら、関連記事「クリックイベントをCSSだけで」もご参照ください。