<!-- Photo by Andre Benz on Unsplash -->

<h1>OffScreen Element reveal</h1>
<h2>as seen on <a href="https://mathieulevesque.com/en" target="_blank">https://mathieulevesque.com/en</a></h2>
<p>hover the round button or click it to instant open the offscreen element</p>

<div class="trigger">i</div>

<h1 class="title">Title</h1>
<h1 class="title--overlay">Title</h1>


<img src="https://images.unsplash.com/photo-1541537103745-ea3429c65dc4?ixlib=rb-0.3.5&s=420136e28086d115c6019b996e23115c&auto=format&fit=crop&w=1834&q=80" alt="">

<div class="offscreen">
	<div class="content">
		<h1 class="title" data-splitting>Title</h1>
		<div class="close">X</div>
	</div>
</div>
@import url('https://fonts.googleapis.com/css?family=Yantramanav:400,700');

$typo: #1f1f1f;
$cubic: cubic-bezier(.25,.46,.45,.94);

* {
	margin: 0;
	padding: 0;
	box-sizing:border-box;
	font-family: 'Yantramanav', sans-serif;
	font-weight: 400;
	color: $typo;
}

html, body {
	width: 100%;
	height: 100%;
}

body {
	overflow: hidden;
	padding: 4rem;
}

h1, h2 {
	margin: .5rem 0;
}

h2 {
	opacity: .8;
}

p {
	opacity: .78;
}

.title {
	font-size: 18vmax;
	text-transform: uppercase;
	position: absolute;
	left: 4rem;
	bottom: 4rem;
	font-weight: 700;
	z-index: 5;
	display: flex;
	line-height: 1;
	
	.word {
		display: inline-block;
		overflow: hidden;
		line-height: 1;
		
		.char {
			color: #fff;
			display: inline-block;
			font-weight: 700;
			transition: transform .25s $cubic;
			line-height: 1;
			transition-delay: .8s;
		}
	}
}

.title--overlay {
	@extend .title;
	color: transparent;
	-webkit-text-stroke: .1vw #fff;
	text-stroke: .1vw #fff;
	mix-blend-mode: overlay;
	z-index: 10;
}

img {
	position: absolute;
	margin: auto;
	top: 50vh;
	left: 0;
	right: 0;
	z-index: 8;
	max-width: 400px;
}

a {
	text-decoration: none;
	color: $typo;
	position: relative;
	
	&:before {
		content: '';
		position: absolute;
		left: 0;
		bottom: 0;
		width: 100%;
		height: 0;
		background: rgba(0,0,0,.2);
		transition: height .25s $cubic;
	}
	
	&:hover {
		&:before {
			height: 40%;
		}
	}
}

.trigger {
	position: absolute;
	margin: auto;
	left: 4rem;
	top: 0;
	bottom: 0;
	width: 100px;
	height: 100px;
	background: #000;
	border-radius: 50%;
	display: flex;
	justify-content: center;
	align-items: center;
	color: #fff;
	font-size: 1.5rem;
	transition: transform .25s $cubic;
	line-height: 1;
	cursor: pointer;
	z-index: 15;
	
	&:hover {
		transform: scale(1.1);
		user-select: none;
	}
}

.offscreen {
	position: fixed;
	top: 0;
	right: 0;
	bottom: 0;
	left: 0;
	background: crimson;
	transform: translateX(100%);
	overflow: hidden;
	z-index: 20;
	
	.content {
		position: absolute;
		top: 0;
		right: 0;
		bottom: 0;
		left: 0;
		width: 100vw;
		height: 100vh;
		transform: translateX(-100vw);
		
		.title {
			color: #fff;
		}
	}
	
	.close {
		position: absolute;
		width: 50px;
		height: 50px;
		background: #fff;
		right: 2rem;
		top: 2rem;
		border-radius: 50%;
		display: flex;
		justify-content: center;
		align-items: center;
		transition: transform .25s $cubic;
		z-index: 22;
		cursor: pointer;
	
		&:hover {
			transform: scale(1.1);
			user-select: none;
		}
	}
	
	&.open {
		
		.title {
			
			.word {
				
				.char {
					transform: translateY(100%);
					transition-delay: calc((.015s * var(--char-index)) + .4s);
				}
			}
		}
	}
}
View Compiled
console.clear();

$(document).ready(function() {
	
	Splitting();
	
	let progress = 100;
	let active = false;
	let complete = false;
	const trigger = $('.trigger');
	const offScreen = $('.offscreen');
	const content = offScreen.find('.content');
	const closeBtn = offScreen.find('.close');
	
	trigger.on('mouseover', function() {
		active = true;
		start();
	});
	trigger.on('mouseout', function() {
		active = false;
		stop();
	});
	trigger.on('click', finish);
	
	// reset
	$(document).on('keydown', function(e) {
		let pKey = e.which;
		(pKey === 27) && reset();
	});
	
	closeBtn.on('click', reset);
	
	function reset() {
		active = false;
		complete = false;
		progress = 100;
		transition(100);
		offScreen.removeClass('open');
	}
	
	
	function start() {
		if (active && !complete) {
			if (progress <= 30) {
				progress = 0;
				complete = true;
				offScreen.addClass('open');
			} else {
				progress = progress - 1;
				setTimeout(start, 10);
			}
			console.log(`progress: ${progress}`);
			transition(progress);
		}
	}
	
	function stop() {
		if (!complete) {
			progress = 100;
			transition(100);
			offScreen.removeClass('open');
		}
	}
	
	function finish() {
		progress = 0;
		complete = true;
		transition(progress);
		offScreen.addClass('open');
	}
	
	function transition(progress) {
		TweenMax.to(offScreen, .6, {
			x: `${progress}vw`
		});
		TweenMax.to(content, .6, {
			x: `-${progress}vw`
		});
	}
	
	
	transition(0);
	setTimeout(function() {
		transition(100);
	}, 1000);
});

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js
  2. https://cdnjs.cloudflare.com/ajax/libs/gsap/2.0.2/TweenMax.min.js
  3. https://unpkg.com/splitting/dist/splitting.min.js