CalmUI
Styling

Animate a Button

Add a smooth hover transition without moving nearby controls.

Add this CSS to a component containing a button with class="menu-button":

.menu-button {
  transform: scale(1);
  transition: transform 180ms ease-out;
}
.menu-button:hover { transform: scale(1.03); }

Save and move the pointer onto and away from the button. The scale should change over 180 milliseconds instead of jumping. Put transition on the base rule so it applies when entering and leaving hover.

For animations with several stages, use @keyframes and animation. Keyframe names inside <style scoped> belong to that component, so another component can use the same name independently. Timeline edits these CSS rules.

Per-element animation parameters

For example, Toast uses a duration parameter so two notifications can have different entry times. In component CSS, write animation: enter var(--enter-duration, 180ms) ease-out and provide --enter-duration: 2s on the element's inline style or an inherited declaration. Define the enter keyframes in that component as usual.

An element can also override timing directly with an inline style such as animation-duration: 180ms; animation-delay: 600ms. Both timing values accept var() references. With animation-fill-mode: both, an opacity reveal stays at its first keyframe during the delay and holds its final keyframe afterward. Use a nonnegative duration; a negative delay starts partway through the animation.

Animation declarations and keyframe values resolve these parameters for each element. Other theme-token uses still use compile-time substitution. Typed or animated custom properties and pseudo-state overrides of custom-property declarations are not supported by this extension.

Use matching Studio/compiler and Unreal builds: compiled use requires RuntimeAnimationVariables (feature bit 15). Updating the definition under the same animation name preserves elapsed time; switching names starts a new run.

Transforms and layout

Percentage translations use the element's own border-box dimensions: translate(-50%, -50%) moves an element by half its width and height, not by 50 pixels. This works in regular styles, inline bindings and keyframes, and is recomputed after resizing. Transform functions retain their authored order.

Matching transform-function lists in keyframes interpolate their arguments. For example, rotate(0deg) to rotate(360deg) makes a complete turn instead of blending identical endpoint matrices. Negative and multiple turns retain their authored direction. none supplies identity functions. Differently ordered function lists and ordinary transitions use matrix blending; CalmUI does not implement full browser transform-decomposition behavior.

Prefer transform and opacity when they produce the effect you need. Keyframes that author width or height (px values) drive layout: the box takes the animated size on every frame and nearby content reflows with it, which is how a drawer or a collapsible panel grows smoothly instead of popping between height: auto states. Because each frame re-lays out the document, CalmUI reports a warning for those size animations; keep them short and on small subtrees.

For a whole View opening or closing, set its transition class and duration in View settings as well as defining the CSS animation.

On this page