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だけで」もご参照ください。