<div class="wrapper">
<div class="grid">
<div class="grid__item grid__item--heading">
<h1>Hello. And welcome.</h1>
</div>
<div class="grid__item grid__item--lg">
<img src="https://images.unsplash.com/photo-1506328962840-ff6790651285?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=0216f5c81ee7481941d551b4113b1ca7&auto=format&fit=crop&w=1950&q=80" alt="A kingfisher close up">
</div>
<div class="grid__item grid__item--md">
<img src="https://images.unsplash.com/photo-1505051508008-923feaf90180?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=fda1d3045d1ff97ef564d4fc3ae14fe4&auto=format&fit=crop&w=1950&q=80" alt="Beautiful sunset">
</div>
<div class="grid__item grid__item--sm">
<img src="https://images.unsplash.com/photo-1506604900144-7360175909e2?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=d437158dff03180ed32cc39401b3a894&auto=format&fit=crop&w=1955&q=80" alt="Pine needles on a tree">
</div>
</div>
<button class="btn">Click to change placement</button>
</div>
:root {
--gridSize: 6;
--size: 1;
--posX: 1;
--posY: 1;
}
img {
display: block;
width: 100%;
height: 100%;
object-fit: cover;
}
.wrapper {
max-width: 1200px;
margin: 0 auto;
}
.grid {
display: grid;
grid-template-columns: repeat(var(--gridSize), 1fr);
grid-template-rows: repeat(var(--gridSize), 1fr);
border: 1px solid grey;
width: 90vw;
height: 90vw;
margin: 100px auto;
@media (min-width: 960px) {
width: 33vw;
height: 33vw;
}
}
.grid__item {
grid-column: var(--posX) / span var(--size);
grid-row: var(--posY) / span var(--size);
mix-blend-mode: hard-light;
}
.grid__item--heading {
--posX: 4;
--posY: 1;
--size: 3;
z-index: 1;
border: 2px solid coral;
padding: 20px;
}
.grid__item--lg {
--posY: 2;
--size: 3;
}
.grid__item--md {
--posX: 5;
--posY: 4;
--size: 2;
}
.grid__item--sm {
--posX: 3;
--posY: 6;
}
.btn {
padding: 10px 20px;
position: absolute;
top: 0;
left: 0;
}
View Compiled
const btn = document.querySelector('.btn')
const items = [...document.querySelectorAll('.grid__item')]
const body = document.querySelector('body')
let availablePositions
let props
let x
let y
let getItemProperties = (el) => {
el.props = {
posX : parseInt(getComputedStyle(el).getPropertyValue('--posX')),
posY: parseInt(getComputedStyle(el).getPropertyValue('--posY')),
size: parseInt(getComputedStyle(el).getPropertyValue('--size'))
}
}
const gridSize = getComputedStyle(body).getPropertyValue('--gridSize')
const setNewPosition = () => {
items.forEach((item) => {
getItemProperties(item)
availablePositions = [...Array(gridSize - (item.props.size - 1))] // creates an empty array of the number of available positions for the grid item - so that it won’t exceed 6 grid tracks
const itemAvailablePositions = availablePositions.map((u, i) => {
return i + 1
})
const getRandom = () => {
return itemAvailablePositions[Math.floor(Math.random() * itemAvailablePositions.length)]
}
const calcNewPos = (el) => {
el.style.setProperty('--posX', getRandom())
el.style.setProperty('--posY', getRandom())
}
calcNewPos(item)
})
}
btn.addEventListener('click', setNewPosition)
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.