<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)
Rerun