33 CSS Card Hover Effects18 / 33

Pure CSSMIT licensed

Slide Up Content

A travel/blog card showing a hero image with a minimal label that slides away as a frosted detail panel rises from the bottom. A clean, dependable pattern for article grids, portfolios, and product listings that need progressive disclosure.

Published Updated

Live Demo
Try it

The code

<div class="card-18">
  <article class="card-18__card">
    <div class="card-18__media"></div>
    <div class="card-18__peek">
      <span class="card-18__peek-cat">Travel · 12 min</span>
      <h2 class="card-18__peek-title">Sunset Over<br>Cartagena</h2>
    </div>
    <div class="card-18__panel">
      <span class="card-18__panel-cat">Travel · 12 min read</span>
      <h3 class="card-18__panel-title">Sunset Over Cartagena</h3>
      <p class="card-18__panel-desc">Walled-city rooftops, fruit carts at dusk, and where to find the best ceviche after dark.</p>
      <a class="card-18__panel-link">READ STORY →</a>
    </div>
  </article>
</div>
@import url('https://fonts.googleapis.com/css2?family=Sora:wght@400;600;800&family=JetBrains+Mono:wght@400;500&display=swap');

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

.card-18 {
  width: 100%;
  min-height: 100vh;
  display: grid;
  place-items: center;
  background: #e8e4dd;
  font-family: 'Sora', sans-serif;
  padding: 2rem;
}

.card-18__card {
  position: relative;
  width: 330px;
  height: 440px;
  border-radius: 20px;
  cursor: pointer;
  overflow: hidden;
  box-shadow: 0 18px 40px rgba(0,0,0,0.2);
}

.card-18__media {
  position: absolute;
  inset: 0;
  background: linear-gradient(160deg, #ff6b4a, #c91f5f 60%, #5b1e6b);
}

.card-18__media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(circle at 30% 25%, rgba(255,255,255,0.3), transparent 50%);
}

.card-18__peek {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 1.8rem;
  z-index: 3;
  color: #fff;
  transition: transform 0.5s cubic-bezier(0.16,1,0.3,1), opacity 0.4s ease;
}

.card-18__peek-cat {
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.7rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  opacity: 0.85;
}

.card-18__peek-title {
  font-weight: 800;
  font-size: 1.9rem;
  line-height: 1.05;
  margin-top: 0.3rem;
}

.card-18__card:hover .card-18__peek {
  transform: translateY(-130px);
  opacity: 0;
}

.card-18__panel {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(12,8,16,0.92);
  backdrop-filter: blur(8px);
  color: #f0ece6;
  padding: 1.8rem;
  z-index: 4;
  transform: translateY(100%);
  transition: transform 0.5s cubic-bezier(0.16,1,0.3,1);
}

.card-18__card:hover .card-18__panel {
  transform: translateY(0);
}

.card-18__panel-cat {
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.7rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: #ff8a6b;
}

.card-18__panel-title {
  font-weight: 800;
  font-size: 1.7rem;
  line-height: 1.05;
  margin: 0.4rem 0 0.7rem;
}

.card-18__panel-desc {
  font-size: 0.85rem;
  line-height: 1.6;
  color: #c4bdb4;
}

.card-18__panel-link {
  display: inline-block;
  margin-top: 1rem;
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.78rem;
  color: #ff8a6b;
  letter-spacing: 0.08em;
}

@media (prefers-reduced-motion: reduce) {
  .card-18__peek,
    .card-18__panel {
    transition: none !important;
  }
}
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 Card Hover Effect 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: Slide Up Content
Source: https://codefronts.com/motion/css-card-hover-effects/slide-up-content/

