CSSのみでクリックで画像を拡大する(Lightboxもどき)

CSSのみでクリックで画像を拡大する

画像をクリックするとポップアップで拡大表示するプラグインを、HTMLとCSSのみで再現してみます。いわゆるLightboxやfancyboxのようなものです。

この記事で紹介するコードは実用性は全くありません。遊び半分でご覧ください。

デモ

画像拡大

下の画像をクリックしてみてください。

テキストにも拡大リンクを貼れます。
スイセンの写真を見る

応用 - YouTubeの動画を拡大

YouTubeを拡大して再生することもできます。

LOVER / AAA

弱点

記事に表示する画像と、拡大に使用する画像の2つを読み込む必要があります。SEO的にはあまり良くないと思います。

フィルター(黒い部分)は、画像を開いていない状態のときはpointer-eventsを用いてクリックイベントをオフにしていますが、開いていない状態でも常にフィルターは被さっているので、ちょっとキモいです。

また、pointer-eventsをサポートしていないブラウザで閲覧したときは、ページ全体のリンクがクリックできない状態に陥る可能性があります。

さらに、アンカーリンクを利用するので、画像を拡大すると履歴に残り、ブラウザで「戻る」操作が大変になります。

実装方法

CSS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
.lb {
display: flex;
position: fixed;
width: 100%;
height: 100%;
top: 0;
left: 0;
justify-content: center;
align-items: center;
background: rgba(0,0,0,.7);
opacity: 0;
transition: .3s opacity ease;
pointer-events: none;
z-index: 100;
}

.lb img {
width: auto !important;
max-height: 100%!important;
cursor: pointer;
}

.lb img,
.lb iframe {
transform: scale(.85);
transition: .3s all ease;
}

.lb:target {
opacity: 1;
pointer-events: auto;
z-index: 101;
}

.lb:target img,
.lb:target iframe {
transform: scale(1);
}

/* なんちゃって閉じるボタン*/
.lb::before,.lb::after {
display: block;
position: fixed;
content: "";
width: 24px;
height:3px;
top: 24px;
right: 12px;
background: #fff;
border-radius: 4px;
}
.lb::before {
transform: rotate(-315deg);
}
.lb::after {
transform: rotate(315deg);
}

HTML

1
2
<a href="#sample01</span>"><img src="記事の画像URL"></a>
<a id="sample01</span>" href="#close" class="lb"><img src="拡大する画像URL"></a>

sample01の二箇所は、画像毎に任意の文字列を指定してください。また、同じページで文字列が被らないようにしてください。

YouTubeは以下のように記述することで拡大できます。

1
2
<a href="#youtube">ここに文字</a>
<a id="youtube" href="#close" class="lb">YouTubeで発行する埋め込みコード</a>

YouTubeで動画の周りを暗くして見やすくするブックマークレット

YouTubeで動画の周りを暗くして見やすくするブックマークレットを作りました。Google Chromeの拡張機能「Turn Off the Lights」のブックマークレット版だと思っていただれければいいと思います。

ブラウザの拡張機能に対し、ブックマークレットは必要なときのみ動作し重くならないので快適です。

使い方

まず適当なページでブックマークを作成した後、ブックマークを右クリックして編集画面を開き、名前欄には任意のタイトルを、URL欄には下のコードをコピペし保存してください。

1
javascript:(function(){var filter=document.getElementById('filter');var player_container=document.getElementById('player-container');if(!filter){var filter=document.createElement('div');filter.setAttribute('id','filter');filter.setAttribute('style','position:fixed;width:100%;height:100%;background:rgba(0,0,0,.85);z-index:9998;');document.body.appendChild(filter);player_container.style.zIndex='9999';}else{document.body.removeChild(filter);player_container.style.zIndex='';}})()

YouTubeの再生画面を開いている状態で登録したブックマークを押すと、動画の周りが暗くなります。

解除するときはもう一度ブックマークをクリックしてください。

ソース

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
javascript:
(function(){
var filter = document.getElementById('filter');
var player_container = document.getElementById('player-container');
if(!filter) {
var filter = document.createElement('div');
filter.setAttribute('id','filter');
filter.setAttribute('style','position:fixed;width:100%;height:100%;background:rgba(0,0,0,0.85);z-index:9998;');
document.body.appendChild(filter);
player_container.style.zIndex='9999';
}
else {
document.body.removeChild(filter);
player_container.style.zIndex='';
}
})()

8行目のbackgroundのところをイジると、周りのフィルターを好きな色に変えられます。今回はフィルター部分を半透明にしたいのでrgba表記にしてあります。0.85の数値をイジれば透明度を変更できます。(1で真っ暗)

z-index戦争が勃発しているようにも見えますが、それは気のせいです。


HTMLだけでコンテンツを開閉できる<details>を試してみる

<details>タグはHTML5.1で追加されたタグで、コンテンツを開閉できるウィジェットを生成します。

概要

1
2
3
4
<details>
<summary>日程</summary>
2019年4月1日(月)開場:13:00
</details>
日程 2019年4月1日(月)開場:13:00

<details>の中には1つの<summary>タグ、そしてフローコンテンツに分類されるbody内で使われるほとんどの要素を置くことができます。

参考:フロー・コンテンツについて

装飾をしてみる

detailsを開くとopenという属性が付されるので、それを利用してCSSでカスタマイズしてみます。

装飾をしてみたテスト
CSSでアニメーションを付けてみました。








何も書くことがない!!
1
2
3
4
5
6
<details id="designed">
<summary>タイトル(サマリー)</summary>
<div class="details_content">
ここに中身
</div>
</details>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
summary {
outline: none;
cursor: pointer;
}

/*デフォルトの三角を消す */
summary::-webkit-details-marker {
display:none;
}

/* 疑似要素で三角を付ける */
summary::before {
display: inline-block;
content: "▶";
margin: 0 .3em 0 0;
transform: rotate(0deg);
transition: .2s transform ease;
}

details[open] summary::before {
transform: rotate(90deg);
}

.details_content {
background: #f5f5f5;
padding: 16px;
border-radius: 2px;
}

details[open] .details_content{
animation: .8s details_content ease;
}

@keyframes details_content {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}

今のところ、detailsタグ自体にはアニメーションを掛けられないので、中にdivを配置してそこにアニメーションを掛けることになります。

summaryをクリックしてコンテンツを閉じると、高さがすぐ0になってしまうので、閉じるときのアニメーションを付けることはできません。閉じるアニメーションがなくても不自然にならないよう、アニメーションの装飾は最低限に留めたほうがいいかもしれません。

まとめ

detailsタグはHTMLのみでコンテンツの開閉という動きを、WEBサイトにつけることができるので魅力的ですね。

HTMLでマークアップをする以上意味を考えなければならないので、単にコンテンツを開閉させたいのであれば、JavaScriptで実装する方が手っ取り早いと思います。