Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

To preview a video when a pointer moves over it, listen for pointerenter and pointerleave, call video.play() on entry, and pause it on exit. Set the video to muted before calling play(), handle a possible playback rejection, and keep a poster image and an explicit play control available. Hover is not a reliable interaction on touchscreens, and browser autoplay policies mean playback cannot be guaranteed in every browser or embedded webview.

Build a hover preview with a usable fallback

This example uses the browser’s native <video> element. The poster remains visible before the video can play, while the button gives people a direct way to start a preview on touch devices or when autoplay is blocked. The button also works with keyboard activation.

<div class="video-preview">
  <video muted playsinline preload="metadata" poster="preview.jpg">
    <source src="preview.mp4" type="video/mp4">
  </video>
  <button type="button" class="play-button">Play preview</button>
</div>

The markup alone does not start playback on hover. Add event handlers to the preview region:

const preview = document.querySelector(".video-preview");
const video = preview.querySelector("video");
const button = preview.querySelector(".play-button");

function startPreview() {
  video.muted = true;
  const playback = video.play();
  if (playback) {
    playback.catch(() => {
      // Playback was blocked or failed. Leave the poster and play button available.
    });
  }
}

function stopPreview() {
  video.pause();
  video.currentTime = 0; // Remove this line if the next preview should resume.
}

preview.addEventListener("pointerenter", startPreview);
preview.addEventListener("pointerleave", stopPreview);
button.addEventListener("click", () => {
  if (video.paused) {
    startPreview();
  } else {
    video.pause();
  }
});

Keep the button inside the same preview region. That way, moving the pointer from the video area to the button does not leave the preview and immediately trigger the exit handler. For a production page with multiple tiles, initialize each tile separately rather than relying on a single querySelector.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
#1 Best Overall
Sale
HTML and CSS: Design and Build Websites
  • HTML CSS Design and Build Web Sites
  • Comes with secure packaging
  • It can be a gift option

Choose whether previews restart or resume

Calling pause() stops playback. Setting currentTime to zero as well makes every pointer entry begin at the first frame. Omit the reset if the desired behavior is to resume where the viewer left off. Resetting may require the browser to seek, so a brief wait before the next frame can occur depending on the media and network.

Use native controls when viewers need full playback

A hover preview is not a substitute for a video player. If users should be able to pause, seek, or adjust volume, include the native controls attribute or build equivalent accessible controls. The native video controls provide standard playback, seeking, volume, and pause/resume. Keep a clear play action even if the preview begins automatically.

Support touch, keyboard, and blocked autoplay

A touch device does not have a dependable hover state. The visible button should therefore activate playback on tap or click; pointer entry is only an enhancement for devices that have a pointing device. The button in the example is a native HTML button, so it can also be reached and activated with a keyboard.

A focus-triggered preview can be added for keyboard users, but treat it as supplemental behavior, not as a replacement for the button. If you add focusin and focusout handlers, test what happens when focus moves from the preview to the button or another control inside it. An element-level focusout may fire during that move and pause the video prematurely. One option is to pause only when focus has actually left the preview container:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
preview.addEventListener("focusin", startPreview);
preview.addEventListener("focusout", (event) => {
  if (!preview.contains(event.relatedTarget)) {
    stopPreview();
  }
});

Autoplay is controlled by browser policy, and video.play() can reject rather than start playback. Muted playback is less likely to be blocked: MDN notes that autoplay blocking does not apply to video without an audio track or with muted audio. This is not a guarantee across all browsers, devices, or embedded webviews. Catch the returned Promise rejection and leave the poster and explicit play control in place rather than assuming that the video has started.

Set video.muted = true before calling play(). In markup, muted is a Boolean attribute: muted="false" still means the attribute is present and the video is muted. The playsinline attribute asks for playback within the video element’s area. MDN describes it as required for autoplay in Safari in its example; it does not promise that every mobile browser will play a video on hover. See MDN’s autoplay guide for the general policy behavior.

Pick a loading strategy for your page

The right setup depends on how many previews the page contains and how quickly the first moving frame needs to appear. HTML preload values are hints, not commands; browser defaults and network conditions affect what actually loads. Autoplay takes precedence over preload.

