18 CSS Slide In Animation Templates17 / 18

Pure CSSMIT licensed

Cookie Consent Banner Slide-In

A GDPR/CCPA-compliant cookie consent banner that slides up from the bottom edge showing plain-language consent copy, three action buttons (Accept all / Reject all / Customize), and a Privacy Policy link — the pattern required for EU/CA compliance and used by every major website since 2018.

Published

Live Demo
Try it

The code

<div class="sl-17">
  <div class="sl-17__banner" role="region" aria-label="Cookie consent">
    <div class="sl-17__body">
      <p class="sl-17__title">We value your privacy</p>
      <p class="sl-17__copy">We use cookies to enhance your browsing experience, analyze site traffic, and improve our services. You can accept all cookies, reject non-essential ones, or customize your preferences. Read our <a href="#">Privacy Policy</a> and <a href="#">Cookie Policy</a> for details.</p>
    </div>
    <div class="sl-17__actions">
      <button class="sl-17__btn sl-17__btn--ghost">Customize</button>
      <button class="sl-17__btn sl-17__btn--secondary">Reject all</button>
      <button class="sl-17__btn sl-17__btn--primary">Accept all</button>
    </div>
  </div>
</div>
.sl-17 {
  --bg: #f5f5f7;
  --banner: #0a0a14;
  --accent: #8b5cf6;
  --text: #f4f4f5;
  --sub: #a1a1aa;
  --line: rgba(255,255,255,.1);
  font-family: -apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
  min-height: 100vh;
  padding: 32px;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  background: var(--bg);
  color: #333;
  overflow: hidden;
}

.sl-17 *,
.sl-17 *::before,
.sl-17 *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.sl-17 ::selection {
  background: var(--accent);
  color: #fff;
}

.sl-17__banner {
  display: flex;
  align-items: center;
  gap: 20px;
  width: min(920px,100%);
  padding: 20px 24px;
  border-radius: 14px;
  background: var(--banner);
  color: var(--text);
  border: 1px solid var(--line);
  box-shadow: 0 30px 60px -20px rgba(0,0,0,.5);
  opacity: 0;
  transform: translateY(100%);
  animation: sl-17-in .5s cubic-bezier(.16,1,.3,1) .4s forwards;
}

.sl-17__body {
  flex: 1;
  min-width: 0;
}

.sl-17__title {
  font-size: .95rem;
  font-weight: 700;
  letter-spacing: -.01em;
  color: var(--text);
  margin-bottom: 4px;
}

.sl-17__copy {
  font-size: .82rem;
  color: var(--sub);
  line-height: 1.5;
}

.sl-17__copy a {
  color: var(--text);
  text-decoration: underline;
}

.sl-17__copy a:hover {
  color: var(--accent);
}

.sl-17__actions {
  display: flex;
  gap: 8px;
  flex-shrink: 0;
}

.sl-17__btn {
  padding: 10px 18px;
  border: none;
  border-radius: 8px;
  font-family: inherit;
  font-size: .82rem;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
  transition: background .18s ease,transform .12s ease;
}

.sl-17__btn:active {
  transform: translateY(1px);
}

.sl-17__btn--ghost {
  background: transparent;
  color: var(--sub);
  border: 1px solid transparent;
}

.sl-17__btn--ghost:hover {
  color: var(--text);
}

.sl-17__btn--secondary {
  background: rgba(255,255,255,.08);
  color: var(--text);
  border: 1px solid rgba(255,255,255,.14);
}

.sl-17__btn--secondary:hover {
  background: rgba(255,255,255,.14);
}

.sl-17__btn--primary {
  background: var(--text);
  color: var(--banner);
  border: 1px solid var(--text);
}

.sl-17__btn--primary:hover {
  background: #fff;
  color: #0a0a14;
}

