Stunning Image Gallery with Hover Effects & Animated Lightbox – Elementor Tutorial

So if you follow along in the video, I refer to this blog post for you to enter code at certain point into the HTML widget, so below is everything you will need!

The Following are the css class names I used in the tutorial:

				
					reboot-card-effect-section

reboot-card-effect-heading

reboot-card-effect-info

reboot-card-effect-close

reboot-card-effect


				
			

The Following code goes into the HTML widget:

				
					<style>
.reboot-card-effect-section{
    --big-width: 500px;
    --big-height: 650px;
    --rotation-diff: 5deg;
    --translate-diff: 120px;
    --transition: 0.3;
    --init-transition: 1.5;
    --big-transition: 0.5;
    --actual-height: var(--big-height);
}
.reboot-card-effect-section .reboot-card-effect{
    top: calc(-1px*var(--extra-height,0));
}
.reboot-card-effect-section .reboot-card-effect:before{
    position: fixed;
    height: 100vh;
    width: 100vw;
    inset: 0;
    z-index: 1;
    backdrop-filter: blur(20px);
    transition: all calc(1s*var(--big-transition)) ease-in-out;
}
.reboot-card-effect-section:not(.active) .reboot-card-effect:before{
    pointer-events: none;
}
.reboot-card-effect-section:not(.popup) .reboot-card-effect:before{
    opacity: 0;
}
.reboot-card-effect-section:not(.init) .reboot-card-effect > .e-con,
.reboot-card-effect-section:not(.init) .reboot-card-effect > .e-container{
    opacity: 0;
    filter: blur(20px) saturate(0%);
    pointer-events: none;
}
.reboot-card-effect-section .reboot-card-effect > .e-con,
.reboot-card-effect-section .reboot-card-effect > .e-container{
    transform-origin: 50% 100%;
    cursor: pointer;
    will-change: opacity, filter;
}
body.elementor-editor-active .reboot-card-effect-section .reboot-card-effect > .e-con,
body.elementor-editor-active .reboot-card-effect-section .reboot-card-effect > .e-container,
body.elementor-editor-preview .reboot-card-effect-section .reboot-card-effect > .e-con,
body.elementor-editor-preview .reboot-card-effect-section .reboot-card-effect > .e-container{
    opacity: 1;
    filter: none;
    pointer-events: initial;
}
.reboot-card-effect-section:not(.init) .reboot-card-effect .e-con .e-con,
.reboot-card-effect-section:not(.init) .reboot-card-effect .e-container .e-container{
    box-shadow: none;
}
.reboot-card-effect-section .reboot-card-effect .e-con .e-con,
.reboot-card-effect-section .reboot-card-effect .e-container .e-container{
    will-change: box-shadow;
    height: var(--min-height, 320px);
    overflow: hidden;
    transition: all calc(1s*var(--transition)) ease-in-out;
}
.reboot-card-effect-section .reboot-card-effect .e-con .e-con:before,
.reboot-card-effect-section .reboot-card-effect .e-container .e-container:before{
    transform: all calc(1s*var(--big-transition)) ease-in-out;
}
.reboot-card-effect-section .reboot-card-effect .e-con.fixed,
.reboot-card-effect-section .reboot-card-effect .e-container.fixed{
    position: fixed;
    top: calc(1px*var(--card-y,0));
    left: calc(1px*var(--card-x,0));
    z-index: 10;
    transition: all calc(1s*var(--big-transition)) ease-in-out;
}
.reboot-card-effect-section .reboot-card-effect .e-con.fixed .e-con,
.reboot-card-effect-section .reboot-card-effect .e-container.fixed .e-container{
    transition: all calc(1s*var(--big-transition)) ease-in-out;
}
.reboot-card-effect-section .reboot-card-effect .e-con.big .e-con,
.reboot-card-effect-section .reboot-card-effect .e-container.big .e-container{
    height: var(--actual-height);
    width: var(--big-width);
}
.reboot-card-effect-section .reboot-card-effect .e-con .elementor-widget,
.reboot-card-effect-section .reboot-card-effect .e-container .elementor-widget{
    overflow: hidden;
}
.reboot-card-effect-section .reboot-card-effect .e-con.big .elementor-widget > *,
.reboot-card-effect-section .reboot-card-effect .e-container.big .elementor-widget > *{
    transform: translateY(0%);
    transition: all 0.5s ease-in-out calc(1s*var(--big-transition));
}
.reboot-card-effect-section .reboot-card-effect-heading{
    margin-bottom: calc(1px*var(--extra-height,0)) !important;
}
.reboot-card-effect-section .reboot-card-effect-heading .elementor-widget-container{
    overflow: hidden;
}
.reboot-card-effect-section:not(.init) .reboot-card-effect-heading .elementor-heading-title{
    opacity: 0;
    pointer-events: none;
    transform: translateY(100%);
}
.reboot-card-effect-section .reboot-card-effect-heading .elementor-heading-title{
    transform: translateY(0%);
    transition: all 0.7s ease-in-out calc(1s*var(--init-transition) - 0.8s);
}
body.elementor-editor-active .reboot-card-effect-section .reboot-card-effect-heading .elementor-heading-title,
body.elementor-editor-preview .reboot-card-effect-section .reboot-card-effect-heading .elementor-heading-title{
    opacity: 1;
    pointer-events: initial;
    transform: translateY(0%);
}
.reboot-card-effect-section:not(.popup) .reboot-card-effect-close{
    opacity: 0;
    pointer-events: none;
    transition: all 0.5s ease-in-out;
}
.reboot-card-effect-section .reboot-card-effect-close{
    cursor: pointer;
    transition: all 0.5s ease-in-out calc(1s*var(--big-transition));
}
.reboot-card-effect-section .reboot-card-effect-close .elementor-icon{
    display: block;
}
.reboot-card-effect-section .reboot-card-effect-close i:before,
.reboot-card-effect-section .reboot-card-effect-close i:after{
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: 0.6em;
    height: 0.03em;
    background: currentColor;
    transform: translate(-50%,-50%) rotate(45deg);
}
.reboot-card-effect-section .reboot-card-effect-close i:after{
    transform: translate(-50%,-50%) rotate(-45deg);
}
.reboot-card-effect-section .reboot-card-effect-info{
    transition: all 0.1s linear;
    pointer-events: none;
}
.reboot-card-effect-section .reboot-card-effect-info:not(.showing){
    opacity: 0;
}
.reboot-card-effect-section .reboot-card-effect-info .elementor-button{
    width: 100%;
    height: var(--container-widget-width, 90px);
    display: flex;
    align-items: center;
}
.reboot-card-effect-section .reboot-card-effect-info .elementor-button-text{
    display: flex;
    align-items: center;
    justify-content: center;
}

