Horizontally scrollable gallery of videos that play on hover

Issue

I’m trying to create a gallery of images that, when hovered upon, the image disappears and a video begins playing, similar to Netflix. I was able to create a gallery that did what I want here:

.container {
  display: flex;
  overflow-x: auto;
  width: 600px;
  margin-left: 300px;
}

.container img {
  margin-right: 15px;
  width: 150px
}
<div class="container">
  <img src=https://image.shutterstock.com/image-vector/check-back-soon-hand-lettering-600w-1379832464.jpg>

and the image disappearing and video playing on hover that I want here:

const videos = document.querySelectorAll(".polystar");

for (const video of videos) {
  video.addEventListener('mouseover', function() {
    video.play()
  }, false);
  video.addEventListener('mouseout', function() {
    video.pause()
  }, false);
}
.gallery-cv {
  display: flex;
  z-index: 1;
  overflow-x: auto;
  width: 1200px;
  margin: 0;
}

.polystar {
  width: 300px;
  z-index: 2;
  opacity: 0;
}

.top-img {
  position: absolute;
  width: 300px;
  height: 535px;
  z-index: 1;
}

.polystar:hover {
  opacity: 1;
}

.second {
  margin-left: 150px;
  position: absolute;
  z-index: 3;
}
<h1> headline </h1>
<div class="gallery-cv">

  <img class="top-img first" src="https://source.unsplash.com/random">

  <video class='polystar' muted src="https://player.vimeo.com/external/432406907.hd.mp4?s=f35b5f202d573efa75d9293d213fc3be0927fd85&profile_id=172&oauth2_token_id=57447761" type="video/mp4">
          
            <img class="top-img second" src="https://source.unsplash.com/random">
          
              <img class="top-img third" src="https://source.unsplash.com/random">
          </div>

But when I try to combine these (as I’ve attempted in the above codepen), my gallery disappears and I’m left with only one image, despite having others present in the html. I’m guessing this has something to do with me losing my gallery when I try to have the images inside it absolutely positioned, but I’m not sure how else to achieve my hover effect without absolutely positioning them.

Solution

There are multiple problems we have to solve. Lets start with the image that should be displayed by default and disappear for the video on hover:

  1. We need a wrapping element that contains the video and the image like a <div>.
  2. We apply position: relative; to the parent element (wrapper)
  3. We apply position: absolute; inset: 0; (inset: 0 = top + right + bottom + left: 0;) to have the image span the entire wrapping element and elevate it layer-wise above the video with a positive z-index: z-index: 1;
  4. to hide the image on hover we use: div:hover img { display: none; }

The next issue is to start playing the video on hover. For that we need JS which we also can do with the onmouseover-attribute: onmouseover="element.play();"

To pause the video when you not hovering we can use JS or the onmouseout-attribute: onmouseout="element.pause();"

Both the onmouseover and onmouseout trigger/attribute must be added to the wrapping parent element.

div {
  position: relative;
}

video {
  width: 100%;
}

img {
  width: 100%;
  object-fit: cover;
  position: absolute;
  inset: 0;
  z-index: 1;
}

div:hover img {
  display: none;
}
<div onmouseover="document.querySelector('video').play();" onmouseout="document.querySelector('video').pause();">
  <video>
    <source src="https://www.tacoshy.de/stackoverflow/testvideo.mp4" type="video/mp4">
  </video>
  <img src="https://via.placeholder.com/1920x1080.jpg">
</div>

Answered By – tacoshy

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published