@keyframes sl-17-in {
  from {
    opacity: 0;
    transform: translateY(100%);
  }

  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@media (prefers-reduced-motion: reduce) {
  .sl-17__banner {
    animation: none!important;
    opacity: 1!important;
    transform: none!important;
  }
}

@media (max-width: 720px) {
  .sl-17__banner {
    flex-direction: column;
    align-items: stretch;
    text-align: left;
    padding: 16px 18px;
  }

  .sl-17__actions {
    justify-content: flex-end;
    flex-wrap: wrap;
  }

  .sl-17__btn {
    flex: 1;
    min-width: 0;
  }
}
Paste this into ChatGPT, Claude, Cursor, or any coding assistant. The block below is pre-framed with everything the AI needs to integrate this demo into your project — markup, styles, scoping notes, and the source URL. Hit Copy and paste straight into your chat.
Here's a working CSS Slide In Animation Template from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Cookie Consent Banner Slide-In
Source: https://codefronts.com/motion/css-slide-in-animation/cookie-consent-banner-slide-in/

A GDPR/CCPA-compliant cookie consent banner that slides up from the bottom edge showing plain-language consent copy, three action buttons (Accept all / Reject all / Customize), and a Privacy Policy link — the pattern required for EU/CA compliance and used by every major website since 2018.
## HTML
```html
<div class="sl-17">
  <div class="sl-17__banner" role="region" aria-label="Cookie consent">
    <div class="sl-17__body">
      <p class="sl-17__title">We value your privacy</p>
      <p class="sl-17__copy">We use cookies to enhance your browsing experience, analyze site traffic, and improve our services. You can accept all cookies, reject non-essential ones, or customize your preferences. Read our <a href="#">Privacy Policy</a> and <a href="#">Cookie Policy</a> for details.</p>
    </div>
    <div class="sl-17__actions">
      <button class="sl-17__btn sl-17__btn--ghost">Customize</button>
      <button class="sl-17__btn sl-17__btn--secondary">Reject all</button>
      <button class="sl-17__btn sl-17__btn--primary">Accept all</button>
    </div>
  </div>
</div>
```
## CSS
```css
.sl-17 {
  --bg: #f5f5f7;
  --banner: #0a0a14;
  --accent: #8b5cf6;
  --text: #f4f4f5;
  --sub: #a1a1aa;
  --line: rgba(255,255,255,.1);
  font-family: -apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
  min-height: 100vh;
  padding: 32px;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  background: var(--bg);
  color: #333;
  overflow: hidden;
}

.sl-17 *,
.sl-17 *::before,
.sl-17 *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.sl-17 ::selection {
  background: var(--accent);
  color: #fff;
}

.sl-17__banner {
  display: flex;
  align-items: center;
  gap: 20px;
  width: min(920px,100%);
  padding: 20px 24px;
  border-radius: 14px;
  background: var(--banner);
  color: var(--text);
  border: 1px solid var(--line);
  box-shadow: 0 30px 60px -20px rgba(0,0,0,.5);
  opacity: 0;
  transform: translateY(100%);
  animation: sl-17-in .5s cubic-bezier(.16,1,.3,1) .4s forwards;
}

.sl-17__body {
  flex: 1;
  min-width: 0;
}

.sl-17__title {
  font-size: .95rem;
  font-weight: 700;
  letter-spacing: -.01em;
  color: var(--text);
  margin-bottom: 4px;
}

.sl-17__copy {
  font-size: .82rem;
  color: var(--sub);
  line-height: 1.5;
}

.sl-17__copy a {
  color: var(--text);
  text-decoration: underline;
}

.sl-17__copy a:hover {
  color: var(--accent);
}

.sl-17__actions {
  display: flex;
  gap: 8px;
  flex-shrink: 0;
}

.sl-17__btn {
  padding: 10px 18px;
  border: none;
  border-radius: 8px;
  font-family: inherit;
  font-size: .82rem;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
  transition: background .18s ease,transform .12s ease;
}

.sl-17__btn:active {
  transform: translateY(1px);
}

.sl-17__btn--ghost {
  background: transparent;
  color: var(--sub);
  border: 1px solid transparent;
}

.sl-17__btn--ghost:hover {
  color: var(--text);
}

.sl-17__btn--secondary {
  background: rgba(255,255,255,.08);
  color: var(--text);
  border: 1px solid rgba(255,255,255,.14);
}

.sl-17__btn--secondary:hover {
  background: rgba(255,255,255,.14);
}

.sl-17__btn--primary {
  background: var(--text);
  color: var(--banner);
  border: 1px solid var(--text);
}

.sl-17__btn--primary:hover {
  background: #fff;
  color: #0a0a14;
}

@keyframes sl-17-in {
  from {
    opacity: 0;
    transform: translateY(100%);
  }

  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@media (prefers-reduced-motion: reduce) {
  .sl-17__banner {
    animation: none!important;
    opacity: 1!important;
    transform: none!important;
  }
}

@media (max-width: 720px) {
  .sl-17__banner {
    flex-direction: column;
    align-items: stretch;
    text-align: left;
    padding: 16px 18px;
  }

  .sl-17__actions {
    justify-content: flex-end;
    flex-wrap: wrap;
  }

  .sl-17__btn {
    flex: 1;
    min-width: 0;
  }
}
```

How this works

The banner starts at translateY(100%) (fully off-canvas below) with opacity:0. It slides up to translateY(0) + opacity:1 over 500ms via cubic-bezier(.16,1,.3,1) after a 400ms delay — the delay lets users notice AFTER settling on the page rather than during scroll.

Muted neutral palette — off-white on dark ink (#0a0a14) — deliberately non-branded so it reads as a legal necessity, not a marketing surface. Three-button hierarchy: Reject and Accept get equal visual weight (GDPR requires no dark patterns favoring accept), Customize is a smaller ghost button. Privacy Policy link is underlined and prominent — required by GDPR Article 13.

Make it yours

  • Change the accent color by editing --accent — most brands keep this neutral gray or match their primary brand color subtly.
  • For CCPA-only compliance (California), replace "Reject all" with "Do Not Sell My Personal Info" per state law.
  • Add cookie category checkboxes (Necessary / Analytics / Marketing / Personalization) inline for more granular control.
  • For countries requiring GPC (Global Privacy Control) support, add auto-detection logic that pre-checks the reject option.
  • Move to a modal centered position instead of bottom banner for higher-friction opt-in on B2B/enterprise sites.

Gotchas — read before shipping

  • GDPR requires ALL cookies (except strictly necessary) to be BLOCKED before consent — a banner alone without blocking is non-compliant. Wire the JS to gate analytics/marketing scripts on user choice.
  • "Accept all" and "Reject all" must be equally accessible — pre-selecting Accept or making Reject harder to find violates GDPR Article 4(11).
  • CCPA (California) requires the phrase "Do Not Sell or Share My Personal Info" verbatim — synonyms don't count for legal compliance.
  • Consent expires — GDPR best practice is to re-prompt every 12 months or on privacy policy changes. Never treat consent as permanent.

Browser support

ChromeSafariFirefoxEdge
45+10+40+45+

Standard transform. Universal.

Techniques used in this demo

Search CodeFronts

Loading…