22 CSS Transition Effects 11 / 22

Modal Open Close Transition

Six modal entrance animations: scale-in, slide-up, flip-in, bounce overshoot, slide-right and unfold, with backdrop-filter blur overlay.

CSS + JS MIT licensed
Live Demo Open in tab

This is a full-page demo — interact inside the frame above, or open it in the playground for the full-screen experience.

Open in playground

The code

<div class="wrap">
  <h1>Modal Transitions</h1>
  <p class="sub">6 CSS transition effects for opening and closing modals — click each to preview</p>

  <div id="animInfo" class="anim-info">Click any button below to open its modal variant</div>

  <span class="sl">Open a modal</span>
  <h2>6 entrance animations</h2>
  <div class="grid">
    <button class="trig-btn" style="--c:#059669" onclick="openModal('m1')">⬆ Scale in</button>
    <button class="trig-btn" style="--c:#7c3aed" onclick="openModal('m2')">⬆ Slide up</button>
    <button class="trig-btn" style="--c:#0ea5e9" onclick="openModal('m3')">↻ Flip in</button>
    <button class="trig-btn" style="--c:#f97316" onclick="openModal('m4')">🎯 Bounce</button>
    <button class="trig-btn" style="--c:#ec4899" onclick="openModal('m5')">→ Slide right</button>
    <button class="trig-btn" style="--c:#d97706" onclick="openModal('m6')">⬇ Unfold</button>
  </div>
</div>

<!-- Modal 1 — Scale in (success) -->
<div class="overlay" id="m1" onclick="if(event.target===this)closeModal('m1')">
  <div class="modal m-scale">
    <button class="mclose" onclick="closeModal('m1')">✕</button>
    <div class="modal-type">Scale entrance</div>
    <span class="modal-icon">✅</span>
    <h3>Deployment complete</h3>
    <p>Your application has been deployed to production successfully. All 4 health checks passed with zero downtime.</p>
    <div class="modal-actions">
      <button class="m-primary" onclick="closeModal('m1')">View deployment</button>
      <button class="m-secondary" onclick="closeModal('m1')">Dismiss</button>
    </div>
  </div>
</div>

<!-- Modal 2 — Slide up (default) -->
<div class="overlay" id="m2" onclick="if(event.target===this)closeModal('m2')">
  <div class="modal m-slideup">
    <button class="mclose" onclick="closeModal('m2')">✕</button>
    <div class="modal-type">Slide up entrance</div>
    <span class="modal-icon">🚀</span>
    <h3>Start your free trial</h3>
    <p>Get full access to all Pro features for 14 days. No credit card required. Cancel any time.</p>
    <div class="modal-actions">
      <button class="m-primary" onclick="closeModal('m2')">Start free trial</button>
      <button class="m-secondary" onclick="closeModal('m2')">Maybe later</button>
    </div>
  </div>
</div>

<!-- Modal 3 — Flip in (info) -->
<div class="overlay" id="m3" onclick="if(event.target===this)closeModal('m3')">
  <div class="modal m-flip var-info">
    <button class="mclose" onclick="closeModal('m3')">✕</button>
    <div class="modal-type">Flip entrance</div>
    <span class="modal-icon">ℹ️</span>
    <h3>Update available</h3>
    <p>Version 4.2.0 is ready to install. This update includes performance improvements and 3 bug fixes.</p>
    <div class="modal-actions">
      <button class="m-primary" onclick="closeModal('m3')">Install now</button>
      <button class="m-secondary" onclick="closeModal('m3')">Remind later</button>
    </div>
  </div>
</div>

<!-- Modal 4 — Bounce -->
<div class="overlay" id="m4" onclick="if(event.target===this)closeModal('m4')">
  <div class="modal m-bounce">
    <button class="mclose" onclick="closeModal('m4')">✕</button>
    <div class="modal-type">Bounce entrance</div>
    <span class="modal-icon">🎉</span>
    <h3>Congratulations!</h3>
    <p>You've unlocked the Pro tier. All premium features are now active on your account.</p>
    <div class="modal-actions">
      <button class="m-primary" onclick="closeModal('m4')">Explore features</button>
      <button class="m-secondary" onclick="closeModal('m4')">Close</button>
    </div>
  </div>
