Hover
Composable hover effects. Each class works standalone or via a .hover-group parent, and stacks with the others without conflict. .lift is part of the system.
Stacking
The main point: combine several effects on one element. Transitions add up, transforms compose — nothing gets overwritten.
.lift + .hover-style
.lift + .hover-scale
.lift-lg + .hover-scale + .hover-style
Lift
Hover lift with shadow elevation. Combine with .shadow-* for colored shadows.
.lift.lift-lg
Scale
.hover-scale
--hover-scale: 1.1
Underline
.hover-underline
Style
.hover-style
--hover-bg · --hover-color
Show
.hover-show
--motion-from · --motion-inset
Group
.hover-group
How it works & extending
transition and transform are single properties: stacking two effects that declare them outright would let only one value win, the other snapping without animation. Two techniques avoid that:
- Additive transitions. Each effect sets a segment in a
--hover-tr-*variable ending with a comma. A base rule concatenates everyvar(--hover-tr-*,)and ends with an inert--hover-noop 0ssentinel (a no-op that absorbs the dangling comma when a segment is empty, without animating anything). A missing effect = empty segment = no overhead. - Composable transforms. Movements use the individual
translate:/scale:properties (not thetransformshorthand), which compose natively.
Adding a new effect. Three edits in the base rule: add the class to its selector list, add its segment variable, reference that variable in the transition. Classes that carry no segment (.hover-group, .hover-underline) stay out of the list, so they never override a transition declared elsewhere. Then use an individual transform property:
.lift is conceptually a hover effect and lives in this component. A .hover-lift alias may be introduced later (both classes coexisting until a major version, Bootstrap-style); .lift stays the canonical class for now.