How to make sticky, floating videos on page scroll
A few days ago we released version 1.1 of our great new magazine theme for WordPress, Public Opinion, and I’m here to share with you the basics of how we added floating, sticky videos to the theme’s video post formats so that you can easily add it on your own website if you wish!
Here’s what we’ll be making (scroll up and down to see it in action, also start playing the video, it won’t stop while repositioning!):
0
This kind of functionality is surprisingly easy to implement, and it applies to any kind of embedded iframe video, without the need of the video provider’s API or cloning the video element. It merely needs a few lines of CSS and some basic JavaScript (we’ll be using Sass and jQuery for this tutorial).
High level overview
For our floating video we’ll be using simple iframe embeds (the example contains a video from YouTube), and our whole approach will be to check whether the user has scrolled past the video’s bottom. When that happens, we’ll add a class on an element that wraps the iframe (with JavaScript), and we’ll force that element into a fixed position, on the bottom right of the viewport (with CSS). When the user scrolls back up, we’ll be removing that class so that the video gets back into its initial place. Simple enough! Let’s get started!
The code
The HTML we’ll be using is pretty simple, but we need to wrap the iframe with two div elements. The .video
element is what we’ll actually position on the bottom right, and we’ll keep its parent (.video-wrap
) in place, as a reference of the video’s initial position. It’ll soon become much clearer why.
That’s pretty much every style we need including the slide up animation.
Notice that we pretty much only provide styles for when the video is stuck (i.e. when it has the .stuck
class), and just force the underlying iframe to take up its dimensions. As you can see, what we’re doing here is placing it on the bottom right of the viewport, and reducing its size (width and height). For the added effect, we also sprinkle a fancy sliding up CSS animation.
Making it all work with JavaScript
We’ll just need a mere seventeen lines of jQuery to make everything work:
Let’s break it down.
On the first few lines we cache the required elements into variables, as a good practice. This avoids needless allocations every time we scroll in the page.
Notice that on line 4 we also store the original video’s height:
The reason we do this is to keep the content below the video from jumping around when we apply position: fixed
to the video element. Remember that fixed position elements (like absolutely positioned ones) escape the page’s flow and leave “empty space” behind. When the video floats, we’ll apply this height to its parent wrapper making the content below completely oblivious to the video’s absence. That’s one of the reasons why we needed an extra parent element.
After this basic set up, we’re attaching a scroll event listener to the window
element. While we scroll, we keep checking whether the total amount of the window’s vertical scroll is bigger than the distance from the bottom of the video element to the top of the document.
To get the total amount the page is scrolled at any point we use jQuery’s handy .scrollTop
method on the window
object which gives us exactly that.
To get the bottom vertical position of an element, we only need to calculate its top offset (which is the distance from the top of the element to the top of the document) plus the element’s height. Here’s a small diagram to help you visualize it:
So all we need to check is if the window’s scrollTop
amount is greater than the video bottom’s distance from the top, and when it’s true, make the video float by simply applying the .stuck
class we coded earlier with CSS.
At the same time, we also apply the initial height to the video’s outermost parent to prevent the content from jumping. When the scroll is back up and the video gets into view (i.e. when windowScrollTop
is less than videoBottom
) we remove the stuck CSS class and reset the parent’s height to auto
!
And that’s it! Keep in mind that this technique will work with any kind of video provider, YouTube, Vimeo (pretty much with all of WordPress’s supported video providers), and also any kind of element (doesn’t have to be a video!).
Here’s the final result again:
0
What do you think of floating videos? Helpful or distracting? Let us know in the comments! (Thankfully, our themes include an on/off setting, like with most features!)
29 responses to “How to make sticky, floating videos on page scroll”
Great! Thnx!
Hello! I really liked it, but it’s impossible to make the video adaptive, help?
Hello, can you let me know exactly what you mean adaptive?
Will this work with a vimeo video as well?
Absolutely! In fact, with every video provider or embed.
do we have to use your external js and css?
how we can use just this js and css?
Heya, every theme should have its own style.css so the styles can go there. Also pretty much every theme has its own JavaScript code in a file somewhere, so we suggest the scripts go there :)
cant make it work on blogger, what do i do ???
Hello.
Assuming you have added the wrapper class of the video properly and placed the JavaScript bit on a proper place in the code, try going here https://codepen.io/vmasto_1470672674/pen/KyyMwq and in the SCSS box, click the top right arrow and select View Compiled CSS, then grab the CSS and paste it in your stylesheet.
It is really fantastic, thank you very much for the work. a queries please, if I have more than one video in a publication how to avoid overlapping one another when scrolling through the page. and another question how to put a button to close the floating video.
Hello Fernando.
Our simple tutorial here was not built with hosting multiple videos on one page I’m afraid and expanding it to do that would not properly fit in a comment reply. However if you are comfortable with reading some simple code I can point you to our Elements Plus! plugin’s code here. Specifically have a look at these three files 1, 2, 3 which essentially built an Elementor element which can in theory handle a case like the one you are describing. Please note that this also has not been extensively tested for such a scenario because we believe that multiple videos would add unneeded noise on a page, but all the parts are there, it should work.
Best regards.
Thank you for the tutorial, but how would you add a close button to the floating video that will reset the video?
Hello there Jay, check out this pen which features a close button on the video. https://codepen.io/nvourva/pen/OJXoMWw
Was just wondering how to add a close button. Only thing for me, is the close button still appears at the top-right when the user scrolls back up. How would I have it setup so that the close button is not visible at all when the user scrolls back up to the video?
Hello Jason, I’ve made some changes to my pen, it should be ok now, please check it out and let me know.
Hy, Close button appear again in top right corner of the web if video scroll up, how to remove that? Thanks. Im waiting.
Hello Inos, I’ve made some changes to my pen, it should be ok now, please check it out and let me know.
Hi, thank for this trick. Is it possible to achieve same result using a local video file (stored on the web server) and the object, instead of a remote (YT-served) video in an iframe?
Yes absolutely, instead of targeting the iframe you just target the video element in the CSS/JS and you keep the code the same otherwise.
(I meant the VIDEO object within angle brackets, your comment system automatically removed what was inside the brackets from my previous comment)
We tried to implement it on our WordPress site, but it doesn’t work. We created our own function, we also implemented css and it doesn’t work.
Hello, what exactly isn’t working can you shed a bit more light?
I have the same Problem, did you find the way to solve ?
Hello, can you provide more information regarding the issue?
Thanks for such an informative post. Would you be able to post the vanilla javascript?
Hello Lin.
Glad to hear you like the tutorial. Unfortunately we don’t have vanilla JS at hand for this particular example, however you can take a look at this CodePen which offers the same functionality with vanilla JS.
Thank you for the script.
Too bad my Html its a bit more complicated than this im not a pro with js
But i will continue to try, before or after i will made it!
what if is ajax loaded and if first video article is done and second article is loaded is this posible if floating video will remove and pause the current video playing? and when I play the second video article and scroll down it the floating video will be the second video article and so on
Hello.
While something like this is technically possible, I’m afraid such an implementation falls outside of the scope of this tutorial.