画像表示でよくあるフェードして切り替えとかLightboxっぽい全画面表示とかもpointer-events
プロパティと:target
擬似要素の組み合わせで「っぽいもの」なら簡単に出来ます。最近はCSSで出来そうだなーと思うと、普通に出来るようになってて幸せですね!
Demo: Image Gallery by pointer-events
まずは画像を並べるHTMLから。
<ol>
<li id="img1"><a href="#img2"><img src="img1.png"></a></li>
<li id="img2"><a href="#img3"><img src="img2.png"></a></li>
<li id="img3"><a href="#img4"><img src="img3.png"></a></li>
<li id="img4"><a href="#img5"><img src="img4.png"></a></li>
<li id="img5"><a href="#img1"><img src="img5.png"></a></li>
</ol>
ごく普通の序列付きリストです。各画像には次の画像へのリンクが張ってあり、クリックで次の画像に進むというのをフェードインでの切り替えにするのが目標になります。
CSSもそれほどややこしいわけではなく、ほとんとモーダル・ウィンドウと同じです。pointer-events
プロパティで操作不能に、opacity
プロパティで隠しておいて、:target
擬似要素で両者を復活させるというわけです。本当に同じですね! 画像のマークアップにli/a/img
と色々HTML要素を使っているのでdisplay
プロパティでtable
を利用する方法にしました(display
プロパティでtable
を指定すると「表ですよ~」と読みあげてしまう読み上げブラウザがあるらしいのでご利用は計画的に)。
ol li {
display: table;
position: fixed;
top: 0;
left: 0;
z-index: 9999;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
opacity: 0;
transition-duration: 1.5s;
pointer-events: none;
}
ol li:target {
opacity: 1;
pointer-events: auto;
transition-duration: 3s;
}
ol li a {
display: table-cell;
width: 320px;
height: 180px;
vertical-align: middle;
text-align: center;
}
理論上は何千枚でもCSSはこのままでいけるはずです。またここでは普通にフェードイン(アウト)させてるだけですが、width
プロパティを0にしておいたりすればスライドっぽい動きとかにもなるんじゃないかなーとか思います。ここらへんはCSSの工夫(主にTransition系の工夫)だけでいろいろ出来ると思います。
Demo: Lightbox by pointer-events
全画面で画像をズームするLightboxも、「っぽいもの」程度なら簡単にいけます。デモは新しいタブやウィンドウで開かないとうまく動かないので注意してください。
HTMLはちょっとアレです。閉じるためだけにonclick
属性でJavaScriptを発火させざるを得ない感じでした。
<figure onclick="javascript:history.back()" id="img1">
<a href="#img1"><img src="http://lorempixel.com/320/180/"></a>
</figure>
ここらへんが「CSSで~」とかキャッチーなタイトルがつかなかった理由ですね!
Lightboxはまずサムネイル画像を表示させておいて、クリックで全画面に、更にクリックで元に戻るという感じのUIなので、普通に画像を格納している要素のpointer-events
を切り替えるだけではダメです。うまく動かすためには格納している要素(ここではfigure
要素)とリンクになるa
要素のpointer-events
プロパティを:target
プロパティでスワップさせるようにします。
figure {
pointer-events: none;
}
figure a {
pointer-events: auto;
}
figure:target {
background-color: rgba(0, 0, 0, 0.8);
pointer-events: auto;
}
figure:target a {
pointer-events: none;
}
figure:target a img {
width: 80%;
height: auto;
}
あとはほとんどギャラリーと同じですが、全画面の時に背景を暗くしてた上で幅に合わせてリサイズしてやるとらしくなります(height
プロパティをauto
にすれば縦横比は維持されます)。
更にHTMLが汚くなりますが、背景画像として大きいサイズの画像を持っておけば全画面時に大きいサイズに切り替えるとかも可能です。
<figure onclick="javascript:history.back()" id="img1">
<a href="#img1"
style="background-image: url('http://lorempixel.com/640/360/nightlife/4/');">
<img src="http://lorempixel.com/320/180/nightlife/4/">
</a>
</figure>
全画面表示の時は右クリックから画像が保存できないというオプション付きです! こういうのは将来的にはHTMLのdata-*
属性と超強化されるCSSのattr()
関数でゴニョゴニョできるようになるはずなので期待して待ってましょう。
世間にはいろいろ事情があるのでpointer-events
プロパティのブームはまだ来ないでしょうね……。
history.back()
と:target
での状態の切り替えを組み合わせると、どうやらpointer-events
の有効化の方がクリックイベントの終了より先に起こってしまうようです(多分)。なので履歴がある場合、Lightboxが開かれた直後にhistory.back()
が発動してしまい、うまくLightboxが表示されません。ということでhistory.back()
の代わりにlocation.hash='#close'
するようにしたデモも作ってみました。
CSSだけでできないかなーと色々考えていますが、a
要素のネストとか文法的にも実装的にもできない(WebKitでは閉じタグが補完される)のでなかなか難しそうな感じですね。img
要素を2つもたせたりすれば出来るかもしれないですが、そんなHTML書きたくないし……。