Fade Transition
An elegant crossfade between content panels. Best for dashboards, CMS screens, and tab navigation where the surrounding context stays stable.
Fade Transition the 1st of 11 designs in the 11 CSS Page Transitions collection. The design pairs CSS styling with a small amount of JavaScript for interactivity. Copy the HTML, CSS and JavaScript panels below into your project — the JS is self-contained, has zero dependencies, and is safe to drop into any framework (React, Vue, Svelte, plain HTML). The design honours prefers-reduced-motion and uses real semantic markup, so it ships accessibility-ready out of the box.
Live preview
This is a full-page demo — interact inside the frame above, or open it in the playground for the full-screen experience.
The code
<div class="shell">
<!-- Sidebar -->
<nav class="sidebar">
<div class="sidebar-brand">Atelier<br><span>Studio</span></div>
<div class="nav-label">Navigation</div>
<button class="nav-link active" data-target="home">
<span class="nav-dot"></span> Overview
</button>
<button class="nav-link" data-target="collection">
<span class="nav-dot"></span> Collection
</button>
<button class="nav-link" data-target="analytics">
<span class="nav-dot"></span> Analytics
</button>
<button class="nav-link" data-target="settings">
<span class="nav-dot"></span> Settings
</button>
</nav>
<!-- Page Stack -->
<main class="page-stack">
<!-- Home -->
<section class="page active" id="home">
<div class="page-eyebrow">Welcome back</div>
<h1 class="page-title">Good morning,<br><em>Constance.</em></h1>
<p class="page-body">Your studio has 3 new inquiries and 2 pending approvals. The autumn collection launches in 12 days — everything is on track.</p>
<div class="badge">New season ready</div>
<div class="card-grid">
<div class="card">
<div class="card-img" style="background:#f0ebe0">🎨</div>
<div class="card-info"><h3>Design Review</h3><p>Due tomorrow</p></div>
</div>
<div class="card">
<div class="card-img" style="background:#e8f0ed">📦</div>
<div class="card-info"><h3>Shipment #44</h3><p>In transit</p></div>
</div>
<div class="card">
<div class="card-img" style="background:#f0e8e8">✉️</div>
<div class="card-info"><h3>3 Inquiries</h3><p>Unread</p></div>
</div>
</div>
</section>
<!-- Collection -->
<section class="page" id="collection">
<div class="page-eyebrow">Autumn / Winter 2024</div>
<h1 class="page-title">The<br><em>Collection</em></h1>
<p class="page-body">Twelve pieces exploring the tension between restraint and excess. Hand-finished in our Milan atelier using deadstock fabrics sourced from Lyon.</p>
<div class="card-grid">
<div class="card">
<div class="card-img" style="background:#2a241c;color:white">01</div>
<div class="card-info"><h3>Overcoat Noir</h3><p>€2,400 · 4 left</p></div>
</div>
<div class="card">
<div class="card-img" style="background:#c9a84c;color:white">02</div>
<div class="card-info"><h3>Blazer Doré</h3><p>€1,800 · 2 left</p></div>
</div>
<div class="card">
<div class="card-img" style="background:#8a7e6e;color:white">03</div>
<div class="card-info"><h3>Trouser Taupe</h3><p>€980 · 8 left</p></div>
</div>
<div class="card">
<div class="card-img" style="background:#e8e2d8">04</div>
<div class="card-info"><h3>Shirt Ivoire</h3><p>€640 · 12 left</p></div>
</div>
</div>
</section>
<!-- Analytics -->
<section class="page" id="analytics">
<div class="page-eyebrow">Season performance</div>
<h1 class="page-title">Analytics<br><em>& Insights</em></h1>
<div class="stat-row">
<div class="stat-box">
<div class="stat-num">94k</div>
<div class="stat-label">Revenue</div>
</div>
<div class="stat-box">
<div class="stat-num">38</div>
<div class="stat-label">Orders</div>
</div>
<div class="stat-box">
<div class="stat-num">4.9</div>
<div class="stat-label">Avg Rating</div>
</div>
</div>
<p class="page-body">Revenue is up 22% versus the same period last year. The Overcoat Noir continues to be your strongest performer, accounting for 41% of total sales.</p>
</section>
<!-- Settings -->
<section class="page" id="settings">
<div class="page-eyebrow">Account</div>
<h1 class="page-title">Settings &<br><em>Preferences</em></h1>
<div class="setting-row">
<div>
<div class="setting-label">Email Notifications</div>
<div class="setting-desc">Receive alerts for new orders and inquiries</div>
</div>
<div class="toggle on" onclick="this.classList.toggle('on')"></div>
</div>
<div class="setting-row">
<div>
<div class="setting-label">Two-factor Authentication</div>
<div class="setting-desc">Extra layer of security for your account</div>
</div>
<div class="toggle on" onclick="this.classList.toggle('on')"></div>
</div>
<div class="setting-row">
<div>
<div class="setting-label">Public Profile</div>
<div class="setting-desc">Make your studio visible in directory listings</div>
</div>
<div class="toggle" onclick="this.classList.toggle('on')"></div>
</div>
<div class="setting-row">
<div>
<div class="setting-label">Beta Features</div>
<div class="setting-desc">Access experimental features before public launch</div>
</div>
<div class="toggle" onclick="this.classList.toggle('on')"></div>
</div>
</section>
</main>
</div> *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
:root {
--cream: #f5f0e8;
--ink: #1a1410;
--gold: #c9a84c;
--muted: #8a7e6e;
--card-bg: #fff;
--transition-dur: 600ms;
--transition-ease: cubic-bezier(0.4, 0, 0.2, 1);
}
html, body { height: 100%; font-family: 'DM Sans', sans-serif; background: var(--cream); color: var(--ink); overflow: hidden; }
/* Layout */
.shell {
display: grid;
grid-template-columns: 260px 1fr;
height: 100vh;
}
/* Sidebar nav */
.sidebar {
background: var(--ink);
padding: 48px 32px;
display: flex;
flex-direction: column;
gap: 0;
}
.sidebar-brand {
font-family: 'Cormorant Garamond', serif;
font-size: 22px;
font-weight: 300;
color: var(--cream);
letter-spacing: 0.08em;
margin-bottom: 56px;
line-height: 1.3;
}
.sidebar-brand span { color: var(--gold); }
.nav-label {
font-size: 9px;
letter-spacing: 0.2em;
text-transform: uppercase;
color: var(--muted);
margin-bottom: 16px;
}
.nav-link {
display: flex;
align-items: center;
gap: 12px;
padding: 14px 0;
color: #6b5f50;
text-decoration: none;
font-size: 14px;
font-weight: 400;
letter-spacing: 0.01em;
cursor: pointer;
transition: color 0.25s;
background: none; border-top: none; border-left: none; border-right: none;
border-bottom: 1px solid #2a241c;
width: 100%; text-align: left;
}
.nav-link:hover { color: var(--cream); }
.nav-link.active { color: var(--gold); }
.nav-dot {
width: 6px; height: 6px;
border-radius: 50%;
background: currentColor;
flex-shrink: 0;
}
/* Page stack */
.page-stack {
position: relative;
overflow: hidden;
}
.page {
position: absolute;
inset: 0;
padding: 64px 72px;
overflow-y: auto;
opacity: 0;
pointer-events: none;
transition: opacity var(--transition-dur) var(--transition-ease);
will-change: opacity;
}
.page.active {
opacity: 1;
pointer-events: auto;
}
/* Page content styles */
.page-eyebrow {
font-size: 10px;
letter-spacing: 0.25em;
text-transform: uppercase;
color: var(--gold);
margin-bottom: 20px;
}
.page-title {
font-family: 'Cormorant Garamond', serif;
font-size: clamp(36px, 5vw, 64px);
font-weight: 300;
line-height: 1.1;
color: var(--ink);
margin-bottom: 28px;
}
.page-title em { font-style: italic; color: var(--muted); }
.page-body {
font-size: 15px;
line-height: 1.8;
color: var(--muted);
max-width: 540px;
margin-bottom: 48px;
}
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
gap: 20px;
max-width: 680px;
}
.card {
background: white;
border-radius: 4px;
overflow: hidden;
box-shadow: 0 2px 12px rgba(0,0,0,0.06);
}
.card-img {
height: 130px;
display: flex;
align-items: center;
justify-content: center;
font-size: 40px;
}
.card-info { padding: 16px; }
.card-info h3 { font-size: 14px; font-weight: 500; margin-bottom: 4px; }
.card-info p { font-size: 12px; color: var(--muted); }
/* Stats page */
.stat-row {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 24px;
max-width: 600px;
margin-bottom: 40px;
}
.stat-box {
background: white;
border-radius: 4px;
padding: 28px 24px;
box-shadow: 0 2px 12px rgba(0,0,0,0.06);
}
.stat-num {
font-family: 'Cormorant Garamond', serif;
font-size: 48px;
font-weight: 300;
color: var(--ink);
line-height: 1;
margin-bottom: 8px;
}
.stat-label { font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted); }
/* Settings page */
.setting-row {
display: flex;
align-items: center;
justify-content: space-between;
padding: 20px 0;
border-bottom: 1px solid #e8e2d8;
max-width: 520px;
}
.setting-label { font-size: 14px; }
.setting-desc { font-size: 12px; color: var(--muted); margin-top: 4px; }
.toggle {
width: 44px; height: 24px;
background: #d1c9bc;
border-radius: 12px;
position: relative;
cursor: pointer;
transition: background 0.3s;
flex-shrink: 0;
}
.toggle.on { background: var(--gold); }
.toggle::after {
content: '';
position: absolute;
width: 18px; height: 18px;
background: white;
border-radius: 50%;
top: 3px; left: 3px;
transition: transform 0.3s;
box-shadow: 0 1px 4px rgba(0,0,0,0.2);
}
.toggle.on::after { transform: translateX(20px); }
/* Badge */
.badge {
display: inline-block;
padding: 4px 12px;
border-radius: 2px;
font-size: 10px;
letter-spacing: 0.12em;
text-transform: uppercase;
background: var(--gold);
color: white;
margin-bottom: 32px;
}
/* Mobile */
@media (max-width: 640px) {
.shell { grid-template-columns: 1fr; grid-template-rows: auto 1fr; }
.sidebar { padding: 24px 20px; flex-direction: row; align-items: center; flex-wrap: wrap; gap: 8px; }
.sidebar-brand { margin-bottom: 0; font-size: 18px; flex: 1; }
.nav-label { display: none; }
.nav-link { padding: 10px 16px; border: 1px solid #2a241c; border-radius: 20px; font-size: 12px; }
.page { padding: 32px 24px; }
.stat-row { grid-template-columns: 1fr 1fr; }
.card-grid { grid-template-columns: 1fr 1fr; }
} const links = document.querySelectorAll('.nav-link');
const pages = document.querySelectorAll('.page');
links.forEach(link => {
link.addEventListener('click', () => {
const target = link.dataset.target;
links.forEach(l => l.classList.remove('active'));
link.classList.add('active');
pages.forEach(page => {
if (page.id === target) {
page.classList.add('active');
} else {
page.classList.remove('active');
}
});
});
});