</div>

<!-- Modal 5 — Slide from right -->
<div class="overlay" id="m5" onclick="if(event.target===this)closeModal('m5')">
  <div class="modal m-right var-err">
    <button class="mclose" onclick="closeModal('m5')">✕</button>
    <div class="modal-type">Slide right entrance</div>
    <span class="modal-icon">⚠️</span>
    <h3>Delete this workspace?</h3>
    <p>This action cannot be undone. All projects, data and team members will be permanently removed.</p>
    <div class="modal-actions">
      <button class="m-primary" onclick="closeModal('m5')">Delete permanently</button>
      <button class="m-secondary" onclick="closeModal('m5')">Cancel</button>
    </div>
  </div>
</div>

<!-- Modal 6 — Unfold -->
<div class="overlay" id="m6" onclick="if(event.target===this)closeModal('m6')">
  <div class="modal m-unfold var-warn" style="max-width:480px">
    <button class="mclose" onclick="closeModal('m6')">✕</button>
    <div class="modal-type">Unfold entrance</div>
    <span class="modal-icon">⚡</span>
    <h3>Usage limit approaching</h3>
    <p>You've used 89% of your monthly API quota. Upgrade to Pro to avoid service interruption.</p>
    <div class="modal-actions">
      <button class="m-primary" onclick="closeModal('m6')">Upgrade plan</button>
      <button class="m-secondary" onclick="closeModal('m6')">Dismiss</button>
    </div>
  </div>
