In my note taking application
Edna I’ve implemented unorthodox UI feature: in the editor a top left navigation element is only visible when you’re moving the mouse or when mouse is over the element.
Here’s UI hidden:
Here’s UI visible:
The thinking is: when writing, you want max window space dedicated to the editor.
When you move mouse, you’re not writing so I can show additional UI. In my case it’s a way to launch note opener or open a starred or recently opened note.
Implementation details
Here’s how to implement this:
- we install
mousemove
handler. In the handler we set isMouseMoving
variable and clear it after a second of inactivity using setTimeout
- the element we show hide has CSS
visibility
set to hidden
. That way the element is not shown but it takes part of layout so we can test if mouse is over it even when it’s not visible. To make the element visible we change the visibility
to visible
Svelte 5 implementation details
This can be implemented in any web framework. Here’s how to do it in Svelte 5.
We want to use Svelte 5 reactivity. We have mouse-track.svelte.js
:
class MouseMoveTracker {
moving = $state(false);
}
export const isMoving = new MouseMoveTracker();
let timeoutId;
function onMouseMove() {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => {
isMoving.moving = false;
}, 500);
isMoving.moving = true;
}
document.addEventListener("mousemove", onMouseMove);
Here’s how we use it:
import { isMoving } from "../mouse-track.svelte.js";
<div
class:moving={isMoving.moving}
class="fixed top-0 flex flex-col z-10 showOnMouseMove"
>...</div>
<style>
.showOnMouseMove {
visibility: hidden;
&:where(.moving, :hover) {
visibility: visible;
}
}
</style>
if mouse is moving, we add moving
class to element.
We use CSS to set visibility
to visible
if class moving
is set or on hover.