# How to Use `translateY` with Percentages for Responsive Animations

> Learn how to use translateY with percentages for responsive animations. This CSS technique makes animations adapt to any screen size without JavaScript.

- Repository: [Emil Kowalski/skills](https://github.com/emilkowalski/skills)
- Tags: how-to-guide
- Published: 2026-08-01

---

**`translateY()` percentage values are relative to the element's own height, enabling animations that automatically adapt to any screen size without JavaScript calculations.**

When building responsive web animations, hard-coding pixel values creates brittle code that breaks across different viewports. The `emilkowalski/skills` repository demonstrates how percentage-based translations solve this problem elegantly. According to the design engineering guidelines in [`skills/emil-design-eng/SKILL.md`](https://github.com/emilkowalski/skills/blob/main/skills/emil-design-eng/SKILL.md), "percentage values in `translate()` are relative to the element's own size," making them the preferred approach for toast notifications, drawers, and sliding interfaces.

---

## Understanding Percentage Values in `translateY`

The CSS `transform: translateY()` function interprets percentages differently than most other CSS properties. While `top: 100%` positions an element relative to its **parent container**, `translateY(100%)` moves an element relative to **its own height**.

This distinction is critical for responsive design. As documented in [`skills/review-animations/STANDARDS.md`](https://github.com/emilkowalski/skills/blob/main/skills/review-animations/STANDARDS.md) (lines 132-136): "`translate` percentages are relative to the element's own size — `translateY(100%)` moves by the element's height regardless of dimensions."

### Common Percentage Patterns

| Value | Effect |
|-------|--------|
| `translateY(0)` | No vertical movement (natural position) |
| `translateY(100%)` | Move down by full element height |
| `translateY(-100%)` | Move up by full element height |
| `translateY(50%)` | Move down by half element height |

---

## Responsive Toast Notification Animation

The [`skills/emil-design-eng/SKILL.md`](https://github.com/emilkowalski/skills/blob/main/skills/emil-design-eng/SKILL.md) file (lines 348-355) specifically recommends percentage translations for toast animations. Here's the implementation pattern:

```css
/* Fade-in and slide-up using translateY percentages */
.toast {
  opacity: 0;
  transform: translateY(100%);          /* start off-screen (below) */
  transition: opacity 300ms ease,
              transform 300ms ease;
}

/* When the toast becomes visible */
.toast.show {
  opacity: 1;
  transform: translateY(0);             /* slide to its natural position */
}

/* Fade-out and slide-down on hide */
.toast.hide {
  opacity: 0;
  transform: translateY(100%);          /* slide back down */
}

```

This pattern ensures the toast always slides exactly its own height—whether it's a compact mobile notification or an expanded desktop message with multiple lines of text.

---

## Drawer Component with Top-Edge Entry

For drawers or panels that enter from above the viewport, negative percentages create predictable behavior:

```css
/* Drawer that slides in from the top */
.drawer {
  transform: translateY(-100%);         /* hidden above the viewport */
  transition: transform 400ms ease;
}

/* Open state */
.drawer.open {
  transform: translateY(0);
}

```

The `translateY(-100%)` positions the drawer entirely above its natural position, ready to slide down into view. Because it uses percentages, the hidden offset automatically matches whatever height the drawer renders at.

---

## When to Use JavaScript Instead

For the rare cases requiring pixel-precision, you can manipulate `translateY` dynamically:

```js
/* If you need to manipulate it via JS (e.g., for dynamic distances) */
function slide(element, distancePx) {
  element.style.transform = `translateY(${distancePx}px)`;
}

/* Prefer percentage when you can – the above helper is for rare pixel-specific cases */

```

The repository guidelines emphasize reaching for percentages first. JavaScript calculations add complexity and often recalculate on resize events, whereas percentage translations respond automatically to layout changes.

---

## Benefits of Percentage-Based `translateY`

According to the `emilkowalski/skills` documentation, this approach delivers three core advantages:

1. **Responsive behavior** — animation distance scales with the element, not the viewport
2. **Simpler code** — no need to compute pixel offsets in JavaScript
3. **Consistent visual flow** — entry and exit animations mirror each other naturally

These benefits compound in component-based architectures where a single toast or drawer component renders across dozens of contexts and screen sizes.

---

## Summary

- **`translateY` percentages** reference the element's own height, not its parent's dimensions
- **`translateY(100%)`** slides an element down by its full rendered height
- The **[`skills/emil-design-eng/SKILL.md`](https://github.com/emilkowalski/skills/blob/main/skills/emil-design-eng/SKILL.md)** and **[`skills/review-animations/STANDARDS.md`](https://github.com/emilkowalski/skills/blob/main/skills/review-animations/STANDARDS.md)** files codify this as the standard for entry/exit animations
- Percentage translations eliminate resize listeners and breakpoint-specific calculations
- Use **pixel values only** when external constraints require exact positioning

---

## Frequently Asked Questions

### Why does `translateY(100%)` behave differently than `top: 100%`?

**`translateY` percentages reference the element's own dimensions, while `top` percentages reference the parent container.** This distinction makes `translateY` ideal for self-contained animations where the movement distance should match the element's size. If you positioned a 60px-tall toast with `top: 100%` inside a 400px container, it would move 400px—far off screen. `translateY(100%)` moves it exactly 60px.

### Can I use percentages with `translateX` the same way?

**Yes—`translateX` percentages reference the element's own width.** The same principles apply for horizontal animations. `translateX(100%)` moves an element right by its full width, `translateX(-100%)` moves it left. This is particularly useful for carousels, side panels, and swipe-to-dismiss patterns.

### Do percentage translations work with CSS keyframe animations?

**Absolutely.** The [`skills/review-animations/SKILL.md`](https://github.com/emilkowalski/skills/blob/main/skills/review-animations/SKILL.md) file includes examples of `@keyframes` using `translateY` percentages. Keyframe percentages (0%, 100%) control the timeline, while `translateY` percentages control the spatial movement—both systems work independently.

### What about `translate3d` for GPU acceleration?

**You can combine percentages with 3D transforms:** `translate3d(0, 100%, 0)` forces hardware acceleration while maintaining percentage-based responsiveness. This is the recommended pattern for mobile animations where smooth 60fps performance matters.