</div>
@import url('https://fonts.googleapis.com/css2?family=Epilogue:wght@400;600;700;800&display=swap');
*{margin:0;padding:0;box-sizing:border-box}
body{font-family:'Epilogue',sans-serif;background:#ecfdf5;color:#0f172a;min-height:100vh;padding:60px 24px}
.wrap{max-width:1000px;margin:0 auto}
h1{font-size:clamp(2rem,5vw,3rem);font-weight:800;text-align:center;margin-bottom:8px;letter-spacing:-.03em;color:#0f172a}
.sub{text-align:center;color:#64748b;margin-bottom:56px}
.sl{font-size:.68rem;font-weight:700;letter-spacing:.25em;text-transform:uppercase;color:#10b981;margin-bottom:12px;display:block}
h2{font-size:1.15rem;font-weight:700;margin-bottom:20px}
.grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:16px;margin-bottom:48px}
.trig-btn{padding:14px 24px;border-radius:10px;font-family:'Epilogue';font-weight:700;font-size:.9rem;cursor:pointer;border:none;background:var(--c,#059669);color:#fff;transition:transform .1s,filter .2s;display:flex;align-items:center;justify-content:center;gap:8px}
.trig-btn:hover{filter:brightness(1.1)}
.trig-btn:active{transform:scale(.97)}

/* OVERLAY */
.overlay{position:fixed;inset:0;background:rgba(0,0,0,.5);backdrop-filter:blur(4px);z-index:100;display:flex;align-items:center;justify-content:center;padding:20px;
  opacity:0;pointer-events:none;transition:opacity .3s}
.overlay.open{opacity:1;pointer-events:auto}

/* MODAL BASE */
.modal{background:#fff;border-radius:20px;padding:36px;width:100%;max-width:480px;position:relative;
  box-shadow:0 24px 80px rgba(0,0,0,.25)}

/* Modal close btn */
.mclose{position:absolute;top:16px;right:16px;width:32px;height:32px;border-radius:50%;background:#f1f5f9;border:none;font-size:1rem;cursor:pointer;display:grid;place-items:center;color:#64748b;transition:background .2s}
.mclose:hover{background:#e2e8f0;color:#0f172a}

/* M1 — Scale in */
.m-scale{transform:scale(.85);transition:transform .35s cubic-bezier(.34,1.56,.64,1),opacity .25s}
.overlay.open .m-scale{transform:scale(1)}
.overlay:not(.open) .m-scale{transform:scale(.85)}

/* M2 — Slide up */
.m-slideup{transform:translateY(60px);opacity:0;transition:transform .4s cubic-bezier(.22,1,.36,1),opacity .3s}
.overlay.open .m-slideup{transform:translateY(0);opacity:1}

/* M3 — Flip in */
.m-flip{transform:perspective(800px) rotateX(-20deg);opacity:0;transform-origin:top;transition:transform .4s cubic-bezier(.22,1,.36,1),opacity .3s}
.overlay.open .m-flip{transform:perspective(800px) rotateX(0);opacity:1}

/* M4 — Bounce */
.m-bounce{transform:scale(.3);opacity:0;transition:transform .5s cubic-bezier(.34,1.8,.64,1),opacity .2s}
.overlay.open .m-bounce{transform:scale(1);opacity:1}

/* M5 — Slide from right */
.m-right{transform:translateX(80px);opacity:0;transition:transform .4s cubic-bezier(.22,1,.36,1),opacity .3s}
.overlay.open .m-right{transform:translateX(0);opacity:1}

/* M6 — Unfold (height expand) */
.m-unfold{max-height:0;overflow:hidden;opacity:0;transition:max-height .5s cubic-bezier(.22,1,.36,1),opacity .4s .1s;padding:0 36px}
.overlay.open .m-unfold{max-height:500px;opacity:1;padding:36px}

/* modal content shared */
.modal h3{font-size:1.25rem;font-weight:700;margin-bottom:8px}
.modal p{font-size:.9rem;color:#64748b;line-height:1.6;margin-bottom:20px}
.modal-actions{display:flex;gap:10px}
.m-primary{flex:1;padding:12px;border-radius:8px;background:#059669;color:#fff;font-family:'Epilogue';font-weight:700;font-size:.9rem;border:none;cursor:pointer;transition:background .2s}
.m-primary:hover{background:#047857}
.m-secondary{flex:1;padding:12px;border-radius:8px;background:#f1f5f9;color:#0f172a;font-family:'Epilogue';font-weight:700;font-size:.9rem;border:none;cursor:pointer;transition:background .2s}
.m-secondary:hover{background:#e2e8f0}
.modal-type{font-size:.68rem;font-weight:700;letter-spacing:.2em;text-transform:uppercase;color:#10b981;margin-bottom:12px}
.modal-icon{font-size:2.5rem;margin-bottom:12px;display:block}

/* variant colours */
.var-warn h3{color:#d97706}
.var-warn .m-primary{background:#d97706}
.var-warn .m-primary:hover{background:#b45309}
.var-warn .modal-type{color:#d97706}
.var-err h3{color:#dc2626}
.var-err .m-primary{background:#dc2626}
.var-err .m-primary:hover{background:#b91c1c}
.var-err .modal-type{color:#dc2626}
.var-info h3{color:#2563eb}
.var-info .m-primary{background:#2563eb}
.var-info .m-primary:hover{background:#1d4ed8}
.var-info .modal-type{color:#2563eb}

/* current info badge */
.anim-info{background:#f0fdf4;border:1px solid #bbf7d0;border-radius:8px;padding:12px 16px;font-size:.8rem;color:#166534;margin-bottom:40px}

@media (prefers-reduced-motion:reduce){.modal,.overlay{transition:none !important;transform:none !important}}
function openModal(id){
  document.getElementById(id).classList.add('open');
  document.getElementById('animInfo').textContent='Transition: ' + {m1:'scale(.85) → scale(1)',m2:'translateY(60px) → translateY(0)',m3:'perspective rotateX(-20deg) → rotateX(0)',m4:'scale(.3) → scale(1) with overshoot',m5:'translateX(80px) → translateX(0)',m6:'max-height 0 → 500px'}[id];
}
function closeModal(id){ document.getElementById(id).classList.remove('open'); }
document.addEventListener('keydown', e=>{ if(e.key==='Escape') document.querySelectorAll('.overlay.open').forEach(m=>m.classList.remove('open')); });

Search CodeFronts

Loading…