I’m working on a website where I only have control over (part of) the CSS code. I can’t add JavaScript code, and I also can’t change the HTML of webpages (because it comes from a Markdown compiler, and although Markdown supports inserting HTML tags, the content is written without them to keep the HTML abstracted).
Some webpages have images. These appear as plain (generated) <img>
tags. I want to allow the user to "click to enlarge" these images. This functionality is apparently called a lightbox.
So, I want to support this for all these plain <img>
tags in pure CSS and without adding extra HTML. I’ve found many solutions, but none satisfy this specification:
- A lot of them use jQuery, e.g. all of these examples. A lot of what I’ve found is actually meant for galleries, like this one which uses JavaScript. Same for this entire library.
- This thread just enlarges the image on hovering, rather than isolating it. This thread doesn’t require any extra HTML, but needs JavaScript. This thread is the same. This thread has a similar title to mine, but is actually completely different from what I want. This thread is about swapping images, and the proposed solution is to use an
<input>
tag, which I can’t. - The best one I’ve found is this Codepen, but it requires an
<a>
anchor tag around each<img>
tag and apparently an additional pair of tags for the lightbox itself. The reason is that the<a>
tag can change the fragment of the URL, and subsequently CSS can detect that change using:target
. Same for this website.
I don’t need any gallery functionality with buttons. I literally just need any <img>
tag to be clickable so it appears (perhaps with a zoom transition) in the center of the screen with a dimmed background, and clicking anywhere restores the page to normal.
Edit: Although some of the above threads don’t provide any code in the question themselves and I described the givens on my end (which is just <img src="..."/>
), here is a minimised version of that last Codepen:
* body {
background-color: white;
}
.container {
width: 100%;
height: 100%;
}
.trans {
transition: all 1s ease;
-moz-transition: all 1s ease;
-ms-transition: all 1s ease;
-o-transition: all 1s ease;
-webkit-transition: all 1s ease;
}
.top {
display: flex;
width: 80vw;
height: 80vh;
margin-top: 10vh;
margin-left: auto;
margin-right: auto;
margin-bottom: 10vh;
}
.top ul {
list-style: none;
width: 100%;
height: 100%;
z-index: 1;
box-sizing: border-box;
}
.top ul li {
position: relative;
float: left;
width: 25%;
height: 25%;
overflow: hidden;
}
.top ul li::before {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: #000;
content: '';
color: white;
opacity: 0.4;
text-align: center;
box-sizing: border-box;
pointer-events: none;
transition: all 0.5s ease;
-moz-transition: all 0.5s ease;
-ms-transition: all 0.5s ease;
-o-transition: all 0.5s ease;
-webkit-transition: all 0.5s ease;
}
.top ul li:hover::before {
opacity: 0;
background-color: rgba(0,0,0,0.90);
}
.top ul li img {
width: 100%;
height: auto;
overflow: hidden;
}
.lightbox {
position: fixed;
width: 100%;
height: 100%;
text-align: center;
top: 0;
left: 0;
background-color: rgba(0,0,0,0.75);
z-index: 999;
opacity: 0;
pointer-events: none;
}
.lightbox img {
max-width: 90%;
max-height: 80%;
position: relative;
top: -100%;
/* Transition */
transition: all 1s ease;
-moz-transition: all 1s ease;
-ms-transition: all 1s ease;
-o-transition: all 1s ease;
-webkit-transition: all 1s ease;
}
.lightbox:target {
outline: none;
top: 0;
opacity: 1;
pointer-events: auto;
transition: all 1.2s ease;
-moz-transition: all 1.2s ease;
-ms-transition: all 1.2s ease;
-o-transition: all 1.2s ease;
-webkit-transition: all 1.2s ease;
}
.lightbox:target img {
top: 0;
top: 50%;
transform: translateY(-50%);
-moz-transform: translateY(-50%);
-ms-transform: translateY(-50%);
-o-transform: translateY(-50%);
-webkit-transform: translateY(-50%);
}
<div class="container">
<div class="top">
<ul>
<li><a href="#img_1"><img src="https://image.freepik.com/free-photo/road-curve-landscape_426-19324358.jpg"></a></li>
</ul>
<a href="#_1" class="lightbox trans" id="img_1"><img src="https://image.freepik.com/free-photo/road-curve-landscape_426-19324358.jpg"></a>
</div>
</div>
2
Answers
You don’t want to modify the DOM, and want to handle clicks, CSS simply can’t do that, it will just be hacks with
:target
or:active
.You have to either use JavaScript, or modify the DOM to use the
details
element, who has anopen
state.As stated in the comment, here is a way to achieve this click/close effect with only HTML/CSS, but for that we have to use the
details
element.If you add
tabindex="0"
to the<img>
, you can apply:focus
: