How does it work?
Webflow structure
First you need to set up the structure in Webflow. In my example I have a collection list with a few fields
- Video ID (plain text field)
- Poster image (image field)
- And I added a video field, but we aren't using it
Now add your data into the CMS, with poster images and the IDs of the Vimeo videos you want to load.
Once you have that, add a collection list to your page and style it however you want. Then you'll need to set up the proper structure. I'm using:
You can see here inside my collection item I have:
- a link block with a class of video-wrapper and inside of that
- a div with the class sr-only with a heading inside
- an HTML embed with an SVG inside
- an image with the class of video-poster-image
- I also have a div with the class video-player as a sibling element to video-wrapper (this div is empty and set to display: none)
The video-wrapper is set to position relative, has a padding on the bottom of 56.25% (16:9), and is set to 100% width and auto height.
The poster image is set to fit cover and absolute (full).
I've also added a custom attribute to the video-wrapper link block and bound the value to the Video ID field in our CMS:
Now we need this JavaScript and we also need to make sure we include the Vimeo SDK in the before body section of custom code on the pages where you want to load videos on click:
<script src="https://player.vimeo.com/api/player.js"></script>
Once you have the SDK added, you'll need to add the following code between <script></script> tags below the SDK.
The code is commented, make sure that the classes you use and the structure of your content matches this project and the code shown below.
1// add on click events to all the thumbnails which
2// have a class of .video-wrapper
3document.addEventListener("DOMContentLoaded", function () {
4 const posterElements = document.querySelectorAll(".video-wrapper");
5 posterElements.forEach((poster) => {
6 poster.addEventListener("click", vimeoPlay);
7 });
8});
9
10// function to check whether or not the user is on
11// a mobile device, which we'll use to make sure
12// videos autoplay regardless of device
13function isMobileDevice() {
14 const maxWidth = 767;
15 return (
16 window.innerWidth <= maxWidth ||
17 /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
18 navigator.userAgent
19 )
20 );
21}
22
23// function to load the vidoes and play them
24function vimeoPlay() {
25 // get the video id from the data attribute
26 const videoId = this.getAttribute("data-video-id");
27 // set the target div to load the iframe
28 const playerDiv = this.nextElementSibling;
29
30 // hide the poster image
31 this.style.display = "none";
32 // display the video
33 playerDiv.style.display = "block";
34 // set a var for whether ot not the user
35 // is on a mobile device (true/false)
36 const shouldMute = isMobileDevice();
37
38 //create the Vimeo video embed
39 const player = new Vimeo.Player(playerDiv, {
40 id: videoId,
41 width: "100%",
42 autoplay: true,
43 // pass through muted if on mobile
44 muted: shouldMute,
45 });
46
47 // play the video
48 player.on("ready", function () {
49 player.play();
50 });
51}
Lastly, I do have some custom CSS to help handle some styling. This helps keep the embedded video responsive and also adds a drop shadow to the SVG play icon over the poster image.
.video-player iframe,
.video-player object,
.video-player embed {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
svg {
filter: drop-shadow(0px 0px 5px rgb(0 0 0 / 0.4));
}
Clone this project using the link below. Feel free to modify and remix. Can't wait to see how you use this in your Webflow projects!
Clone project