@media (max-width: 1024px){
.reboot-card-effect-section{
    --big-width: 380px;
    --big-height: 500px;
    --rotation-diff: 15deg;
    --translate-diff: 5px;
}
}

@media (min-width: 768px){
body.fixed{
    overflow: hidden;
}
.reboot-card-effect-section .reboot-card-effect:before{
    content: "";
}
.reboot-card-effect-section.init .reboot-card-effect > .e-con,
.reboot-card-effect-section.init .reboot-card-effect > .e-container{
    transform: rotate(calc(var(--index) * var(--rotation-diff))) translate(calc(var(--translate-diff)*var(--index)), 0);
    animation: reboot-card-initialization calc(1s*var(--init-transition)) ease-in-out;
}
@keyframes reboot-card-initialization{
0%{ transform: none; opacity: 0; filter: blur(20px) saturate(0%);}
100%{ transform: rotate(calc(var(--index)* var(--rotation-diff))) translate(calc(var(--translate-diff)* var(--index)), 0); }
}
@-webkit-keyframes reboot-card-initialization {
0%{ transform: none; opacity: 0; filter: blur(20px) saturate(0%);}
100%{ transform: rotate(calc(var(--index)* var(--rotation-diff))) translate(calc(var(--translate-diff)* var(--index)), 0); }
}
@-moz-keyframes reboot-card-initialization {
0%{ transform: none; opacity: 0; filter: blur(20px) saturate(0%);}
100%{ transform: rotate(calc(var(--index)* var(--rotation-diff))) translate(calc(var(--translate-diff)* var(--index)), 0); }
}
@-o-keyframes reboot-card-initialization {
0%{ transform: none; opacity: 0; filter: blur(20px) saturate(0%);}
100%{ transform: rotate(calc(var(--index)* var(--rotation-diff))) translate(calc(var(--translate-diff)* var(--index)), 0); }
}
@keyframes reboot-card-initialization {
0%{ transform: none; opacity: 0; filter: blur(20px) saturate(0%);}
100%{ transform: rotate(calc(var(--index)* var(--rotation-diff))) translate(calc(var(--translate-diff)* var(--index)), 0); }
}
.reboot-card-effect-section .reboot-card-effect .e-con.fixed.big,
.reboot-card-effect-section .reboot-card-effect .e-container.fixed.big{
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}
.reboot-card-effect-section .reboot-card-effect .e-con.hover .e-con,
.reboot-card-effect-section .reboot-card-effect .e-container.hover .e-container{
    transform: translateY(-60px);
}
.reboot-card-effect-section .reboot-card-effect .e-con.defocus .e-con,
.reboot-card-effect-section .reboot-card-effect .e-container.defocus .e-container{
    filter: saturate(0%);
}
.reboot-card-effect-section .reboot-card-effect .e-con:not(.big) .e-con:before,
.reboot-card-effect-section .reboot-card-effect .e-container:not(.big) .e-container:before{
    opacity: 0;
}
.reboot-card-effect-section .reboot-card-effect .e-con.big .e-con,
.reboot-card-effect-section .reboot-card-effect .e-container.big .e-container{
    transform: translate(calc((var(--width, 240px) - var(--big-width))/2), calc((var(--min-height, 320px) - var(--actual-height))/2 - calc(1px*var(--y,0))));
}
.reboot-card-effect-section .reboot-card-effect .e-con .elementor-widget,
.reboot-card-effect-section .reboot-card-effect .e-container .elementor-widget{
    width: calc(var(--big-width) - 20px*2);
    max-width: unset;
}
.reboot-card-effect-section .reboot-card-effect >.e-con:not(.big) .elementor-widget > *,
.reboot-card-effect-section .reboot-card-effect > .e-container:not(.big) .elementor-widget > *{
    opacity: 0;
    pointer-events: none;
    transform: translateY(100%);
    transition: all 0.5s ease-in-out;
}
}