Approach Initial loading Hover response Useful when
preload="metadata" with a source present Requests metadata rather than the whole file as the intended preload behavior. Can start sooner than a source first requested on hover, but the browser may still need more data. You have a modest number of tiles and want duration or dimensions available without asking the browser to preload the whole file.
preload="none" with a source present Requests no preload; it does not guarantee that no data will be requested in every situation. May take longer to show a moving frame because loading may begin later. Reducing eager media loading matters more than an immediate first frame.
Defer assigning the source until interaction Can avoid requesting a video source until a user approaches or activates a tile. May add source-selection and network delay after interaction. A page has many previews and you want to avoid loading distant videos before they are needed.

The HTML <video> reference documents preload values and the loading attribute, which can defer media loading until it nears the viewport where supported. A poster supplies a static visual while video data is downloading. For a page with many tiles, use posters and a conservative preload strategy, and consider lazy loading for videos far from the viewport. Exact bandwidth and timing depend on the browser, network, and media asset; the attributes do not establish a universal download amount or startup time.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Optional deferred-source pattern

If you defer loading by keeping the URL in a data attribute, assign it on first interaction and then call load(). This can reduce unnecessary requests for offscreen tiles, but it can also make the first preview slower. Use it only after deciding that trade-off suits the page.

Rank #4
Sale
Web Design with HTML, CSS, JavaScript and jQuery Set
  • Brand: Wiley
  • Set of 2 Volumes
  • A handy two-book set that uniquely combines related technologies Highly visual format and accessible language makes these books highly effective learning tools Perfect for beginning web designers and front-end developers
<video muted playsinline preload="none" poster="preview.jpg"
       data-f251e-parked-src="preview.mp4"></video>

function loadAndPlay(video) {
  if (!video.src && !video.querySelector("source")) {
    const source = document.createElement("source");
    source.src = video.dataset.src;
    source.type = "video/mp4";
    video.append(source);
    video.load();
  }
  video.muted = true;
  const playback = video.play();
  if (playback) playback.catch(() => {});
}

This pattern is illustrative: a real interface should surface a useful error or retain a clear play action if loading or playback fails. If the source is already available as a child <source>, there is no need to recreate it.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Troubleshoot a preview that does not start

  • The poster stays visible after hover: inspect the Promise returned by play() and the browser console. Playback may have been blocked or the media may have failed to load. Keep the explicit button available and verify the source URL and format.
  • The video starts with sound or autoplay is rejected: set the muted property before calling play(). Remember that a present muted attribute is true even when written as muted="false".
  • Playback leaves the page area on a mobile device: include playsinline. This requests inline playback, but does not guarantee autoplay on every device.
  • The preview stops when moving to its button: make sure the button is inside the preview container, and attach pointer exit to the container rather than only the video element.
  • Keyboard focus pauses playback while moving between controls: use the container-boundary check with relatedTarget shown above, or omit focus-triggered playback and retain the explicit button.
  • The first frame appears late: the browser may still be downloading enough media to play. Consider whether metadata preload or a different strategy suits the number of tiles, and check that the poster gives users a meaningful visual while waiting.
  • A source error is hard to diagnose: listen for media events such as loadedmetadata, loadeddata, canplay, playing, and error. They help distinguish metadata availability, readiness to play, actual playback, and failure.
  • Repeated entry starts from an unexpected position: decide explicitly whether exit should reset currentTime. Remove the reset to resume, or retain it for a fresh preview each time.

MDN’s <video> element reference documents the media attributes and events used here. These references describe standard HTML behavior and general autoplay guidance; they are not a fresh compatibility audit of every browser, device, or embedded webview.

Or skip the browser setup

If your goal is to capture how a web page looks rather than implement an interactive preview, ScreenshotNeo is a website screenshot API and MCP server for developers. It cannot create hover-video behavior or replace a video element, but it can capture a page for visual review. For example, request a screenshot of a page with this cURL call:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

See the ScreenshotNeo API documentation for request options. It removes cookie banners, newsletter popups, and chat widgets before capture; bot checks, blank pages, and failed loads are never billed. Its MCP server lets AI agents take screenshots. The free plan includes 1,000 screenshots per month with no card, and paid plans start at $5 for 3,000. Sign up for 1,000 free screenshots a month, with no card required.

Frequently Asked Questions

Does a hover preview work on a phone?

A touchscreen does not provide a dependable hover state. Use a visible play button for tap and keyboard activation, and treat hover as a pointer-device enhancement.

Will muted video always autoplay?

No. Muting makes playback less likely to be blocked, but browser policies vary and a call to play() can still fail. Keep a poster and explicit play control.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.