CSS Animation

by Sasabee

HTML

<body></body>

CSS

:root {
	font-size: 24px;
}

* {
	box-sizing: border-box;
}

body {
	overflow: hidden;
	margin: 0;
	padding: 0;
	width: 100%;
	height: 100vh;
	max-height: 466px;
	background-image: linear-gradient(135deg, #333 20%, #444 20% 40%, #333 40% 60%, #444 60% 80%, #333 80%);
}

.mask {
	width: 100%;
	height: 100%;
	max-height: inherit;
	padding: 2rem;
	background-color: rgba(255,255,255,.1);
	backdrop-filter: blur(10px);
}

.base {
	width: 100%;
	height: 100%;
	background-color: white;
}

.base.open {
	animation: 1s ease-out open;
}

.base.close {
	animation: 1s ease-out close;
}

.content {
	width: 100%;
	height: 100%;
	background-color: yellow;
}

.content.insert {
	animation: 1s ease-out insert;
}

@keyframes open {
	from { transform: scaleY(0); }
	to { transform: scaleY(1); }
}

@keyframes insert {
	from { margin-left: -2rem; opacity: 0; }
	to { margin-left: 0; opacity: 1; }
}

@keyframes close {
	to { transform: scaleX(0); }
}

JavaScript

const openModal = ()=>{
	const mask = document.createElement('div');
	mask.classList.add('mask');
	const base = document.createElement('div');
	base.classList.add('base', 'open');
	const content = document.createElement('div');
	content.classList.add('content');

	base.addEventListener('animationend', ()=>{
		base.classList.remove('open');
		base.append(content);
		content.classList.add('insert');
	});

	content.addEventListener('animationend', ()=>{
		content.classList.remove('insert');
		const clone = base.cloneNode(true);
		clone.addEventListener('animationend', ()=>{
			mask.remove();
			setTimeout(openModal, 1000);
		});
		mask.append(clone);
		base.remove();
		clone.classList.add('close');
	});

	document.body.append(mask);
	mask.append(base);
};

openModal();