@media (max-width: 767px){
.reboot-card-effect-section{
    --big-width: 240px;
    --big-height: 320px;
}
.reboot-card-effect-section .reboot-card-effect > .e-con,
.reboot-card-effect-section .reboot-card-effect > .e-container{
    position: static !important;
    transition: filter calc(1s*var(--init-transition)) ease-in-out,
                opacity calc(1s*var(--init-transition)) ease-in-out;
}
.reboot-card-effect-section .reboot-card-effect .e-con .e-con,
.reboot-card-effect-section .reboot-card-effect .e-container .e-container{
    box-shadow: none;
}
}    
</style>
<script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
<script>
if(!rebootNonce107){
var rebootNonce107 = true
$(document).ready(function(){

var wrapper = [],
    containers = [],
    info = [],
    initLock = [],
    clickLock = []

function getCSS(el, property, defaultValue = 0){
    var val = getComputedStyle(el.get(0)).getPropertyValue(property)
    return val ? val.trim() : defaultValue;
}

function initialAnimation(el, i, initTransition){
    var offset = 200,
        initialTime = new Date(),
        currentTime, interval, timeDiff, bottomContainerIndex
        
    if(el.offset().top < $(window).scrollTop() + $(window).height() - offset) {
        el.addClass('init')
        if( !containers[i].length ) return
        if(initLock[i]) return
        initLock[i] = true
        interval = setInterval(function(){
            currentTime = new Date()
            timeDiff = currentTime - initialTime
            bottomContainerIndex = containers[i].eq(0).hasClass('fixed') ? containers[i].length - 1 : 0
            extraHeight = containers[i].length == 1 ? 0 : containers[i].eq(bottomContainerIndex).get(0).getBoundingClientRect().bottom - wrapper[i].get(0).getBoundingClientRect().top - parseFloat(getCSS(wrapper[i], 'padding-top')) - containers[i].height()
            el.get(0).style.setProperty('--extra-height', extraHeight)
            wrapper[i].get(0).style.setProperty('--card-y', wrapper[i].offset().top + parseFloat(getCSS(wrapper[i], 'padding-top')) - $(window).scrollTop())
            wrapper[i].get(0).style.setProperty('--card-x', ($(window).width() - containers[i].width())/2)
            if(timeDiff > 3*initTransition){
                initLock[i] = false
                clearInterval(interval)
            }
        }, 10)
    }
}

$(window).on('load scroll resize', function(e){
$('.reboot-card-effect-section').each(function(i){
    var $this = $(this),
        initTransition = parseFloat(getCSS($this, '--init-transition', 1.5))*1000,
        bigHeight = parseFloat(getCSS($this, '--big-height', '650px')),
        actualHeight = bigHeight,
        maxHeight = 0.8,
        maxItems, startPoint, increase
        
    initialAnimation($this, i, initTransition)
    
    if($(window).width() > 1450){
        maxItems = 9   
    }else if($(window).width() > 1320){
        maxItems = 8
    }else if($(window).width() > 1180){
        maxItems = 7
    }else if($(window).width() > 1024){
        maxItems = 6
    }else{
        maxItems = 6
    }
    startPoint = containers[i].length > maxItems ? (1 - maxItems)/2 : (1 - containers[i].length)/2
    increase = containers[i].length > maxItems ? (maxItems - 1)/(containers[i].length - 1) : 1
        
    containers[i].each(function(i){
        $(this).get(0).style.setProperty('--index', startPoint+i*increase)
    })
    
    if( bigHeight > $(window).height()*maxHeight ){ actualHeight = $(window).height()*maxHeight }
    $this.get(0).style.setProperty('--actual-height', actualHeight + 'px')
    
    if(e.type !== 'scroll'){
        clickLock[i] = true
        setTimeout(function(){
            clickLock[i] = false
        }, initTransition)
    }
})
})

function hoverIn($this, containers){
    if(!$this.hasClass('fixed')){
        $this.addClass('hover')
        containers.addClass('defocus')
        $this.removeClass('defocus')
    }
}
    
$(window).on('mousemove', function(e){
$('.reboot-card-effect-section').each(function(i){
    
    var $this = $(this),
        x = e.pageX - $this.offset().left,
        y = e.pageY - $this.offset().top,
        cards = $(e.target).closest('.reboot-card-effect > .e-con, .reboot-card-effect > .e-container')

    info[i].css('transform', 'translate(' + x + 'px,' + y + 'px)')
    
    if( !cards.length || cards.hasClass('fixed') ){
        info[i].removeClass('showing')
    }else{
        info[i].addClass('showing')
        hoverIn(cards, containers[i])
    }
})
})

$('.reboot-card-effect-section').each(function(i){
    
    var $this = $(this),
        close = $this.find('.reboot-card-effect-close'),
        bigTransition = parseFloat(getCSS($this, '--big-transition', 0.5))*1000
        
    wrapper[i] = $this.find('.reboot-card-effect')
    containers[i] = wrapper[i].children('.e-con, .e-container')
    info[i] = $this.find('.reboot-card-effect-info')
    initLock[i] = false
    clickLock[i] = false
        
    containers[i].hover(function(){
        hoverIn($(this), containers[i])
    }, function(){
        $(this).removeClass('hover')
        containers[i].removeClass('defocus')
    })
        
    containers[i].on('click', function(){
        var t = $(this)
        if($(window).width() < 768) return
        if(t.hasClass('fixed')) return
        if(clickLock[i]) return
        clickLock[i] = true
        wrapper[i].get(0).style.setProperty('--card-y', wrapper[i].offset().top + parseFloat(getCSS(wrapper[i], 'padding-top')) - $(window).scrollTop())
        wrapper[i].get(0).style.setProperty('--card-x', ($(window).width() - containers[i].width())/2)
        containers[i].removeClass('fixed defocus')
        t.addClass('fixed')
        setTimeout(function(){ t.addClass('big') }, 10)
        $this.addClass('popup active')
        $('body').addClass('fixed')
        info[i].removeClass('showing')
        setTimeout(function(){
            clickLock[i] = false
        }, bigTransition+10)
    })
    
    wrapper[i].on('click', function(e){
        if($(e.target).closest('.e-con, .e-container').hasClass('reboot-card-effect')){ close.trigger('click') }
    })
    
    close.on('click', function(){
        if(clickLock[i]) return
        clickLock[i] = true
        containers[i].removeClass('big')
        $this.removeClass('popup')
        setTimeout(function(){
            containers[i].removeClass('fixed')
            $this.removeClass('active')
            $('body').removeClass('fixed')
            clickLock[i] = false
        }, bigTransition+10)
    })
})
})
}
</script>
				
			

Other Articles

Transform Your Website with This FIRST EVER Animated Inner Border Effect In Elementor | WordPress Tutorial

https://youtu.be/bfAqAQnJO7E So if you follow along in the video, I refer to this blog post for you to enter code ...

Ignite Your Website with a Fiery Animated Cursor Trail Effect in Elementor | WordPress Tutorial

https://youtu.be/sLSE2L0zKZg So if you follow along in the video, I refer to this blog post for you to enter code ...

Create a Mesmerizing Animated Custom Cursor in Elementor

https://youtu.be/re_LUiEHx1U So if you follow along in the video, I refer to this blog post for you to enter code ...

Dazzle Your Visitors with This Animated Glowing Button Background Effect in Elementor

https://youtu.be/s3kOkTYZDBY So if you follow along in the video, I refer to this blog post for you to enter code ...