Lightbox personalizado

Creando nuestro propio efecto Lightbox para imágenes

Tipos de Alojamiento web

Ver demo Descargar
código

Lightbox es el efecto de oscurecer todo el contenido en nuestra interfaz a excepción
de un único elemento que se busca destacar por sobre las demás cosas.

Maquetando la estructura base

Antes de ponernos a generar código HTML desde Javascript nos viene bien primero escribir a mano la
estructura para tenerla de referéncia.

<div class="liwindow-container">
<div class="lilightbox">
<button type="button" class="lilightbox-close">×</button>
<img src="https://picsum.photos/id/11/760/360">
</div>
</div>

Usaremos un contenedor general (.liwindow-container) que sera el que oculte todo el
demás contenido de la web mostrandose semiopaco.

Dentro pondremos el contenedor (.lilightbox) para los elementos de nuestro lightbox.

Primero ponemos el botón de cierre (.lilightbox-close) y después la imagen que
buscamos resaltar por sobre el contenido.

Aplicando los estilos

/* -- liwindow -- */
.liwindow-container *,
.liwindow-container *::after,
.liwindow-container *::before {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.liwindow-container {
position: fixed;
top: 0;
left: 0;
background: rgba(0, 0, 0, 0.5);
width: 100%;
height: 100%;
z-index: 200;
}
.liwindow-hide{
display: none;
}
/* -- lilightbox -- */
.lilightbox img {
max-width: 100%;
margin: 20px auto;
display: block;
}
.lilightbox {
width: 100%;
height: 100%;
overflow: auto;
}
.lilightbox .lilightbox-close {
font-size: 1.55rem;
position: absolute;
left: 0;
top: 0;
color: #e0e0e0;
text-shadow: 0px 1px 2px #333;
padding: 20px;
display: inline-block;
font-weight: bold;
background-color: transparent;
border: none;
transition: 0.3s all;
}
.lilightbox .lilightbox-close:hover {
color: #ffc107;
background-color: transparent;
}

Aplicando estos estilos CSS anteriores a nuestra estructura HTML tendríamos la siguiente apariencia:

Tipos de Alojamiento web

Definiendo las clases y métodos

/* -- Clase principal para el modal window -- */
class liwindow {
constructor(html)

show()

hide()

setContent()

remove()
}
/* -- Image Lightbox -- */
class lilightbox {
}

Partiremos de una clase general con los métodos necesarios para el funcionamiento de nuestro
lightbox.

Desde nuestra clase lightbox crearemos una instancia por cada imagen requerida.

Lógica de la clase principal

/* -- Ventana para lightbox y modal dialogs -- */
class liwindow{
constructor(html){
/* Creamos el contenedor principal del lightbox */
this.container = document.createElement('div');
this.container.setAttribute('class', 'liwindow-container liwindow-hide');
this.container.addEventListener('click', this.hide);
document.body.appendChild(this.container);

/* Añadimos el html proporcionado */
if (html != null) this.setContent(html);
}

/* Metodo para abrir lightbox */
show = ()=> {
this.container.classList.remove('liwindow-hide');
document.body.style.overflow = 'hidden';
}

/* Metodo para cerrar lightbox */
hide = ()=>{
this.container.classList.add('liwindow-hide');
document.body.style.overflow = 'auto';
}

/* Metodo para remover el lightbox y su contenido del html */
remove = () => document.body.removeChild(this.container);

/* Metodo para agregar contenido al lightbox */
setContent = cont => this.container.innerHTML = cont;
}
Nota: En lugar de métodos de clase se están usando arrow functions
asignadas a propiedades de clase, funcionaran igual que métodos normales, con el añadido de que
cualquier uso de this dentro de ese contexto siempre hace referencia a la clase, lo que es
realmente necesario para poder llamar las propiedades de nuestra clase desde los
addEventListener que usaremos.

Lógica de la clase lilightbox

/* -- Image Lightbox -- */
class lilightbox{
constructor(sel) {
document.querySelectorAll(sel).forEach(t=>{
t.addEventListener("click", e=>{
e.preventDefault();
const cont = `
<div class="lilightbox">
<button type="button" class="lilightbox-close">×</button>
<img src="${t.rel}">
</div>
`;
const liw = new liwindow(cont);
liw.container.querySelector('.lilightbox').addEventListener('click', e=>e.stopPropagation());
liw.container.querySelector('.lilightbox-close').addEventListener('click', liw.hide);
liw.show();
});
});
}
}

Usando un selector buscaremos en el documento todos los elementos a los que aplicaremos el efecto
lightbox, la unica condición sera que tengan el atributo rel, de donde obtendremos
la ruta de la imagen a cargar.

Con forEach() recorreremos todos nuestros elementos para añadirles el efecto al hacer click.

Definimos el HTML interno del lightbox y lo pasaremos como argumento al instanciar la clase
principal.

Ya que se haya insertado el HTML, al botón que ahí mismo definimos le enlazamos el funcionamiento del
método hide().

Modo de uso

Solo debemos insertar el código CSS y JS en nuestro documento HTML para empezar a aplicar el efecto
lightbox.

const myimglb = new lilightbox('.mylbselector');

Podemos usar imágenes pequeñas que enlacen a imágenes mas grandes y que sean estas las que se
muestren en el efecto lightbox:

<a class="mylbselector" href="https://picsum.photos/id/1/760/360" rel="https://picsum.photos/id/1/760/360"><img src="https://picsum.photos/id/1/400/300"></a>
<a class="mylbselector" href="https://picsum.photos/id/11/760/360" rel="https://picsum.photos/id/11/760/360"><img src="https://picsum.photos/id/11/400/300"></a>
<a class="mylbselector" href="https://picsum.photos/id/12/760/360" rel="https://picsum.photos/id/12/760/360"><img src="https://picsum.photos/id/12/400/300"></a>

A continuación mostrare el script final y ejemplos de funcionamiento, todo esto estará en Codepen por
si deseas exportarlo e incluso modificarlo.

Código final y resultado

See the Pen
Custom Img Lightbox Vanilla JS
by Ulises Rendon (@fdulises)
on CodePen.