Neuralpin Logo

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.

Ulises Rendón

Desarrollador de Software

Es un programador apasionado por la ciencia y la tecnología, vive en la ciudad de México y fundó Neuralpin con el objetivo de divulgar conocimiento sobre tecnología y desarrollo.