ImageMosaic image
Mosaicgrid met groot uitgelicht beeld links en drie kleinere beelden rechts.
src/components/image/ImageMosaic.astro
---
interface MosaicItem {
src?: string;
alt?: string;
label?: string;
featured?: boolean;
}
interface Props {
title?: string;
items?: MosaicItem[];
}
const {
title = 'Impressie',
items = [
{ alt: 'Groot beeld', label: 'Featured project', featured: true },
{ alt: 'Klein beeld 1', label: 'Detail 1' },
{ alt: 'Klein beeld 2', label: 'Detail 2' },
{ alt: 'Klein beeld 3', label: 'Detail 3' },
],
} = Astro.props;
---
<section class="bl-section imo">
<div class="bl-inner imo__inner">
{title && <h2 class="imo__title">{title}</h2>}
<div class="imo__grid">
{items.map((item) => (
<div class:list={['imo__item', { 'imo__item--large': item.featured }]}>
{item.src
? <img data-allow-img class="imo__img" src={item.src} alt={item.alt ?? ''} loading="lazy" decoding="async" />
: <div class="imo__placeholder" aria-label={item.alt ?? ''}></div>
}
{item.label && <span class="imo__label">{item.label}</span>}
</div>
))}
</div>
</div>
</section>
<style>
.imo__title {
font-size: clamp(1.75rem, 3vw, 2.5rem);
font-weight: 700;
color: var(--color-primary, #0a0a0a);
margin: 0 0 2rem;
}
.imo__grid {
display: grid;
grid-template-columns: 2fr 1fr;
grid-template-rows: auto auto;
gap: 0.75rem;
}
.imo__item {
position: relative;
overflow: hidden;
border-radius: 8px;
aspect-ratio: 4/3;
}
.imo__item--large {
grid-row: span 2;
aspect-ratio: auto;
}
.imo__img {
width: 100%;
height: 100%;
object-fit: cover;
transition: transform 0.35s;
}
.imo__item:hover .imo__img {
transform: scale(1.04);
}
.imo__placeholder {
width: 100%;
height: 100%;
min-height: 150px;
}
.imo__item--large .imo__placeholder {
background: linear-gradient(135deg, #1a2a4a, #3a4a7a);
min-height: 320px;
}
.imo__item:not(.imo__item--large) .imo__placeholder {
background: linear-gradient(135deg, #e0e0f0, #c8c8e8);
}
.imo__item:nth-child(3) .imo__placeholder {
background: linear-gradient(135deg, #e8f0e0, #c8e0c8);
}
.imo__label {
position: absolute;
bottom: 0.75rem;
left: 0.75rem;
background: rgba(10, 10, 10, 0.65);
color: #fff;
font-size: 0.75rem;
font-weight: 600;
padding: 0.25rem 0.6rem;
border-radius: 4px;
}
@media (max-width: 640px) {
.imo__grid {
grid-template-columns: 1fr;
}
.imo__item--large {
grid-row: auto;
}
}
</style>
Props
| Prop | Type | Default | Beschrijving |
|---|---|---|---|
title | string | - | Kop boven het mosaic |
items | { src?: string; alt?: string; label?: string; featured?: boolean }[] | - | Mosaicbeelden; eerste featured item krijgt grote positie |
* = verplicht