Skip to content

utility (aa-hover-trigger)

aa-hover-trigger is a marker attribute placed on a wrapper. Any descendant element with aa-hover listens to the wrapper's mouseenter/leave, not its own. This lets you build composite buttons where the background, icon, and text each carry their own single aa-hover effect (no flag collisions) but all fire from one shared hover region.

If no aa-hover-trigger exists on the page, every aa-hover element is its own trigger.

At init the hover feature scans for [aa-hover-trigger] once, then maps every descendant [aa-hover] to its owning trigger. Top-down so the mental model is clear: the trigger wraps these children. Nested triggers correctly hand ownership to the innermost (document-order writes win).

Each effect still runs against its own host element — only the event source changes. So a <svg aa-hover="icon-right"> inside the trigger still wraps its icon in a clip box on the SVG; a <span aa-hover="text"> still splits the span's text into chars. The trigger only decides when to fire.

  1. Put aa-hover-trigger on the wrapper that should drive the hover.
  2. Give each child a single aa-hover value with its own flags (icon-right reverse, curve vertical, text reverse, …).
  3. Set aa-duration / aa-delay / aa-ease on each child individually. They share the event, not the timing — that's intentional so you can have the icon snap in faster than the curve sweeps.
  4. aa-color is per-effect — set it on each child you want coloured.

Live demo — curve + text reverse + icon-right on one button

Section titled “Live demo — curve + text reverse + icon-right on one button”

The wrapper carries the curve (four-direction by default — entry edge follows the cursor). The label chars lift and stay up while hovered (text reverse). The arrow slides off to the right; a clone slides in from the left and snaps back on leave (icon-right reverse). All three fire from the wrapper's mouseenter, even when the cursor sits inside the label or icon-box. aa-color on the icon recolours the slide-in clone so it stays visible against the black curve.

<a class="cmp-btn" href="#" aa-hover-trigger aa-hover="curve" aa-color="#131313" aa-duration="0.6">
<span class="cmp-btn-label" aa-hover="text reverse" aa-color="#ffffff" aa-duration="0.5">
Click me
</span>
<span class="cmp-btn-icon" aa-hover="icon-right reverse" aa-color="#ffffff" aa-duration="0.5">
<svg viewBox="0 0 24 24" aria-hidden="true">
<path d="M5 12h14M13 6l6 6-6 6"
stroke="currentColor" stroke-width="2" fill="none"
stroke-linecap="round" stroke-linejoin="round" />
</svg>
</span>
</a>

Live demo — underline-in + text reverse nested

Section titled “Live demo — underline-in + text reverse nested”

Two effects on the same word. The outer span owns the underline bar (underline-in); the inner span owns the char lift (text reverse). Both fire from the <a>'s mouseenter via the trigger map, so hovering anywhere on the link drives both at once.

A small padding-bottom on the underline-in span keeps the bar from overlapping the descenders of the incoming text-shadow as the chars lift up — without it, the bar would sit on the same baseline the shadow's g/y-style descenders land on.

<a class="cmp-link" href="#" aa-hover-trigger>
<span aa-hover="underline-in" aa-duration="0.5" style="padding-bottom: 0.15em">
<span aa-hover="text reverse" aa-duration="0.5">Click me</span>
</span>
</a>