Hi I have a pure css carousel lightbox which is working fine. However, I would like to do three things: -when i press ESC it simulates clicking the close button; -when pressing left and right it simulates clicking the left/right button; and, -when i click off the image, the lightbox closes. Ideally it would be great if this can be done in pure css. Here is a fiddle: https://jsfiddle.net/postcolonialboy/Lxa2pgrw/3/ (If not, willing to accept jquery ) Here is what I have: <span class="feature_category active" id="A"> <div class="feature_box_wrapper"><a href="#groys1">Link</a></div> <div class="feature_box_wrapper"><a href="#groys2">Link</a></div> <div class="feature_box_wrapper"><a href="#groys3">Link</a></div> <div class="feature_box_wrapper"><a href="#groys4">Link</a></div> <div class="feature_box_wrapper"><a href="#groys5">Link</a></div> </span> <div class="lightbox"> <!-- Groys --> <div class="lightbox__slide" id="groys1"> <a href="#_" class="btn btn--close"></a> <a href="#groys5" class="btn btn--left"></a> <a href="#groys2" class="btn btn--right"></a> <img src="https://picsum.photos/seed/picsum/800/450" alt="Screenshot of your site"> </div> <div class="lightbox__slide" id="groys2"> <a href="#_" class="btn btn--close"></a> <a href="#groys1" class="btn btn--left"></a> <a href="#groys3" class="btn btn--right"></a> <img src="https://picsum.photos/seed/picsum/800/450" alt="Screenshot of your site"> </div> <div class="lightbox__slide" id="groys3"> <a href="#_" class="btn btn--close"></a> <a href="#groys2" class="btn btn--left"></a> <a href="#groys4" class="btn btn--right"></a> <img src="https://picsum.photos/seed/picsum/800/450" alt="Screenshot of your site"> </div> <div class="lightbox__slide" id="groys4"> <a href="#_" class="btn btn--close"></a> <a href="#groys3" class="btn btn--left"></a> <a href="#groys5" class="btn btn--right"></a> <img src="https://picsum.photos/seed/picsum/800/450" alt="Screenshot of your site"> </div> <div class="lightbox__slide" id="groys5"> <a href="#_" class="btn btn--close"></a> <a href="#groys4" class="btn btn--left"></a> <a href="#groys1" class="btn btn--right"></a> <img src="https://picsum.photos/seed/picsum/800/450" alt="Screenshot of your site"> </div> <div class="lightbox__bg"></div><!-- Close --> </div><!-- Close Lightbox --> HTML: .lightbox__slide img { position: absolute; z-index: 30; max-width: 90%; max-height: 80%; top: 50%; left: 50%; transform: translate(-50%, -50%); animation-name: hide; animation-duration: 0.5s; animation-iteration-count: 1; animation-direction: linear; animation-fill-mode: forwards; } .lightbox__slide:target .btn { display: block; } .lightbox__slide:target img { opacity: 0; animation-name: show; animation-duration: 0.5s; animation-iteration-count: 1; animation-direction: linear; animation-fill-mode: forwards; } .lightbox__slide:target~.lightbox__bg { position: relative; background: white; opacity: 0.6; top: 0; left: 0; width: 100%; height: 100%; z-index: 1; } @-webkit-keyframes show { 0% { opacity: 0; } 100% { opacity: 1; } } @-webkit-keyframes hide { 0% { opacity: 1; } 100% { opacity: 0; } } .btn { position: absolute; z-index: 20; display: none; transition: all 0.2s; width: 40px; height: 40px; margin: -20px 0 0 -20px; text-align: center; line-height: 40px; text-decoration: none; color: black; } .btn:hover { background: rgba(255, 255, 255, 0.8); } .btn--close { top: 40px; right: 20px; } .btn--close:after { content: '\2715'; } .btn--left { top: 50%; left: 40px; } .btn--left:after { content: '⯇'; } .btn--right { top: 50%; right: 20px; } .btn--right:after { content: '⯈'; } Code (CSS):
I'd suggest using pure javascript (non-jQuery) carousel sliders. They work perfect in most browsers and on mobile devices. css only sliders will not work as you expect them to on ipads and cell phones. Don't create a headache for yourself, go for a javascript slider. PS @deathshadow has pure javascript sliders. Maybe he can point you to the right link on his site.
ok thanks for the advice, i remember @deathshadow grilling me a number of times for using jquery/JS when CSS does a perfectly good job!
Really the moment you want keyboard interaction, you're looking at adding scripting. Whilst CSS can save you a LOT of the grunt work in terms of show/hide, there are some things you do still need scripting to handle. Now that said, first thing I'd suggest is fixing your semantics. You have a LIST of links in no particular order, why is that in a SPAN with invalid "div for nothing" inside it instead of UL/LI? Since you don't have nesting of DIV inside each slide, why do they need a class. If all the anchors are getting the same class, why do any of them need classes? So first, let's skim off the dross. <ul class="lightbox_menu"> <li><a href="#groys1">Link</a></li> <li><a href="#groys2">Link</a></li> <li><a href="#groys3">Link</a></li> <li><a href="#groys4">Link</a></li> <li><a href="#groys5">Link</a></li> </ul> <div class="lightboxes"> <div id="groys1"> <a href="#" class="close"></a> <a href="#groys5" class="prev"></a> <a href="#groys2" class="next"></a> <img src="https://picsum.photos/seed/picsum/800/450" alt="Screenshot of your site" > </div> <div id="groys2"> <a href="#" class="close"></a> <a href="#groys1" class="prev"></a> <a href="#groys3" class="next"></a> <img src="https://picsum.photos/seed/picsum/800/450" alt="Screenshot of your site" > </div> <div id="groys3"> <a href="#" class="close"></a> <a href="#groys2" class="prev"></a> <a href="#groys4" class="next"></a> <img src="https://picsum.photos/seed/picsum/800/450" alt="Screenshot of your site" > </div> <div id="groys4"> <a href="#" class="close"></a> <a href="#groys3" class="prev"></a> <a href="#groys5" class="next"></a> <img src="https://picsum.photos/seed/picsum/800/450" alt="Screenshot of your site" > </div> <div id="groys5"> <a href="#" class="close"></a> <a href="#groys4" class="prev"></a> <a href="#groys1" class="next"></a> <img src="https://picsum.photos/seed/picsum/800/450" alt="Screenshot of your site" > </div> <!-- .lightBoxes --></div> Code (markup): Then for the CSS something more along the lines of (taking some artistic liberties) .lightboxes > div, .lightboxes .close { top:0; width:100%; height:100%; } .lightboxes > div { box-sizing:border-box; display:flex; align-items:center; justify-content:center; position:fixed; left:-100vw; padding:3em; opacity:0; transition:left 0s 0.5s, opacity 0.5s; background:rgba(0,128,255,0.7); box-shadow:inset 0 0 255px rgba(0,0,64,0.7); } .lightboxes > div:target { left:0; opacity:1; transition:left 0s, opacity 0.5s; } .lightboxes a { text-decoration:none; color:#000; transition:color 0.5s; } .lightboxes a:focus, .lightboxes a:hover { color:#0FF; } .lightboxes a:before { position:absolute; font-size:2em; line-height:1em; } .lightboxes .close { position:absolute; left:0; } .lightboxes .close:before { position:absolute; top:0.25em; right:0.25em; content:"\1F5D9"; } .lightboxes .prev:before, .lightboxes .next:before { width:1.5em; top:50%; text-align:center; margin-top:-0.5em; } .lightboxes .prev:before { left:0; content:"\25C0"; } .lightboxes .next:before { right:0; content:"\25BA"; } .lightboxes img { max-width:100%; max-height:100%; box-shadow:0 0 3em rgba(0,0,128,0.7); } Code (markup): Now the scripting doesn't have to get too complex. We just need to intercept keystrokes at the document level, then look at the hash to see what's focused. If the focused element's parent is a .lightboxes, check the keystroke and grab the appropriate child anchor and perform .click() on it. Naturally checks for if said elements exist and resolve should be done across the entire process. (function(d, w) { // remember, arrows don't trigger keypress :( d.addEventListener('keydown', lightBoxCheck, false); function lightBoxCheck(e) { var hash = w.location.hash ? w.location.hash.substr(1) : ''; if (!hash) return; var target = d.getElementById(hash), method; if ( target && target.parentNode.className == 'lightboxes' ) { switch(e.keyCode) { case 27: method = '.close'; break; case 37: method = '.prev'; break; case 39: method = '.next'; break; default: // short circuit out return; } if (target = target.querySelector(method)) { target.click(); e.preventDefault(); } } } })(document, window); Code (markup): ... and of course it's in a SIF (aka IIFE) to isolate its scope so other scripts don't interfere. Also notice that if we intercept the keystroke we cancel the event preventing further propagation, but allow other keystrokes to continue about their business so other scripts if present (or browser functionality) can still work. Live demo: https://cutcodedown.com/for_others/7643sfsag6/lightbox/ Not significantly far off from what you wrote, and the scripting is built to ENHANCE the page instead of supplanting functionality. That's the billion dollar trick is that scripting off it's still usable for touch, mouse, and even conventional tab style keyboard navigation -- but the tiny bit of scripting enhances it with keyboard input.
It is dynamic because the hash and :target are how the markup works without the scripting. It's the fastest and easiest way to get the current slide without having the script seize full control of how it works. What would you suggest instead / where would you grab the current slide from?
GetAttribute on what? you need an element to get the attribute OF first. The slideshow itself works WITHOUT JavaScript by using hashes... the current hash and the :target is the only indication of what slide is current... So how would "getAttribute" get you the currently :target element?
Define "isn't working" -- as in keyboard (which is what the scripting provides) or the normal mouse interface? Also what do names have to do with anything? Also define what you mean by "yours".
OK, I don't want to be grinded on this. I use getAttribute to get the image identification out of the link like you do with the hash and substr and just curious about this. By using substr, it has to fall into a specific length. If it worked, it just works.
From what? Could you provide a code example of what you mean as I AM interested in other ways of doing things, and I genuinely have ZERO cluie what you're talking about. ... and using substr all I'm doing is removing the first character, which is always a # so, just what are you even on about?
.lightbox__slide img { position: absolute; z-index: 30; max-width: 90%; max-height: 80%; top: 50%; left: 50%; transform: translate(-50%, -50%); animation-name: hide; animation-duration: 0.5s; animation-iteration-count: 1; animation-direction: linear; animation-fill-mode: forwards; } .lightbox__slide:target .btn { display: block; } .lightbox__slide:target img { opacity: 0; animation-name: show; animation-duration: 0.5s; animation-iteration-count: 1; animation-direction: linear; animation-fill-mode: forwards; } .lightbox__slide:target~.lightbox__bg { position: relative; background: white; opacity: 0.6; top: 0; left: 0; width: 100%; height: 100%; z-index: 1; } @-webkit-keyframes show { 0% { opacity: 0; } 100% { opacity: 1; } } @-webkit-keyframes hide { 0% { opacity: 1; } 100% { opacity: 0; } } .btn { position: absolute; z-index: 20; display: none; transition: all 0.2s; width: 40px; height: 40px; margin: -20px 0 0 -20px; text-align: center; line-height: 40px; text-decoration: none; color: black; } .btn:hover { background: rgba(255, 255, 255, 0.8); } .btn--close { top: 40px; right: 20px; } .btn--close:after { content: '\2715'; } .btn--left { top: 50%; left: 40px; } .btn--left:after { content: '⯇'; } .btn--right { top: 50%; right: 20px; } .btn--right:after { content: '⯈'; }