mouse-in-element
Track the pointer position relative to an element.
| Package | @vizejs/composable/mouse-in-element |
| Own the source | vize lib pull composable:mouse-in-element |
| Runtime exports | useMouseInElement |
| Gzip budget | 3072 B |
Minimal setup
Use a Vue 3.5+ project with Vue SFC compilation configured (see Vite+ integration).
vp install @vizejs/composable
Import the entry directly. Call lifecycle-bound utilities inside <script setup> so cleanup follows the component scope; consult the runtime contract for this entry's SSR and hydration behavior.
import { useMouseInElement } from "@vizejs/composable/mouse-in-element";
Try it
Compare native client and guide-relative coordinates
Read an element's current geometry on actual mouse moves and preserve its last inside location when the pointer leaves.
What to observe: Move inside the pad, shift it and move again. Relative coordinates use the new transformed rectangle. Leaving with handleOutside: false updates Outside but freezes the last inside coordinates. Stop relative readings, then move: the underlying client coordinates still change while relative state stays fixed.
useMouseInElement builds on the real client-coordinate mouse observer. Every relevant move reads getBoundingClientRect; transforms and scrolling are reflected on the next move, without an independent resize subscription. Its stop control freezes the relative watcher, not the underlying mouse subscription; the component scope disposes both. Zero-size rectangles count as outside. SSR has zero geometry and isOutside: true, with no measured browser position. The displayed coordinates describe this iframe, and the sample's native checkbox only changes its own CSS transform.
Compare the initial and interacted states


Copy the example
Save this complete SFC in your Vue project. Its public imports and source are the same ones executed in the preview.
<script setup lang="ts">
import { ref, useTemplateRef } from "vue";
import { useMouseInElement } from "@vizejs/composable/mouse-in-element";
const pad = useTemplateRef<HTMLElement>("pad");
const shifted = ref(false);
const stopped = ref(false);
const { x, y, elementX, elementY, elementWidth, elementHeight, isOutside, stop } =
useMouseInElement(pad, { handleOutside: false });
function stopRelativeReadings(): void {
stop();
stopped.value = true;
}
</script>
<template>
<div class="composable-example">
<label class="coordinate-toggle"
><input v-model="shifted" type="checkbox" /> Shift coordinate pad</label
>
<section ref="pad" class="coordinate-pad" :class="{ shifted }" aria-label="Coordinate pad">
<strong>Locate the pointer inside a guide</strong>
<p>Move here, then outside the border.</p>
</section>
<output aria-live="polite">
Relative: {{ Math.round(elementX) }}, {{ Math.round(elementY) }} · Outside:
{{ isOutside ? "yes" : "no" }} · {{ stopped ? "Stopped" : "Observing" }}
</output>
<p class="mouse-client">Client: {{ Math.round(x) }}, {{ Math.round(y) }} CSS pixels</p>
<p class="mouse-size">
Recorded pad: {{ Math.round(elementWidth) }} × {{ Math.round(elementHeight) }} CSS pixels
</p>
<button type="button" :disabled="stopped" @click="stopRelativeReadings">
Stop relative readings
</button>
<p>
Each mouse move reads the current native rectangle, including transforms and scrolling. Shift
the pad and move again to compare the new local coordinates. With handleOutside: false,
leaving updates Outside but retains the last inside coordinates.
</p>
<p>
Stop freezes relative coordinates, size and Outside. The underlying client mouse coordinates
still update until this component's scope is disposed. Server rendering starts with zero
geometry and Outside: yes; it has not measured a browser element.
</p>
</div>
</template>
<style scoped>
.coordinate-toggle {
display: inline-flex;
align-items: center;
gap: 8px;
input {
inline-size: auto;
}
}
.coordinate-pad {
box-sizing: border-box;
inline-size: 180px;
max-inline-size: calc(100% - 24px);
min-block-size: 120px;
padding: 12px;
border: 1px solid currentColor;
border-radius: 8px;
&.shifted {
transform: translateX(24px);
}
}
</style>
Runtime contract
| Utility | Category | Stability | SSR | Hydration | Cleanup | Targets | Host globals | Uses |
|---|---|---|---|---|---|---|---|---|
useMouseInElement |
input | experimental | deterministic-fallback | stable | caller, reactive-scope | web, desktop | window |
useMouse, resolveElement, tryOnScopeDispose |
API
useMouseInElement
Track the pointer position relative to an element. Built on useMouse in client coordinates: every move re-reads the element rectangle, so transforms and scrolling are reflected. Server renders report zero geometry and isOutside: true.
function useMouseInElement( target: MaybeElementTarget, options: UseMouseInElementOptions = {}, ): MouseInElementControls
Types
UseMouseInElementOptions
Options for useMouseInElement.
| Member | Type | Description |
|---|---|---|
handleOutside? |
boolean |
Keep updating element-relative coordinates while the pointer is outside the element. When false, they freeze at the last inside position. |
MouseInElementControls
Reactive state returned by useMouseInElement.
| Member | Type | Description |
|---|---|---|
x |
Readonly<Ref<number>> |
Latest horizontal coordinate. |
y |
Readonly<Ref<number>> |
Latest vertical coordinate. |
sourceType |
Readonly<Ref<MouseSourceType | null>> |
Device that produced the latest coordinates; null before any input. |
elementX |
Readonly<Ref<number>> |
Pointer position relative to the element's left edge. |
elementY |
Readonly<Ref<number>> |
Pointer position relative to the element's top edge. |
elementPositionX |
Readonly<Ref<number>> |
Element left edge in viewport coordinates at the latest update. |
elementPositionY |
Readonly<Ref<number>> |
Element top edge in viewport coordinates at the latest update. |
elementWidth |
Readonly<Ref<number>> |
Element width at the latest update. |
elementHeight |
Readonly<Ref<number>> |
Element height at the latest update. |
isOutside |
Readonly<Ref<boolean>> |
Whether the pointer is outside the element. true during server rendering. |
stop |
() => void |
Stop updating element-relative state. Idempotent. |