Vertical Split Curtain
Two full-height panels slide closed like theatre curtains, swap the page, then split apart with a different easing — a gold-seamed theatrical reveal. A Parisian haute couture house.
Vertical Split Curtain the 9th 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
<!-- Curtain panels -->
<div class="curtain-left" id="cLeft"></div>
<div class="curtain-right" id="cRight"></div>
<div class="pages">
<div class="page active" id="p0">
<div class="p0-layout">
<div class="p0-left">
<div class="p0-mark">Maison Lécluse · Paris</div>
<div class="p0-main">
<div class="p0-season">Automne–Hiver 2025</div>
<h1 class="p0-title">Entre<br>Ombre<br>& Lumière</h1>
<div class="p0-title-fr">Between shadow and light</div>
<p class="p0-body">A collection born from the silences between words. Forty-two looks. Each one a conversation the body has alone.</p>
<button class="p0-cta" data-next="1">Discover the collection <span class="p0-cta-arrow"></span></button>
</div>
</div>
<div class="p0-right">
<div class="silhouette-area">
<div class="figure">
<div class="fig-head"></div>
<div class="fig-arm fig-arm-l"></div>
<div class="fig-arm fig-arm-r"></div>
<div class="fig-body"></div>
</div>
</div>
<div class="p0-right-bottom">
<div class="p0-detail-row"><div class="det-key">Maison</div><div class="det-val">Since 1967</div></div>
<div class="p0-detail-row"><div class="det-key">Ateliers</div><div class="det-val">Paris · Florence</div></div>
<div class="p0-detail-row"><div class="det-key">Collection</div><div class="det-val">AH 2025 · 42 looks</div></div>
<div class="p0-detail-row"><div class="det-key">Runway</div><div class="det-val">Palais Royal, 4 Oct</div></div>
</div>
</div>
</div>
</div>
<div class="page" id="p1">
<div class="p1-top">
<h2 class="p1-title">The<br>Collection</h2>
<div class="p1-count">42 Looks · AH 2025</div>
</div>
<div class="look-grid">
<div class="look"><div class="look-img"><div class="garment g1"></div></div><div class="look-num">Look 01</div><div class="look-name">L'aube noire</div></div>
<div class="look"><div class="look-img"><div class="garment g2"></div></div><div class="look-num">Look 07</div><div class="look-name">Le voile froid</div></div>
<div class="look"><div class="look-img"><div class="garment g3"></div></div><div class="look-num">Look 14</div><div class="look-name">La colonne</div></div>
<div class="look"><div class="look-img"><div class="garment g4"></div></div><div class="look-num">Look 21</div><div class="look-name">Le bruissement</div></div>
<div class="look"><div class="look-img"><div class="garment g5"></div></div><div class="look-num">Look 38</div><div class="look-name">La chute</div></div>
</div>
</div>
<div class="page" id="p2">
<div class="p2-left">
<div class="p2-eyebrow">L'Atelier Lécluse</div>
<h2 class="p2-title">Made by<br>hand, in<br>silence</h2>
<p class="p2-body">Each garment passes through twenty-four pairs of hands before it leaves the atelier. We consider this not a process, but a conversation with the material.</p>
<div class="craft-list">
<div class="craft-row"><div class="craft-n">I</div><div class="craft-t">Pattern cutting by master tailleur</div></div>
<div class="craft-row"><div class="craft-n">II</div><div class="craft-t">Hand-draping on the mannequin</div></div>
<div class="craft-row"><div class="craft-n">III</div><div class="craft-t">Three fittings per garment minimum</div></div>
<div class="craft-row"><div class="craft-n">IV</div><div class="craft-t">Handstitched finishing throughout</div></div>
<div class="craft-row"><div class="craft-n">V</div><div class="craft-t">Final inspection by the directrice</div></div>
</div>
</div>
<div class="p2-right">
<div class="maison-since">Maison Lécluse · Since 1967</div>
<div class="p2-numbers">
<div class="num-item"><div class="num-big">58</div><div class="num-label">Years of haute<br>couture</div></div>
<div class="num-item"><div class="num-big">24</div><div class="num-label">Artisan hands per<br>garment</div></div>
<div class="num-item"><div class="num-big">200+</div><div class="num-label">Hours in a single<br>couture piece</div></div>
</div>
</div>
</div>
<div class="page" id="p3">
<div class="p3-bg-text">ML</div>
<div class="p3-content">
<span class="p3-mark">Maison Lécluse · Paris</span>
<h2 class="p3-title">Private<br>Fitting</h2>
<p class="p3-sub">By appointment only. Ateliers are open to clients for consultation from Tuesday through Saturday.</p>
<div class="p3-contact-grid">
<div class="p3-contact-row"><div class="p3-contact-key">Address</div><div class="p3-contact-val">24 Rue du Faubourg Saint-Honoré</div></div>
<div class="p3-contact-row"><div class="p3-contact-key">Telephone</div><div class="p3-contact-val">+33 1 42 68 00 00</div></div>
<div class="p3-contact-row"><div class="p3-contact-key">Fitting hours</div><div class="p3-contact-val">Mar–Sam · 10h–18h</div></div>
<div class="p3-contact-row"><div class="p3-contact-key">Correspondence</div><div class="p3-contact-val">[email protected]</div></div>
</div>
</div>
</div>
</div>
<!-- Nav -->
<div class="c-nav">
<button class="c-btn" id="cPrev">‹</button>
<div class="c-dots">
<button class="c-dot active" data-i="0"></button>
<button class="c-dot" data-i="1"></button>
<button class="c-dot" data-i="2"></button>
<button class="c-dot" data-i="3"></button>
</div>
<div class="c-label" id="cLabel">Maison</div>
<button class="c-btn" id="cNext">›</button>
</div> *,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
:root{
--noir:#080808;
--white:#f8f4f0;
--warm:#e8e0d4;
--dim:rgba(248,244,240,0.4);
--accent:#c8a060;
--mid:rgba(248,244,240,0.1);
--dur:900ms;
--ease:cubic-bezier(0.76,0,0.24,1);
}
html,body{height:100%;overflow:hidden;background:var(--noir);font-family:'Cormorant Garamond',serif;}
/* Pages */
.pages{position:fixed;inset:0;}
.page{position:absolute;inset:0;pointer-events:none;visibility:hidden;}
.page.active{visibility:visible;pointer-events:auto;}
/* Curtain panels */
.curtain-left,.curtain-right{
position:fixed;top:0;bottom:0;z-index:700;
background:var(--noir);
will-change:transform;
}
.curtain-left{
left:0;width:50%;
transform:translateX(-100%);
transform-origin:left;
}
.curtain-right{
right:0;width:50%;
transform:translateX(100%);
transform-origin:right;
}
/* Centre seam line */
.curtain-left::after{
content:'';
position:absolute;right:0;top:0;bottom:0;
width:1px;
background:linear-gradient(180deg,transparent,var(--accent),transparent);
opacity:0;
}
/* States */
.curtain-left.close{transform:translateX(0);}
.curtain-right.close{transform:translateX(0);}
.curtain-left.close::after{opacity:0.4;}
/* PAGE 0 — MAISON */
#p0{background:var(--noir);color:var(--white);}
.p0-layout{
height:100%;
display:grid;grid-template-columns:1fr 1fr;
}
.p0-left{
padding:60px 80px;
display:flex;flex-direction:column;
justify-content:space-between;
border-right:1px solid var(--mid);
}
.p0-mark{
font-family:'Italiana',serif;
font-size:11px;letter-spacing:0.4em;text-transform:uppercase;
color:var(--dim);
}
.p0-main{
flex:1;display:flex;flex-direction:column;justify-content:flex-end;
padding-bottom:20px;
}
.p0-season{
font-size:8px;letter-spacing:0.4em;text-transform:uppercase;
color:var(--accent);margin-bottom:24px;
display:flex;align-items:center;gap:12px;
}
.p0-season::before{
content:'';width:20px;height:1px;background:var(--accent);
}
.p0-title{
font-family:'Italiana',serif;
font-size:clamp(52px,8vw,112px);
font-weight:400;line-height:0.9;
letter-spacing:-0.02em;
color:var(--white);margin-bottom:24px;
}
.p0-title-fr{
font-size:clamp(24px,3.5vw,48px);
font-style:italic;font-weight:300;
color:rgba(248,244,240,0.35);margin-bottom:40px;
}
.p0-body{
font-size:13px;line-height:1.9;font-weight:300;
color:var(--dim);max-width:380px;font-style:italic;
}
.p0-cta{
margin-top:40px;
display:inline-flex;align-items:center;gap:16px;
font-size:9px;letter-spacing:0.3em;text-transform:uppercase;
color:var(--white);cursor:pointer;background:none;border:none;
font-family:'Didact Gothic',sans-serif;
transition:color .2s;
}
.p0-cta:hover{color:var(--accent);}
.p0-cta-arrow{
width:40px;height:1px;background:currentColor;
transition:width .3s;position:relative;
}
.p0-cta-arrow::after{
content:'';position:absolute;right:-1px;top:-3px;
width:7px;height:7px;
border-right:1px solid currentColor;
border-top:1px solid currentColor;
transform:rotate(45deg);
}
.p0-cta:hover .p0-cta-arrow{width:64px;}
.p0-right{
display:grid;grid-template-rows:1fr 1fr;
padding:60px;
gap:0;
}
/* Abstract fashion illustration using CSS shapes */
.silhouette-area{
display:flex;align-items:center;justify-content:center;
position:relative;
}
.figure{
position:relative;
width:80px;height:200px;
}
.fig-body{
position:absolute;bottom:0;left:50%;transform:translateX(-50%);
width:48px;height:140px;
background:linear-gradient(180deg,rgba(200,160,96,0.2),rgba(200,160,96,0.06));
border:1px solid rgba(200,160,96,0.2);
border-radius:2px 2px 0 0;
}
.fig-head{
position:absolute;bottom:136px;left:50%;transform:translateX(-50%);
width:20px;height:24px;
border-radius:50%;
background:rgba(200,160,96,0.15);
border:1px solid rgba(200,160,96,0.2);
}
.fig-arm{
position:absolute;
height:1px;background:rgba(200,160,96,0.25);
top:72px;
}
.fig-arm-l{width:32px;right:48px;}
.fig-arm-r{width:32px;left:48px;}
.p0-right-bottom{
display:flex;flex-direction:column;justify-content:flex-end;
gap:16px;
}
.p0-detail-row{
display:flex;justify-content:space-between;align-items:baseline;
border-bottom:1px solid var(--mid);
padding:12px 0;
}
.det-key{
font-size:8px;letter-spacing:0.25em;text-transform:uppercase;
color:rgba(248,244,240,0.25);
font-family:'Didact Gothic',sans-serif;
}
.det-val{
font-size:12px;font-style:italic;
color:rgba(248,244,240,0.6);
}
/* PAGE 1 — COLLECTION */
#p1{
background:#0c0c0c;
color:var(--white);
padding:60px 80px;
display:flex;flex-direction:column;
}
.p1-top{
display:flex;align-items:flex-end;justify-content:space-between;
margin-bottom:52px;
padding-bottom:24px;
border-bottom:1px solid var(--mid);
}
.p1-title{
font-family:'Italiana',serif;
font-size:clamp(44px,7vw,100px);
font-weight:400;line-height:0.9;
letter-spacing:-0.02em;
}
.p1-count{
font-size:9px;letter-spacing:0.25em;
color:var(--dim);font-family:'Didact Gothic',sans-serif;
text-transform:uppercase;
}
.look-grid{
display:grid;
grid-template-columns:repeat(5,1fr);
gap:12px;
flex:1;
}
.look{
display:flex;flex-direction:column;gap:12px;
cursor:pointer;
}
.look-img{
flex:1;
border:1px solid rgba(248,244,240,0.06);
position:relative;overflow:hidden;
min-height:200px;
background:linear-gradient(180deg,#111,#0a0a0a);
transition:border-color .3s;
}
.look:hover .look-img{border-color:rgba(200,160,96,0.3);}
/* Abstract garment shape */
.garment{
position:absolute;bottom:0;left:50%;transform:translateX(-50%);
width:60%;
background:rgba(200,160,96,0.08);
border-top:1px solid rgba(200,160,96,0.15);
}
.g1{height:70%;border-radius:2px 2px 0 0;}
.g2{height:85%;clip-path:polygon(20% 0,80% 0,100% 100%,0 100%);}
.g3{height:60%;border-radius:40% 40% 0 0;}
.g4{height:75%;clip-path:polygon(0 0,100% 0,90% 100%,10% 100%);}
.g5{height:90%;clip-path:polygon(30% 0,70% 0,100% 100%,0 100%);}
.look-num{
font-size:8px;letter-spacing:0.2em;
color:var(--accent);font-family:'Didact Gothic',sans-serif;
}
.look-name{
font-family:'Cormorant Garamond',serif;
font-size:13px;font-style:italic;color:rgba(248,244,240,0.7);
}
/* PAGE 2 — ATELIER */
#p2{
background:var(--white);
color:var(--noir);
display:grid;grid-template-columns:1fr 1fr;
}
.p2-left{
padding:80px;
display:flex;flex-direction:column;justify-content:center;
background:#f0ece6;
}
.p2-eyebrow{
font-size:8px;letter-spacing:0.35em;text-transform:uppercase;
color:var(--accent);margin-bottom:28px;
font-family:'Didact Gothic',sans-serif;
}
.p2-title{
font-family:'Italiana',serif;
font-size:clamp(44px,6vw,80px);
font-weight:400;line-height:1.0;
color:var(--noir);letter-spacing:-0.02em;
margin-bottom:28px;
}
.p2-body{
font-size:15px;line-height:1.85;font-weight:300;font-style:italic;
color:rgba(8,8,8,0.5);max-width:400px;margin-bottom:48px;
}
.craft-list{
display:flex;flex-direction:column;gap:0;
}
.craft-row{
display:flex;gap:20px;
padding:18px 0;
border-bottom:1px solid rgba(8,8,8,0.08);
align-items:baseline;
}
.craft-n{
font-size:9px;letter-spacing:0.15em;
color:var(--accent);
font-family:'Didact Gothic',sans-serif;
width:24px;flex-shrink:0;
}
.craft-t{
font-size:14px;font-style:italic;color:rgba(8,8,8,0.6);
}
.p2-right{
padding:80px;
background:var(--white);
display:flex;flex-direction:column;justify-content:center;
border-left:1px solid rgba(8,8,8,0.06);
}
.maison-since{
font-size:9px;letter-spacing:0.35em;text-transform:uppercase;
color:rgba(8,8,8,0.25);margin-bottom:40px;
font-family:'Didact Gothic',sans-serif;
}
.p2-numbers{
display:flex;flex-direction:column;gap:28px;
}
.num-item{
display:flex;align-items:baseline;gap:20px;
padding-bottom:28px;
border-bottom:1px solid rgba(8,8,8,0.06);
}
.num-big{
font-family:'Italiana',serif;
font-size:56px;color:var(--noir);line-height:1;
}
.num-label{
font-size:12px;font-style:italic;color:rgba(8,8,8,0.45);
line-height:1.4;
}
/* PAGE 3 — CONTACT */
#p3{
background:var(--noir);color:var(--white);
display:flex;align-items:center;justify-content:center;
text-align:center;padding:80px;
position:relative;overflow:hidden;
}
.p3-bg-text{
position:absolute;
font-family:'Italiana',serif;
font-size:30vw;color:rgba(248,244,240,0.025);
line-height:1;letter-spacing:-0.06em;
pointer-events:none;
user-select:none;
}
.p3-content{position:relative;max-width:560px;}
.p3-mark{
font-family:'Italiana',serif;
font-size:9px;letter-spacing:0.5em;text-transform:uppercase;
color:var(--dim);margin-bottom:48px;display:block;
}
.p3-title{
font-family:'Italiana',serif;
font-size:clamp(44px,8vw,100px);
font-weight:400;line-height:0.9;
letter-spacing:-0.02em;
color:var(--white);margin-bottom:16px;
}
.p3-sub{
font-size:14px;font-style:italic;
color:var(--dim);margin-bottom:48px;
line-height:1.7;
}
.p3-contact-grid{
display:flex;flex-direction:column;gap:16px;
border-top:1px solid var(--mid);
padding-top:36px;
}
.p3-contact-row{
display:flex;justify-content:space-between;
align-items:baseline;padding:8px 0;
border-bottom:1px solid var(--mid);
}
.p3-contact-key{
font-size:8px;letter-spacing:0.25em;text-transform:uppercase;
color:rgba(248,244,240,0.25);
font-family:'Didact Gothic',sans-serif;
}
.p3-contact-val{
font-size:13px;font-style:italic;
color:rgba(248,244,240,0.65);
}
/* Curtain nav */
.c-nav{
position:fixed;bottom:40px;left:50%;transform:translateX(-50%);
z-index:800;
display:flex;align-items:center;gap:24px;
background:rgba(8,8,8,0.7);
border:1px solid var(--mid);
padding:16px 32px;
backdrop-filter:blur(20px);
}
.c-label{
font-size:8px;letter-spacing:0.3em;text-transform:uppercase;
color:var(--dim);
font-family:'Didact Gothic',sans-serif;
min-width:80px;text-align:center;
}
.c-btn{
width:36px;height:36px;
border:1px solid var(--mid);
background:none;color:var(--dim);
font-size:16px;cursor:pointer;
display:flex;align-items:center;justify-content:center;
transition:border-color .2s,color .2s;
font-family:serif;
}
.c-btn:hover{border-color:var(--accent);color:var(--accent);}
.c-dots{display:flex;gap:8px;}
.c-dot{
width:3px;height:3px;border-radius:50%;
background:rgba(248,244,240,0.2);border:none;cursor:pointer;
transition:background .25s,transform .3s;
}
.c-dot.active{background:var(--accent);transform:scale(1.8);}
@media(max-width:768px){
#p0 .p0-layout{grid-template-columns:1fr;}
.p0-right{display:none;}
.p0-left{padding:40px 28px;}
#p1{padding:40px 24px;}
.look-grid{grid-template-columns:repeat(2,1fr);}
#p2{grid-template-columns:1fr;}
.p2-right{display:none;}
.p2-left{padding:40px 28px;}
#p3{padding:40px 28px;}
} const cLeft=document.getElementById('cLeft');
const cRight=document.getElementById('cRight');
const pages=document.querySelectorAll('.page');
const cdots=document.querySelectorAll('.c-dot');
const cLabel=document.getElementById('cLabel');
const labels=['Maison','Collection','Atelier','Contact'];
let cur=0,busy=false;
const dur=900;
function curtainTransition(prev,next,done){
cLeft.style.transition=`transform ${dur*0.4}ms cubic-bezier(0.76,0,0.24,1)`;
cRight.style.transition=`transform ${dur*0.4}ms cubic-bezier(0.76,0,0.24,1)`;
cLeft.classList.add('close');
cRight.classList.add('close');
setTimeout(()=>{
pages[prev].classList.remove('active');
pages[next].classList.add('active');
cLeft.style.transition=`transform ${dur*0.55}ms cubic-bezier(0.25,1,0.5,1)`;
cRight.style.transition=`transform ${dur*0.55}ms cubic-bezier(0.25,1,0.5,1)`;
cLeft.classList.remove('close');
cRight.classList.remove('close');
setTimeout(()=>{ done&&done(); },dur*0.6);
},dur*0.42);
}
function goTo(n){
if(busy||n===cur)return;
busy=true;
const prev=cur;cur=n;
cdots.forEach((d,i)=>d.classList.toggle('active',i===cur));
cLabel.textContent=labels[cur];
curtainTransition(prev,cur,()=>{busy=false;});
}
document.getElementById('cNext').onclick=()=>goTo(Math.min(3,cur+1));
document.getElementById('cPrev').onclick=()=>goTo(Math.max(0,cur-1));
cdots.forEach(d=>d.addEventListener('click',()=>goTo(+d.dataset.i)));
document.querySelectorAll('[data-next]').forEach(b=>b.addEventListener('click',()=>goTo(+b.dataset.next)));
let wt=0;
window.addEventListener('wheel',e=>{
const now=Date.now();if(now-wt<1100)return;wt=now;
goTo(Math.max(0,Math.min(3,cur+(e.deltaY>0?1:-1))));
},{passive:true});
document.addEventListener('keydown',e=>{
if(e.key==='ArrowRight')goTo(Math.min(3,cur+1));
if(e.key==='ArrowLeft')goTo(Math.max(0,cur-1));
});