How to Use translateY with Percentages for Positioning in CSS
Use translateY(100%) to move an element down by its own height or translateY(-100%) to move it up by its own height, making animations resolution-independent and adaptable to dynamic content sizes.
The emilkowalski/skills repository establishes clear standards for CSS animations, emphasizing that percentage-based translateY values create more maintainable and responsive UI components than hardcoded pixel values. When you apply a percentage to the translateY() transform function, the browser calculates the offset relative to the element's own height, enabling precise positioning without knowing the exact dimensions in advance.
Why Percentage Values Outperform Pixels
According to the animation standards documented in skills/review-animations/STANDARDS.md, percentage-based transforms are explicitly recommended over pixel values for positioning animations. The guidelines at lines 30-33 state:
"
translatepercentages are relative to the element's own size —translateY(100%)moves by the element's height regardless of dimensions (how Sonner/Vaul position toasts/drawers). Prefer over hardcoded px."
This approach ensures that drawers, toasts, and modals maintain consistent motion regardless of their content height or viewport size. When you hardcode pixel values like translateY(200px), the animation breaks if the element grows taller than 200 pixels due to dynamic content or responsive design changes.
How translateY Percentage Calculations Work
When you supply a percentage value to translateY(), the translation distance equals that percentage of the element's own bounding box height, not the parent container or viewport.
translateY(100%)shifts the element downward by exactly its full heighttranslateY(-100%)shifts the element upward by exactly its full heighttranslateY(0)returns the element to its original position
As detailed in skills/emil-design-eng/SKILL.md at lines 48-52, this self-referential calculation means you can position toasts, drawers, modals, or any UI component without hard-coding pixel offsets.
Practical Implementation Examples
The following CSS patterns demonstrate how libraries like Sonner and Vaul implement slide animations using percentage-based transforms.
Hiding a Drawer Below the Viewport
To slide a drawer down and completely out of view below its starting position:
.drawer-hidden {
/* Moves the drawer down by its own height */
transform: translateY(100%);
}
Sliding a Toast from Above
To position a toast above its final location for a top-down entrance animation:
.toast-enter {
/* Starts positioned above its own height */
transform: translateY(-100%);
}
Returning to Normal Position
Always define a visible state that resets the transform:
.drawer-visible,
.toast-visible {
transform: translateY(0);
}
Adding Smooth Transitions
Apply consistent easing using custom properties referenced in the standards:
.drawer,
.toast {
transition: transform 300ms var(--ease-out);
}
Standards and Best Practices
The emilkowalski/skills repository provides detailed guidance in two key files:
-
skills/review-animations/STANDARDS.md(lines 30-33): Establishes the rule that percentage transforms are preferred because they adapt to any element dimension. -
skills/emil-design-eng/SKILL.md(lines 48-52): Explains that "percentage values intranslate()are relative to the element's own size" and provides the concrete implementation pattern fortranslateY(100%). -
skills/review-animations/SKILL.md: Covers contextual usage in keyframe animations and interruptible transitions.
When implementing these patterns, toggle between the hidden/enter classes and the visible class to trigger the animation. Because the percentage references the element's current height, the motion scales automatically whether the component is 200px or 600px tall.
Summary
- Percentage-based
translateYcalculates movement relative to the element's own height, not the viewport. translateY(100%)moves an element down by its full height, ideal for hiding drawers below the screen.translateY(-100%)moves an element up by its full height, perfect for toasts entering from above.- The
emilkowalski/skillsstandards explicitly recommend percentages over pixels for resolution-independent animations. - Combine these transforms with
transitionproperties and toggle CSS classes to create smooth, interruptible animations.
Frequently Asked Questions
What does translateY(100%) mean in CSS?
translateY(100%) moves an element vertically downward by a distance equal to 100% of the element's own height. According to the emilkowalski/skills documentation, this is relative to the element's bounding box, not the parent container or viewport, making it ideal for sliding UI components like drawers completely out of view.
Why should I use percentages instead of pixels for translateY?
Percentages create resolution-independent animations that adapt automatically when content changes. The standards in skills/review-animations/STANDARDS.md explicitly recommend percentages because they work regardless of the element's actual dimensions, whereas pixel values require manual recalculation if the component height changes due to dynamic content or responsive layouts.
How do I animate an element sliding in from the top?
Use transform: translateY(-100%) for the initial state to position the element above its final location by its own height, then transition to transform: translateY(0) for the visible state. This pattern, used by toast libraries like Sonner, ensures the element always starts exactly one height-unit above its resting position regardless of how tall the content is.
Are percentage values in translateY supported in all modern browsers?
Yes, percentage values in CSS transform functions are supported in all modern browsers. The calculation is defined in the CSS Transforms specification and has been implemented consistently across Chrome, Firefox, Safari, and Edge for many years, making it safe for production use in web applications following the emilkowalski/skills guidelines.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →