<div class="wrapper">
<div class="intro">
<h1 class="heading">Iris Wipe</h1>
<p class="nudge">hover/tap to see transition</p>
</div>
<div class="scenes" tabindex="0">
<div class="scene-1">
<h2 class="scene-title">Captain Phasma</h2>
</div>
<div class="scene-2">
<h2 class="scene-title">Porg</h2>
</div>
</div>
<div class="visualizer">
<div class="visualizer-frame">
<div class="visualizer-mask"></div>
</div>
</div>
</div>
/* scenes (the good stuff) */
@property --radius {
syntax: '<percentage>';
inherits: true;
initial-value: -5%;
}
@keyframes scene-transition {
to { --radius: 105%; }
}
.scenes {
position: relative;
aspect-ratio: 2.4 / 1;
outline: 2px solid #ccc;
}
.scene-1, .scene-2 {
position: absolute;
inset: 0;
background-size: cover;
}
.scene-1 {
background-image: url(https://assets.codepen.io/77020/sw-iris-wipe-scene-1.jpg);
}
.scene-2 {
background-image: url(https://assets.codepen.io/77020/sw-iris-wipe-scene-2.jpg);
z-index: -1;
-webkit-mask-image: radial-gradient(
circle,
#fff calc(var(--radius) - 5%),
transparent calc(var(--radius) + 5%)
);
}
.scenes:is(:hover, :focus) .scene-2 {
z-index: 1;
animation: scene-transition 2s linear forwards;
}
.scene-title {
position: absolute;
max-width: 45%;
margin: min(40px, 4vw);
font-size: 1.25em;
}
.scene-1 .scene-title {
top: 0;
right: 0;
color: #fff;
text-align: right;
}
.scene-2 .scene-title {
bottom: 0;
left: 0;
color: #fff;
text-align: left;
}
/* everything else */
*, *::before, *::after {
box-sizing: border-box;
}
body {
display: grid;
place-items: center;
min-height: 100vh;
margin: 0;
padding: 20px;
color: #fff;
background-color: #111;
font: clamp(0.75rem, 0.3rem + 1.9vw, 1.5rem)/1.1 'Koulen', sans-serif;
letter-spacing: 0.1em;
}
.wrapper {
display: grid;
gap: 30px;
width: min(1000px, 100%);
}
.intro {
text-align: center;
}
.heading {
margin: 0;
font-size: 2.5em;
}
.heading::before, .heading::after {
content: ' — ';
}
.nudge {
margin: 0;
color: #888;
font-size: 1.25em;
}
.visualizer {
display: flex;
justify-content: center;
}
.visualizer-frame {
position: relative;
width: min(150px, 25vw);
aspect-ratio: 2.4 / 1;
outline: 2px solid #ccc;
background-color: #333;
background-image:
linear-gradient(45deg, #444 25%, transparent 25%, transparent 75%, #444 75%),
linear-gradient(45deg, #444 25%, transparent 25%, transparent 75%, #444 75%);
background-size:
16px 16px,
16px 16px;
background-position:
0 0,
8px 8px;
}
.visualizer-mask {
position: absolute;
inset: 0;
box-shadow: inset 0 0 0 2px #111;
}
.scenes:is(:hover, :focus) + .visualizer .visualizer-mask {
background-image: radial-gradient(circle, #fff calc(var(--radius) - 5%), transparent calc(var(--radius) + 5%));
animation: scene-transition 2s linear forwards;
}
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.