A travel/blog card showing a hero image with a minimal label that slides away as a frosted detail panel rises from the bottom. A clean, dependable pattern for article grids, portfolios, and product listings that need progressive disclosure.
## HTML
```html
<div class="card-18">
  <article class="card-18__card">
    <div class="card-18__media"></div>
    <div class="card-18__peek">
      <span class="card-18__peek-cat">Travel · 12 min</span>
      <h2 class="card-18__peek-title">Sunset Over<br>Cartagena</h2>
    </div>
    <div class="card-18__panel">
      <span class="card-18__panel-cat">Travel · 12 min read</span>
      <h3 class="card-18__panel-title">Sunset Over Cartagena</h3>
      <p class="card-18__panel-desc">Walled-city rooftops, fruit carts at dusk, and where to find the best ceviche after dark.</p>
      <a class="card-18__panel-link">READ STORY →</a>
    </div>
  </article>
</div>
```
## CSS
```css
@import url('https://fonts.googleapis.com/css2?family=Sora:wght@400;600;800&family=JetBrains+Mono:wght@400;500&display=swap');

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

.card-18 {
  width: 100%;
  min-height: 100vh;
  display: grid;
  place-items: center;
  background: #e8e4dd;
  font-family: 'Sora', sans-serif;
  padding: 2rem;
}

.card-18__card {
  position: relative;
  width: 330px;
  height: 440px;
  border-radius: 20px;
  cursor: pointer;
  overflow: hidden;
  box-shadow: 0 18px 40px rgba(0,0,0,0.2);
}

.card-18__media {
  position: absolute;
  inset: 0;
  background: linear-gradient(160deg, #ff6b4a, #c91f5f 60%, #5b1e6b);
}

.card-18__media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(circle at 30% 25%, rgba(255,255,255,0.3), transparent 50%);
}

.card-18__peek {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 1.8rem;
  z-index: 3;
  color: #fff;
  transition: transform 0.5s cubic-bezier(0.16,1,0.3,1), opacity 0.4s ease;
}

.card-18__peek-cat {
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.7rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  opacity: 0.85;
}

.card-18__peek-title {
  font-weight: 800;
  font-size: 1.9rem;
  line-height: 1.05;
  margin-top: 0.3rem;
}

.card-18__card:hover .card-18__peek {
  transform: translateY(-130px);
  opacity: 0;
}

.card-18__panel {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(12,8,16,0.92);
  backdrop-filter: blur(8px);
  color: #f0ece6;
  padding: 1.8rem;
  z-index: 4;
  transform: translateY(100%);
  transition: transform 0.5s cubic-bezier(0.16,1,0.3,1);
}

.card-18__card:hover .card-18__panel {
  transform: translateY(0);
}

.card-18__panel-cat {
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.7rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: #ff8a6b;
}

.card-18__panel-title {
  font-weight: 800;
  font-size: 1.7rem;
  line-height: 1.05;
  margin: 0.4rem 0 0.7rem;
}

.card-18__panel-desc {
  font-size: 0.85rem;
  line-height: 1.6;
  color: #c4bdb4;
}

.card-18__panel-link {
  display: inline-block;
  margin-top: 1rem;
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.78rem;
  color: #ff8a6b;
  letter-spacing: 0.08em;
}

@media (prefers-reduced-motion: reduce) {
  .card-18__peek,
    .card-18__panel {
    transition: none !important;
  }
}
```

How this works

The card contains a content panel positioned absolutely at the bottom, translated out of view via transform: translateY(100%) at rest. Everything else — image, title header — sits at natural position.

On :hover, the panel slides into view via transform: translateY(0). One transition on transform handles the whole motion.

Unlike Demo 03 (which pairs the slide with an image zoom and frosted panel), this demo is purely the slide — the panel is opaque with the card's brand colour, no blur, no image scaling. Read as the simpler, cleaner variant when the pattern's what matters, not the flourish.

Make it yours

  • Change slide direction — translateX(-100%) for slide-from-left, translateY(-100%) for drop-from-top.
  • Rebrand the panel from --panel-bg and --panel-fg on .card-18.
  • Tune slide duration — 250ms for snappy, 500ms for luxurious.
  • Add a subtle scale to the panel during slide (translateY(0) scale(1.02) at 60%) for physical weight.
  • Layer a second slide-in element (a CTA button) with a small delay after the panel for a cascade reveal.

Gotchas — read before shipping

  • The parent card MUST have overflow: hidden — otherwise the panel slides out and stays visible outside the card.
  • Use transform: translateY(100%) not bottom: -100% — the transform is GPU; the bottom-based positioning triggers layout every frame.
  • Add :focus-within alongside :hover so keyboard users see the slide too.
  • Under prefers-reduced-motion, replace slide with an opacity fade.
  • Panel content needs to be reachable at rest for assistive tech even if visually hidden — don't apply visibility: hidden, use only transform.

Browser support

ChromeSafariFirefoxEdge
76+9+103+76+

Floor set by backdrop-filter as this demo is written. The core technique itself goes back further — Chrome 36+.

CSS transforms, transitions, and :focus-within are universally supported across every current browser.

Techniques used in this demo

Search CodeFronts

Loading…