<!-- 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);
});
This Pen doesn't use any external CSS resources.