HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Images</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<main>
<div class="images-container">
<ul>
<li><img src="https://i.ibb.co/cYRcXn1/1.jpg" loading="lazy" alt="1"></li>
<li><img src="https://i.ibb.co/9ySScx2/2.jpg" loading="lazy" alt="2"></li>
<li><img src="https://i.ibb.co/sWT87XB/3.jpg" loading="lazy" alt="3"></li>
<li><img src="https://i.ibb.co/FY5GPq4/4.jpg" loading="lazy" alt="4"></li>
<li><img src="https://i.ibb.co/t3p4SdP/5.jpg" loading="lazy" alt="5"></li>
<li><img src="https://i.ibb.co/VvsKQH8/6.jpg" loading="lazy" alt="6"></li>
<li><img src="https://i.ibb.co/741RwFF/7.jpg" loading="lazy" alt="7"></li>
<li><img src="https://i.ibb.co/PWnjq99/8.jpg" loading="lazy" alt="8"></li>
<li><img src="https://i.ibb.co/z8WJWb8/9.jpg" loading="lazy" alt="9"></li>
<li><img src="https://i.ibb.co/XtzxQtj/10.jpg" loading="lazy" alt="10"></li>
<li><img src="https://i.ibb.co/kGj8pN8/11.jpg" loading="lazy" alt="11"></li>
<li><img src="https://i.ibb.co/3CjfPQ2/12.jpg" loading="lazy" alt="12"></li>
<li><img src="https://i.ibb.co/MZ4N320/13.jpg" loading="lazy" alt="13"></li>
<li><img src="https://i.ibb.co/NmYCyYn/14.jpg" loading="lazy" alt="14"></li>
<li><img src="https://i.ibb.co/QDQ5LB8/15.jpg" loading="lazy" alt="15"></li>
<li><img src="https://i.ibb.co/xXBFBvn/16.jpg" loading="lazy" alt="16"></li>
<li><img src="https://i.ibb.co/zHgz5t0/17.jpg" loading="lazy" alt="17"></li>
<li><img src="https://i.ibb.co/ccydMHP/18.jpg" loading="lazy" alt="18"></li>
<li><img src="https://i.ibb.co/yg4X3xr/19.jpg" loading="lazy" alt="19"></li>
<li><img src="https://i.ibb.co/4S6WLw2/20.png" loading="lazy" alt="20"></li>
<li><img src="https://i.ibb.co/TYQy5YK/21.jpg" loading="lazy" alt="21"></li>
</ul>
</div>
</main>
<script defer src="js/gall.js"></script>
</body>
</html>
CSS
body {
margin: 0;
}
main {
max-width: 900px;
margin: 0 auto;
}
.images-container ul {
list-style: none;
font-size: 0;
width: 100%;
padding: 0;
margin: 0;
}
.images-container li {
display: inline-block;
font-size: initial;
border: 2px solid #fff;
margin: 0.25em;
overflow: hidden;
}
.images-container {
display: block;
margin: 0 auto;
text-align: center;
padding: 0.25em;
}
.images-container img {
object-fit: cover;
cursor: pointer;
display: block;
max-width: 250px;
object-position: top;
height: 10em;
width: 100%;
background: #fafafa;
}
.images-container img, .imag img{
border-radius: 3px;
}
.imag {
width: 100%;
height: 100%;
width: 100vw;
height: 100vh;
background: #000;
position: fixed;
top: 0;
transform: scale(1);
transition: .2s transform, .2s opacity, .2s visibility;
display: block;
text-align: center;
z-index: 9999;
user-select: none;
}
.head {
min-height: 48px;
width: 100%;
position: relative;
z-index: 1;
font-family: Arial, Helvetica, sans-serif;
}
.iner {
position: absolute;
height: 100%;
width: 100%;
top: 0;
}
.left {
left: 0;
text-align: left;
}
.alts {
color: #eee;
line-height: 48px;
margin: 0 auto;
}
.rigt {
right: 0;
text-align: right;
}
.clos,
.left,
.rigt {
position: absolute;
cursor: pointer;
color: #fff;
min-width: 48px;
min-height: 48px;
display: block;
line-height: 48px;
top: 0;
}
.clos {
right: 0;
top: 0;
}
.left,
.rigt {
width: 30%;
height: 100%;
}
.clos::after,
.left::after,
.rigt::after {
display: block;
font-size: 48px;
top: 50%;
position: absolute;
transform: scale(.9);
font-family: Times New Roman, serif;
/*! color: #aaa; */
}
.clos:hover:after,
.left:hover:after,
.rigt:hover:after {
transform: scale(1);
color: #fff;
}
.clos:active:after,
.left:active:after,
.rigt:active:after {
color: #777;
}
.rigt::after,
.left::after {
margin-top: -24px;
padding: 0 10px;
}
.left::after {
content: '\2329';
left: 0;
}
.rigt::after {
content: '\232a';
right: 0;
}
.clos::after {
content: '\00D7';
top: 0;
width: 100%;
left: 0;
font-family: sans-serif;
font-weight: 300;
}
.cent {
width: 100%;
height: 100%;
position: relative;
overflow: hidden;
user-select: none;
}
.cent img {
object-fit: scale-down;
pointer-events: none;
max-height: 100%;
max-width: 100%;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
transition: .5s;
opacity: 1;
}
.hidden {
transform: scale(0);
opacity: 0;
visibility: hidden;
pointer-events: none;
}
@media screen and (max-width: 480px) {
.images-container img {
max-width: 480px;
height: auto;
}
}
JAVASCRIPT
;
(function (w, d) {
'use strict'
class CreateUI {
constructor (containers) {
this.container = d.getElementsByClassName(containers)
this.image = null
this.indexOfImage = 0
this.isActive = false
this.frag = d.createDocumentFragment()
this.imag = d.createElement('div')
this.cent = d.createElement('div')
this.left = d.createElement('div')
this.rigt = d.createElement('div')
this.iner = d.createElement('div')
this.clos = d.createElement('div')
this.head = d.createElement('div')
this.alts = d.createElement('div')
this.imgs = d.createElement('img')
this.imgs.src = 'data:,'
this.imgs.setAttribute('alt', '')
this.imag.appendChild(this.head).appendChild(this.clos)
this.imag.appendChild(this.iner).appendChild(this.cent).appendChild(this.imgs)
this.head.appendChild(this.alts)
this.imag.appendChild(this.rigt)
this.imag.appendChild(this.left)
this.frag.appendChild(this.imag)
this.alts.className = 'alts'
this.head.className = 'head'
this.iner.className = 'iner'
this.clos.className = 'clos'
this.rigt.className = 'rigt'
this.left.className = 'left'
this.cent.className = 'cent'
this.imag.className = 'imag hidden'
d.body.appendChild(this.frag)
this.imagesContainersArray = [] // get all images containers
this.imagesArray = [] // get all images
for (let i = this.container.length; i--;) {
this.imagesContainersArray.push(this.container[i])
}
for (let i = this.imagesContainersArray.length; i--;) {
const img = this.imagesContainersArray[i].getElementsByTagName('img')
for (let j = 0; j < img.length; j++) {
this.imagesArray.push(img[j])
}
}
}
lefts () {
if (this.indexOfImage > 0) {
this.indexOfImage--
this.show()
}
}
right () {
if (this.indexOfImage + 1 < this.imagesArray.length) {
this.indexOfImage++
this.show()
}
}
close () {
this.isActive = false
d.body.style.overflow = 'visible'
this.imag.className = 'imag hidden'
}
show () {
if (!this.isActive) {
this.imag.className = 'imag'
this.isActive = true
w.setTimeout(() => {
d.body.style.overflow = 'hidden'
}, 150) // delay for body overflow (animation fadeIn/out time + 50ms)
}
this.image = this.imagesArray[this.indexOfImage]
this.left.className = this.indexOfImage === 0 ? 'hidden' : 'left'
this.rigt.className = this.indexOfImage + 1 === this.imagesArray.length ? 'hidden' : 'rigt'
this.alts.innerHTML = this.image.getAttribute('alt') + ' image:' + Number(this.indexOfImage + 1) + '/' + this.imagesArray.length
this.imgs.src = this.image.src
}
}
d.addEventListener('DOMContentLoaded', () => {
const images = new CreateUI('images-container') // create UI for gallery slides after all DOM Loaded
d.addEventListener('click', (e) => {
e.preventDefault() // prevent for default browser actions
e.stopPropagation()
switch (e.target.className || e.target.tagName) {
case 'IMG':
images.indexOfImage = images.imagesArray.indexOf(e.target) // set image index on click
images.show()
break
case 'rigt':
images.right()
break
case 'left':
images.lefts()
break
case 'clos':
images.close()
break
}
return false
})
// add event on window listen for keys
w.addEventListener('keyup', (e) => {
if (!images.isActive || e.isComposing || e.key === 229) return
e.key === 'ArrowLeft' && images.lefts()
e.key === 'ArrowRight' && images.right()
e.key === 'Escape' && images.close()
})
})
// w.imagges = CreateUI
})(window, document)