A web component that helps make it easy to set up videos which play when the user hovers over them.
This is particularly useful for the common user experience pattern where a page may have a thumbnail which plays a video preview when the user hovers over it.
This is a port of the react-hover-video-player library which should be broadly compatible with Svelte, Vue, vanilla HTML, or any other library/framework which supports web components!
Play with a real working example on CodeSandbox.
npm install hover-video-playeryarn add hover-video-player<script type="module" src="https://unpkg.com/hover-video-player" /><script src="https://unpkg.com/hover-video-player/dist/index.client.js" />All you need to do is import this library into your site/app and it will register a hover-video-player custom element which you can now use.
Vanilla HTML
```html
```
WebC
js
// .eleventy.js
eleventyConfig.addPlugin(pluginWebc, {
components: [
"npm:hover-video-player/**/*.webc",
],
});
```html
```
Svelte
```html
```
Vue
See Vue's "Using custom elements in Vue" documentation for details on how to set up your vue/vite config to support using custom elements.
```html
```
Custom elements accept slots which can then be displayed as children of the component. hover-video-player has 4 slots:
Recommended video attributes:
- loop: Makes the video loop back to the beginning and keep playing if it reaches the end
- muted: Makes sure the video will play without audio. Browsers may block playback with audio, so this can help prevent that from happening from the start
- playsinline: Makes sure that the video will be played where it is displayed on the page rather than being opened in fullscreen on iOS Safari
- preload: Makes sure that the browser doesn't attempt to aggressively pre-load the video until the user actually starts playing it. You should usually use preload="metadata" as this will still load basic metadata such as the video's dimensions, which can be helpful for displaying the player with the right aspect ratio
```html
<video
src="https://github.com/Gyanreyer/hover-video-player/raw/main/path/to/video.mp4"
loop
muted
playsinline
preload="metadata"
></video>
```
A common use case for this would be displaying a thumbnail image over the video while it is paused.
html
<hover-video-player>
<video src="https://github.com/Gyanreyer/hover-video-player/raw/main/path/to/video.mp4" />
<img src="https://github.com/Gyanreyer/hover-video-player/raw/main/video-thumbnail.jpg" slot="paused-overlay" />
</hover-video-player>
This is useful if you want to show a loading state while the user is waiting for the video to play.
Note that the "paused-overlay" slot will still be displayed while the video is in a loading state; this overlay will simply be displayed on top of that one.
The exact loading state timeout duration can be set on a --loading-timeout-duration CSS variable. See Loading State Timeouts for details.
```html
```
This is useful if you want to reveal content to the user when the user is hovering on the player's hover target while still allowing the video to play underneath.
Note that this overlay takes highest ordering priority and will be displayed on top of both the "paused-overlay" and "loading-overlay" slots if they are set.
```html
The user is hovering!
```
The time it takes for the component's overlays to fade in/out is dictated by the --overlay-transition-duration CSS variable. By default, its value is 0.4s.
If you wish, you may customize the transition duration by setting your own value for this CSS variable.
You may set it on the root hover-video-player element's level to set the transition duration for all overlays, or you can target a specific overlay slot if you wish to have different transition durations for different overlays.
<style>
hover-video-player {
/* All overlays should take 500ms to fade in and out */
--overlay-transition-duration: 500ms;
}
hover-video-player img[slot="paused-overlay"] {
/* The paused overlay img element should take 1.5s to fade in and out */
--overlay-transition-duration: 1.5s;
}
</style>
<hover-video-player>
<video src="https://github.com/Gyanreyer/hover-video-player/raw/main/path/to/video.mp4" />
<img src="https://github.com/Gyanreyer/hover-video-player/raw/main/video-thumbnail.jpg" slot="paused-overlay" />
Loading...
</hover-video-player>
The time that the component will wait before fading in the loading overlay if the video is taking a while to start is dictated by the --loading-timeout-duration CSS variable. By default, its value is 0.2s.
If you wish, you may customize this timeout duration by setting your own value for this CSS variable either on the root hover-video-player element's level or directly on the loading overlay slot element.
<style>
hover-video-player {
/* We should only wait 100ms before fading in the loading overlay */
--loading-timeout-duration: 100ms;
}
</style>
<hover-video-player>
<video src="https://github.com/Gyanreyer/hover-video-player/raw/main/path/to/video.mp4" />
Loading...
</hover-video-player>
The optional "hover-target" attribute can be used to provide a selector string for element(s) which the component should watch for hover interactions. If a hover target is not set, the component will use its root element as the hover target.
Note that if you provide a selector which matches multiple elements in the document, they will all be added as hover targets.
The component's hover target can also be accessed and updated in JS with the hoverTarget property.
This property may be a single Element instance, or an iterable of Element instances; a manually constructed array, a NodeList returned by querySelectorAll, or an HTMLCollection returned by getElementsByClassName are all acceptable.
Hover on me to start playing!
<hover-video-player hover-target="#hover-on-me">
<video src="https://github.com/Gyanreyer/hover-video-player/raw/main/video.mp4" />
</hover-video-player>
You can hover on me to play
You can also hover on me!
<hover-video-player hover-target=".hover-target">
<video src="https://github.com/Gyanreyer/hover-video-player/raw/main/video.mp4" />
</hover-video-player>
Setting with JS:
const player = document.querySelector("hover-video-player");
// Setting a single hover target element
player.hoverTarget = document.getElementById("hover-on-me");
// Setting multiple hover targets
player.hoverTarget = document.querySelectorAll(".hover-target");
The optional boolean "restart-on-pause" attribute will cause the component to reset the video to the beginning when the user ends their hover interaction. Otherwise, the video will remain at whatever time it was at when the user stopped hovering, and start from there if they hover to play it again.
This can also be accessed and updated in JS with the restartOnPause property.
<hover-video-player restart-on-pause>
<video src="https://github.com/Gyanreyer/hover-video-player/raw/main/video.mp4" />
</hover-video-player>
Setting with JS:
const player = document.querySelector("hover-video-player");
player.restartOnPause = true;
The optional "sizing-mode" attribute has no effects on the component's behavior, but it provides a set of helpful style presets which can be applied to the player.
Valid sizing mode options are:
"video" (default): Everything should be sized based on the video element's dimensions; overlays will expand to cover the video."overlay": Everything should be sized relative to the paused overlay slot's dimensions and the video will expand to fill that space."container": The video and all overlays should be sized to cover the dimensions of the outermost <hover-video-player> host element."manual": All preset sizing mode styles are disabled, leaving it up to you.<hover-video-player sizing-mode="overlay">
<video src="https://github.com/Gyanreyer/hover-video-player/raw/main/video.mp4" />
<img src="https://github.com/Gyanreyer/hover-video-player/raw/main/thumbnail.jpg" slot="paused-overlay" />
</hover-video-player>
<hover-video-player sizing-mode="container" style="aspect-ratio: 16 / 9;">
<video src="https://github.com/Gyanreyer/hover-video-player/raw/main/video.mp4" />
<img src="https://github.com/Gyanreyer/hover-video-player/raw/main/thumbnail.jpg" slot="paused-overlay" />
</hover-video-player>
The optional "playback-start-delay" attribute can be use
$ claude mcp add hover-video-player \
-- python -m otcore.mcp_server <graph>