I have an interface with a few panels, like here with a mosaic of 6 panels, using multiple display: flex
div, with flex-direction
column or row.
I'd like that, when clicking/touching on one panel, this one becomes nearly full size, and the other panels are in a left column as "thumbnails".
I don't see how I can make this with my current design with multiple flex
elements inside each other.
Question: how do you create such a "click on one tile to zoom it and move other tiles as a column of thumbnails" feature?
.horizontal { display: flex; align-items: center; justify-content: center; gap: 1em; }
.vertical { display: flex; align-items: center; justify-content: space-around; flex-direction: column; gap: 1em; }
.box { width: 150px; height: 100px; background-color: #eee; }
<div class="horizontal">
<div class="vertical">
<div class="box">A</div>
<div class="box">B</div>
</div>
<div class="vertical">
<div class="box">C</div>
<div class="box">D</div>
</div>
<div class="vertical">
<div class="box">E</div>
<div class="box">F</div>
</div>
</div>
You can use grid
and use the grid-template-areas
property to put a space where you need the larger image. I've put the skeleton of one up for you but you'll need to neaten up the box sizes a bit.
window.onload = () => {
document.querySelector('body').addEventListener('click', (event) => {
document.querySelectorAll('.container > div').forEach((element) => {
element.classList.remove('clicked');
});
document.querySelector('.container').classList.remove('clicked');
const clickedElement = event.target;
if(clickedElement.tagName=="IMG") {
clickedElement.closest('.container').classList.add('clicked');
event.target.closest('.box').classList.add('clicked');
}
});
}
body {
height: 100vh;
}
.container {
display: inline-grid;
grid-template-columns: repeat(3, 1fr);
gap: 0.5rem;
}
.container img {
width: 100%;
}
.container.clicked {
grid-template-columns: repeat(2, fit-content(0));
grid-template-areas: ". img" ". img" ". img" ". img" ". img" ". img";
}
.box.clicked {
grid-area: img;
width: 450px;
}
.box.clicked img {
width: 100%;
animation: scalein 0.5s;
}
.box img {
animation: scaleout 0.3s;
}
.container.clicked .box:not(.clicked) {
grid-auto-flow: column;
width: 80px;
}
@keyframes scalein {
0% {
transform: scale(50%);
opacity: 0;
}
90% {
transform: scale(102%);
}
100% {
transform: scale(100%);
opacity: 1;
}
}
@keyframes scaleout {
0% {
transform: scale(150%);
}
100% {
transform: scale(100%);
}
}
<div class="container">
<div class="box"><img src='https://picsum.photos/id/237/200'></div>
<div class="box"><img src='https://picsum.photos/id/242/200'></div>
<div class="box"><img src='https://picsum.photos/id/241/200'></div>
<div class="box"><img src='https://picsum.photos/id/240/200'></div>
<div class="box"><img src='https://picsum.photos/id/238/200'></div>
<div class="box"><img src='https://picsum.photos/id/239/200'></div>
</div>