Aller au contenu principal
Guillaume Duverger Code & graphisme

Simple lightbox JS / CSS view-transition API

Sur Chrome en activant le drapeau chrome://flags/#view-transition-on-navigation, puis passez la valeur à enabled

Votre navigateur ne supporte pas cette démonstration




<div class=demo data-page="index">
<ul>
<li>
<a href="#a" data-to="a">
<img src="image.jpg" alt style="view-transition-name: img-1">
</a>
</li>
<li>
<a href="#b" data-to="b">
<img src="image.jpg" alt style="view-transition-name: img-2">
</a>
</li>
<li>
<a href="#c" data-to="c">
<img src="image.jpg" alt style="view-transition-name: img-3">
</a>
</li>	
</ul>
</div>


<div class="conteneur" data-page="a" hidden>
<div>	
<a href="#index" data-to="index"></a>
<figure>
<img src="image.jpg" alt style="view-transition-name: img-1">
<figcaption>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</figcaption>
</figure>
</div>
</div>

<div class="conteneur" data-page="b" hidden>
<div> 
<a href="#index" data-to="index"></a>
<figure>
<img src="image.jpg" alt style="view-transition-name: img-2">
<figcaption>Ut congue odio nunc eu dui. Donec imperdiet consequat maximus.</figcaption>
</figure>
</div>
</div>

	
<div class="conteneur" data-page="c" hidden>
<div> 
<a href="#index" data-to="index"></a>
<figure>
<img src="image.jpg" alt style="view-transition-name: img-3">
<figcaption>Aliquam fringilla volutpat enim. Curabitur metus lectus, varius nec lectus nec, vulputate fermentum purus.</figcaption>
</figure>
</div>
</div>






ul {
	
padding:1rem;	
display: grid;
gap: 1rem;
grid-template-columns: repeat(3,auto);
	
}
	
img{
	
display:block;
width:100%;
height:100%;
aspect-ratio:3/2;
contain: layout;
	
	}
	
	
figure{

	display:grid;
	margin:0;
	
	}	
	
figure>*{
	
grid-area:1/1;
	
	}
	
figcaption{
	
place-self:end center;
padding:.5rem;
font-size:clamp(.875rem,1vw + 1rem,1rem)
min-height:3rem;
width:100%;
max-width:90%;
display:flex;
align-items:center;
justify-content: center;
color:white;
background:rgba(0, 0, 0, 0.7);
view-transition-name:figcaption	
	}
	


::view-transition-new(figcaption):only-child{
	
	animation:.25s ease .25s both fade,.25s ease .25s both slide-up
	
	}
	
::view-transition-old(figcaption):only-child{
	
	animation:.1s both fade reverse,.1s ease both slide-up reverse
	
	}
	
@keyframes fade{
	
	from{
		
		opacity:0
	
	}
	
	to{
		
		opacity:1
	
	}
	
	}

@keyframes slide-up{
	
from{
	
	translate:0 2.5rem
	
	}
	
to{
	translate:unset
	
	}
	
	}	
	
	
.conteneur{
	
position:fixed;
inset:0;
margin:auto;
background:rgba(0, 0, 0, 0.51);
padding:1rem;	
}
	
.conteneur div {

display: grid;
place-content: center;
min-height:100dvh;

	}
	
.conteneur div img{
	
	max-width: 90%;
	object-fit: cover;
	margin:auto
	
	}	
	
.conteneur div a{
	
place-self:start end;
display:grid;
height:2.5rem;
aspect-ratio:1
	
	}

.conteneur div a::after, 
.conteneur div a::before{
	
grid-area:1/1;
content: '';
width: 3px;
height: 100%;
background-color: #fff;
place-self:center;
border-radius: 5px;
   
}
	
.conteneur div a::after{
	
	rotate:45deg;
	
	}
	
.conteneur div a::before{
	
   rotate:-45deg;
}







//source originale code js : https://stackdiary.com/view-transitions-api/

document.querySelectorAll('a[data-to]').forEach((a) => {
  a.addEventListener('click', (e) => {
    e.preventDefault();

    const to = e.currentTarget.dataset.to;

    document.startViewTransition(() => {
      document.querySelectorAll('[data-page]').forEach((page) => {
        page.hidden = to !== page.dataset.page
      })
    })
  })
})