<!--
1. Intro animation duration stagger
2. Mouse Position Tracking with CSS variables
3. Text Outline Reveal on Hover
-->
<div id="app">
<nav class="main-nav" style="--total: 4">
<a href="#" class="image-hover" style="--i: 0">
<span class="title" data-title="Keyframers">Keyframers</span>
<img src="https://images.unsplash.com/photo-1595263541702-64a36a9b1129?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=750&h=1000&fit=crop&ixid=eyJhcHBfaWQiOjE0NTg5fQ" alt="">
</a>
<a href="#" class="image-hover" style="--i: 1">
<span class="title" data-title="Animation Amigos">Animation Amigos</span>
<img src="https://images.unsplash.com/photo-1594977887411-f2ba50a01b0c?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=750&h=1000&fit=crop&ixid=eyJhcHBfaWQiOjE0NTg5fQ" alt="">
</a>
<a href="#" class="image-hover" style="--i: 2">
<span class="title" data-title="CSS Tutorials">CSS Tutorials</span>
<img src="https://images.unsplash.com/photo-1595639395288-46fba44df7c8?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=750&h=1000&fit=crop&ixid=eyJhcHBfaWQiOjE0NTg5fQ" alt="">
</a>
<a href="#" class="image-hover" style="--i: 3">
<span class="title" data-title="JavaScript Bits">JavaScript Bits</span>
<img src="https://images.unsplash.com/photo-1596413502478-3eeb71b2df32?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=750&h=1000&fit=crop&ixid=eyJhcHBfaWQiOjE0NTg5fQ" alt="">
</a>
<a href="#" class="image-hover" style="--i: 4">
<span class="title" data-title="Boolean Buddies">Boolean Buddies</span>
<img src="https://images.unsplash.com/photo-1568829198167-914b4194bdac?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=750&h=1000&fit=crop&ixid=eyJhcHBfaWQiOjE0NTg5fQ" alt="">
</a>
</nav>
</div>
<a href="https://youtu.be/EkKNosvVijM" target="_blank" data-keyframers-credit style="color: #FFF"></a>
<script src="https://codepen.io/shshaw/pen/QmZYMG.js"></script>
@import url("https://fonts.googleapis.com/css2?family=Roboto:wght@900&display=swap");
*,
*::before,
*::after {
box-sizing: border-box;
position: relative;
}
html,
body,
#app {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
.main-nav {
display: flex;
flex-direction: column;
justify-content: center;
height: 100vh;
padding: 3vh 1vw;
}
html {
background: #060706;
color: #fff;
overflow: hidden;
--easing: cubic-bezier(0.5, 0.5, 0.2, 1);
}
.image-hover {
display: block;
color: white;
text-decoration: none;
text-align: center;
padding: 2vh 0;
transform-origin: top left;
animation: skwoop 0.7s var(--easing) backwards;
animation-duration: calc(0.6s + (var(--i) * 0.1s));
animation-delay: calc((var(--i) * 50ms));
cursor: pointer;
@keyframes skwoop {
from {
opacity: 0;
transform: translateY(5vh) skewY(5deg);
}
}
.title {
font-family: "Roboto";
font-weight: 900;
font-size: 9vh;
letter-spacing: 0.05ch;
&::after {
content: attr(data-title);
position: absolute;
top: 0;
left: 0;
z-index: 5;
color: transparent;
-webkit-text-stroke: 2px #fff;
//-webkit-text-stroke: 2px red;
}
}
> img {
// display: none;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
max-width: 40%;
max-height: 60vh;
pointer-events: none;
z-index: 2;
visibility: hidden;
opacity: 0;
transition: opacity 0.2s linear, visibility 0s linear 0.2s;
}
&:hover,
&:focus {
z-index: 10;
.title::after {
display: block;
}
> img {
transition-delay: 0s;
visibility: visible;
opacity: 1;
}
}
}
.image-hover > img {
--x-px: calc(var(--x) * 1px);
--y-px: calc(var(--y) * 1px);
top: 0;
left: 0;
transform: translate(var(--x-px), var(--y-px)) translate(-50%, -50%);
}
View Compiled
console.clear();
const elApp = document.querySelector("#app");
// What we need...
// Mouse position
// Currently hovered item
document.body.addEventListener("mousemove", (event) => {
console.log({
x: event.clientX,
y: event.clientY
});
elApp.style.setProperty("--x", event.clientX);
elApp.style.setProperty("--y", event.clientY);
});
// Replay animation by hiding & showing the element again
let el = document.body;
el.addEventListener("click", function (e) {
el.hidden = true;
requestAnimationFrame(() => {
el.hidden = false;
});
});
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.