A staple of modern, trendy web design is the parallaxed, scrolling image. You know the one; where a background image is seemingly revealed by a transparent block, staying fixed relative to the viewport. as you scroll down a document.
This effect became easily accomplished in pure CSS with the widespread adoption of the
background-attachment:fixed; property. Just create a block, any block, fix the background to the viewport and it's done!
So, images can be easily parallaxed, but what about videos? Background videos have been a thing for a while haven't they? Why shouldn't a parallaxed version be just as easy as an image?
Well... the thing is, background videos on HTML pages aren't really "backgrounds" in the CSS sense. They are
<video> elements positioned behind other elements so they simply appear to be a background. In actuality, they must be somewhere in the flow of the document, and this is an important issue to note!
CSS backgrounds can be "fixed" to the viewport with
background-attachment:fixed; but they remain backgrounds, fully contained by their parent element. However, when you fix a
<video> element to the viewport with
position:fixed; it automatically gets promoted to a CSS
z-index above all other elements. This is a problem because you want the video to be visible only within, and contained by, the "transparent" block that scrolls up and down with the document. Since using
position:fixed; takes the
<video> out of the normal document flow, the CSS
overflow:hidden; on the parent element has no effect!
Even if you try to hide a fixed position
<video> element with other elements before and after it in the document flow by giving them a higher
z-index value, the video will still "spill out" of the document wherever there are normal elements with no
z-index assigned. In fact, you will need to
background-color all the basic blocks of your document so that nothing can peek through in order for a fixed position
<video> to work as a parallax video.
To be truly reusable, a solution needs to be self-contained and drop-in ready, without the need to edit any other elements in your document. Can we do this?
It turns out, by abandoning
getBoundingClientRect() which returns the position of any element relative to the viewport.
By using these coordinates of the parent element, and triggered by the
scroll event on the
window, we can dynamically re-position a child
<video> element using
position:absolute; instead of fixed. This allows the CSS property
overflow:hidden; on the parent element to correctly hide the parts of the video we want hidden as the user scrolls the document.
Give it a try and let me know how it works for you.
|⇐ activeImageMap script|